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

            Bug ID: 127648
           Summary: wrong code at -O{1,2,3} with AVX-512 min/max under
                    `-ffinite-math-only`
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kyuwoncho18 at gmail dot com
  Target Milestone: ---

Created attachment 65714
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65714&action=edit
reproduction code

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

static inline unsigned rd_mxcsr (void)
{
  unsigned m;
  __asm__ __volatile__ ("stmxcsr %0" : "=m" (m) : : "memory");
  return m;
}

static inline void wr_mxcsr (unsigned m)
{
  __asm__ __volatile__ ("ldmxcsr %0" : : "m" (m) : "memory");
}

/* -> __builtin_ia32_minps512_mask (a, b, s, -1, 8):  all-ones write mask,
   round argument 8 == _MM_FROUND_NO_EXC (suppress all exceptions).  */
__attribute__((noinline))
__m512 f (__m512 a, __m512 b, __m512 s)
{
  return _mm512_mask_min_round_ps (s, (__mmask16) -1, a, b, _MM_FROUND_NO_EXC);
}

/* volatile so no compiler can constant-propagate the operands into f */
static volatile unsigned denorm_bits = 0x00000001u;   /* 0x1p-149f: DENORMAL,
and FINITE */
static volatile float one = 1.0f;
static volatile float zero = 0.0f;

int main (void)
{
  union { unsigned u; float f; } cv, rv;
  float av[16], bv[16], sv[16];
  __m512 a, b, s, r;
  unsigned m;
  int i;

  cv.u = denorm_bits;
  for (i = 0; i < 16; i++)
    {
      av[i] = cv.f;
      bv[i] = one;
      sv[i] = zero;
    }
  a = _mm512_loadu_ps (av);
  b = _mm512_loadu_ps (bv);
  s = _mm512_loadu_ps (sv);

  wr_mxcsr (0x1f80u);     /* all exceptions masked, all flags clear, FTZ=DAZ=0
*/
  r = f (a, b, s);
  m = rd_mxcsr ();

  _mm512_storeu_ps (sv, r);
  rv.f = sv[0];
  printf ("DE=%u IE=%u r0=0x%08x\n", (m >> 1) & 1u, m & 1u, rv.u);
  return 0;
}


With the -mavx512f -ffinite-math-only flags, the PoC prints diverged with
optimization.
The DE (Denormal) flag is set only with -O{*} but not with -O0.

godbolt: https://gcc.godbolt.org/z/zbYjY5s7e

Reply via email to