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

            Bug ID: 72867
           Summary: SSE/AVX/AVX512: incorrect optimization of
                    VMINPS/VMAXPS at compile time
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wen...@mitsuba-renderer.org
  Target Milestone: ---

The Intel intrinsics provide a family functions for computing the minimum and
maximum of two floating point vectors of different SIMD widths.

For the most part, these are symmetric. They are not, however, when given a NaN
argument: in particular,

min(1, nan) == 1
min(nan, 1) == nan

Whether that is pretty is arguable, but it's what the hardware implements (and
numerical libraries depend on this behavior).

The program below computes the expected output at optimization level 0.

$ g++ test.c -o test -msse4.2 -O0 && ./test
min(1, nan) = [nan nan nan nan]
min(nan, 1) = [1.000000 1.000000 1.000000 1.000000]

At optimization level 1, the minimum is computed at compile time, and the NaN
value is incorrectly propagated. This problem occurs both on GCC trunk and on
GCC 5.0 (I have not tested other versions).

$ g++ test.c -o test -msse4.2 -O1 && ./test
min(1, nan) = [nan nan nan nan]
min(nan, 1) = [nan nan nan nan]

/// ************ Program to reproduce the issue ************

#include <stdio.h>
#include <math.h>
#include <immintrin.h>


int main(int argc, char *argv[]) {
    __m128 x = _mm_min_ps(_mm_set1_ps(1.f), _mm_set1_ps(NAN));
    printf("min(1, nan) = [%f %f %f %f]\n", x[0], x[1], x[2], x[3]);

    x = _mm_min_ps(_mm_set1_ps(NAN), _mm_set1_ps(1.f));
    printf("min(nan, 1) = [%f %f %f %f]\n", x[0], x[1], x[2], x[3]);

    return 0;
}

Reply via email to