scan-5.C 2.5 KB

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