https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127908
liu zhenyu <lzy20000419 at outlook dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lzy20000419 at outlook dot com
--- Comment #4 from liu zhenyu <lzy20000419 at outlook dot com> ---
The same `default_unspec_may_trap_p` hole shows up on x86-64, which also lacks
`TARGET_UNSPEC_MAY_TRAP_P`.
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.