https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104952
Bug ID: 104952 Summary: [nvptx][OpenMP] wrong code with OR / AND reduction ('reduction(||:' and '&&') with SIMT Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: burnus at gcc dot gnu.org CC: jakub at gcc dot gnu.org, vries at gcc dot gnu.org Target Milestone: --- Target: nvptx-none * Works when compiled with -O0 * Fails when compiled with -O1 → "result" is 0 instead of 1. Observations: * Issue occurs with '||' and '&&' – and for char/short/int/long. * Note: -O1 implies that omp_max_vf() returns != 1 Thus, only with -O1 there is SIMT, which seems to cause the problem. * When replacing 'reduction(||:' by 'reduction(|:' the code passes. Regarding the latter: Given that the order is not determined (i.e. 'a || b' and 'b || a' can occur), I think '||' can always be replaced by '|' in the reduction. @jakub: ^ does this make sense? * * * Long testcase is tests/5.0/loop/test_loop_reduction_or_device.c from https://github.com/SOLLVE/sollve_vv/ [the ..._and_... ('&&') testcase fails in the same way.] — Short testcase is below. Short testcase (runs into abort with -O1, works with -O0 or with "reduction:(|"): * * * int main () { char arr[100]; int result = 0; for (int i = 0; i < 100; ++i) arr[i] = 0; arr[5] = 1; #pragma omp target parallel map(tofrom:arr,result) #pragma omp loop reduction(||: result) for (int i = 0; i < 100; ++i) result = result || arr[i]; if (result != 1) __builtin_abort (); return 0; }