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

--- Comment #5 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(In reply to liu zhenyu from comment #4)
> The same `default_unspec_may_trap_p` hole shows up on x86-64, which also
> lacks `TARGET_UNSPEC_MAY_TRAP_P`.

Please report X86_64 issue separately. 

> Here the mover is RTL loop-invariant motion (`find_invariant_insn` checks
> `may_trap_or_fault_p`), at plain
> `-O1`/`-O2`/`-Os`:
> 
> ```c
> #include <fenv.h>
> #include <stdio.h>
> #include <immintrin.h>
> volatile int sink;
> int a[16];   /* all zero: the guarded statement never runs */
> __attribute__((noipa)) void f (double x, int n)
> {
>   for (int i = 0; i < n; i++)
>     if (a[i])
>       sink = _mm_cvtsd_si32 (_mm_set_sd (x));
> }
> int main (void)
> {
>   feclearexcept (FE_ALL_EXCEPT);
>   f (__builtin_nan (""), 16);
>   printf ("%d\n", fetestexcept (FE_INVALID) != 0);   /* expect 0 */
> }
> ```
> 
> `gcc -O2 t.c -lm` prints 1 (`-O0` and clang `-O2` print 0). `cvtsd2si` is
> hoisted as
> `(unspec:SI [...] UNSPEC_FIX_NOTRUNC)`. Fails on trunk / 15.2 / 14.2 / ... /
> 9.4; works on 7.5.
> `-fno-move-loop-invariants` fixes it; with `feenableexcept (FE_INVALID)` it
> SIGFPEs.
> 
> Also: plain `sink = __builtin_lrint (x)` at `-O2 -fno-math-errno`, and
> vector-float unspecs such as
> `_mm_min_pd` (`UNSPEC_IEEE_MIN`, result is V2DF so `SCALAR_FLOAT_MODE_P` is
> false). Scheduler / RTL PRE /
> ifcvt can speculate the same unspecs too.
> 
> A generic fix in `default_unspec_may_trap_p` (treat float / vector-float
> operand or result modes as trapping
> under `-ftrapping-math`) would cover RISC-V and x86 together.
> 
> Disclaimer: This test case was generated by a fuzzer, and the report was
> written with LLM assistance.

Reply via email to