https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102409

            Bug ID: 102409
           Summary: _pragma ("omp ...") expansion issue - placed in the
                    wrong scope
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
  Target Milestone: ---

Created attachment 51484
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51484&action=edit
Testcase. Compile with "g++ -fopenmp" or with "g++ -E" vs. "clang++ -E" and
inspect "omp ordered" placement

I have to admit that I do not know the fine print of _Pragma and nested macro
expansion. However, the result I get with clang matches what I naively would
expect – while I find the result for GCC odd. I also do not know whether this
use is an extension or matches the C (C++?) standard.

I think it is similar to PR 91669, PR 90400, PR91285, PR 82335

... except that here only the _Pragma that ends up at the wrong spot is the one
which is used in the macro call – while those which are in a #define are
handled properly.
If I read the other PRs correctly, there the issue is the _Pragma in the macro
#define. Nonetheless, they may still fail due to the very same reason.

 * * *

In any case, the result which clang gives matches the expectation of the
testcase author
of the test at
https://github.com/clang-ykt/omptests/blob/master/t-for/test.c#L296

Due to GCC's macro/_Pragma expansion, that one (as well as the attached
stripped-down version) fails with:
  error: ‘ordered’ region may not be closely nested inside of ‘critical’,
‘ordered’, explicit ‘task’ or ‘taskloop’ region

 * * *

The code uses:

#define PARALLEL(X) TEST({ \
...
_Pragma("omp for ordered") \
  X  \
_Pragma("omp for schedule(auto) ordered") \
  X  \
})
...

    PARALLEL(
    for (int i = 0; i < N; i++) { \
      _Pragma("omp ordered") \



EXPECTED: same result as with clang++-11 -E -fopenmp:

...
#pragma omp for ordered
 for (int i = 0; i < (1024*3); i++) {
#pragma omp ordered
 S[0] += C[i] + D[i]; }
#pragma omp for schedule(auto) ordered
 for (int i = 0; i < (1024*3); i++) {
#pragma omp ordered
 S[0] += C[i] + D[i]; } } }} } }
  }
...


BUT: g++ -E -fopenmp gives the following, placing the 'omp ordered' before TEST
instead of inside before "S[0] = " together with the rest of X:

#pragma omp ordered
#pragma omp ordered
    { int fail = 0, trial; for (int trial = 0; trial < (1) && fail == 0;
trial++) {
...
#pragma omp for ordered
    for (int i = 0; i < (1024*3); i++) { S[0] += C[i] + D[i]; } 
#pragma omp for schedule(auto) ordered
    for (int i = 0; i < (1024*3); i++) { S[0] += C[i] + D[i]; } } }} } }
  }

Reply via email to