scan-8.C 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // { dg-require-effective-target size32plus }
  2. extern "C" void abort ();
  3. struct S {
  4. inline S ();
  5. inline ~S ();
  6. inline S (const S &);
  7. inline S & operator= (const S &);
  8. int s;
  9. };
  10. S::S () : s (0)
  11. {
  12. }
  13. S::~S ()
  14. {
  15. }
  16. S::S (const S &x)
  17. {
  18. s = x.s;
  19. }
  20. S &
  21. S::operator= (const S &x)
  22. {
  23. s = x.s;
  24. return *this;
  25. }
  26. static inline void
  27. ini (S &x)
  28. {
  29. x.s = 0;
  30. }
  31. S r, a[1024], b[1024];
  32. #pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
  33. #pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
  34. __attribute__((noipa)) void
  35. foo (S *a, S *b, S &r)
  36. {
  37. #pragma omp for reduction (inscan, +:r)
  38. for (int i = 0; i < 1024; i++)
  39. {
  40. b[i] = r;
  41. #pragma omp scan exclusive(r)
  42. r.s += a[i].s;
  43. }
  44. }
  45. __attribute__((noipa)) S
  46. bar (void)
  47. {
  48. S s;
  49. #pragma omp parallel
  50. #pragma omp for reduction (inscan, plus:s)
  51. for (int i = 0; i < 1024; i++)
  52. {
  53. b[i] = s;
  54. #pragma omp scan exclusive(s)
  55. s.s += 2 * a[i].s;
  56. }
  57. return s;
  58. }
  59. __attribute__((noipa)) void
  60. baz (S *a, S *b, S &r)
  61. {
  62. #pragma omp parallel for reduction (inscan, +:r)
  63. for (int i = 0; i < 1024; i++)
  64. {
  65. b[i] = r;
  66. #pragma omp scan exclusive(r)
  67. r.s += a[i].s;
  68. }
  69. }
  70. __attribute__((noipa)) S
  71. qux (void)
  72. {
  73. S s;
  74. #pragma omp parallel for reduction (inscan, plus:s)
  75. for (int i = 0; i < 1024; i++)
  76. {
  77. b[i] = s;
  78. #pragma omp scan exclusive(s)
  79. s.s += 2 * a[i].s;
  80. }
  81. return s;
  82. }
  83. int
  84. main ()
  85. {
  86. S s;
  87. for (int i = 0; i < 1024; ++i)
  88. {
  89. a[i].s = i;
  90. b[i].s = -1;
  91. asm ("" : "+g" (i));
  92. }
  93. #pragma omp parallel
  94. foo (a, b, r);
  95. if (r.s != 1024 * 1023 / 2)
  96. abort ();
  97. for (int i = 0; i < 1024; ++i)
  98. {
  99. if (b[i].s != s.s)
  100. abort ();
  101. else
  102. b[i].s = 25;
  103. s.s += i;
  104. }
  105. if (bar ().s != 1024 * 1023)
  106. abort ();
  107. s.s = 0;
  108. for (int i = 0; i < 1024; ++i)
  109. {
  110. if (b[i].s != s.s)
  111. abort ();
  112. s.s += 2 * i;
  113. }
  114. r.s = 0;
  115. baz (a, b, r);
  116. if (r.s != 1024 * 1023 / 2)
  117. abort ();
  118. s.s = 0;
  119. for (int i = 0; i < 1024; ++i)
  120. {
  121. if (b[i].s != s.s)
  122. abort ();
  123. else
  124. b[i].s = 25;
  125. s.s += i;
  126. }
  127. if (qux ().s != 1024 * 1023)
  128. abort ();
  129. s.s = 0;
  130. for (int i = 0; i < 1024; ++i)
  131. {
  132. if (b[i].s != s.s)
  133. abort ();
  134. s.s += 2 * i;
  135. }
  136. }