http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58482

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Yeah, the testcase is just wrong.  The way OpenMP reductions work is that
in the loop the reduction variable(s) are privatized, i.e. either each thread
(for e.g. #pragma omp for) or each SIMD lane (for #pragma omp simd) gets its
own copy of that var, either default constructed (C++98 wording; for UDRs with
missing initializer clause), or initialized otherwise (see the standard for
details), in the loop everything is done on the privatized variable and finally
at the end the reduction operation is performed on the original variable,
calling the combiner expression with omp_out being the original variable and
omp_in being the privatized var, for each of the privatized variables.
But your testcase obviously can't work properly in that case, because your
reduction operation can't cope properly with being performed more than once.
If you subtract the array element values from the counter, then if they are all
positive, you'll get negative number, while if you subtract them from the
privatized var, all those privatized vars will have negative counter, but
then you subtract those negative numbers from the original var counter and get
positive number.  There is a reason why reduction (-:int_var) is actually
implemented as addition rather than subtraction...
In your testcase, you'd want a different operation to be used in the reduction
combiner, one that would add things rather than subtract.

Reply via email to