https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128237
Bug ID: 128237
Summary: [14/15/16/17 Regression] gimple_could_trap_p_1 treats
FP-to-integer builtins (lrint, llrint, irint) as
non-trapping, vectorized lrint raises FE_INVALID for
inactive lanes
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: lzy20000419 at outlook dot com
Target Milestone: ---
Created attachment 66000
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=66000&action=edit
testcase
This was split out of PR122103 comment 25, as suggested in comment 27.
```c
#include <fenv.h>
#include <stdio.h>
long out[64];
double in[64];
int a[64]; /* only a[0] set: lrint called once, on 1.0 */
__attribute__((noipa)) void f (int n)
{
for (int i = 0; i < n; i++)
if (a[i])
out[i] = __builtin_lrint (in[i]);
}
int main (void)
{
for (int i = 1; i < 64; i++) in[i] = __builtin_nan ("");
in[0] = 1.0; a[0] = 1;
feclearexcept (FE_ALL_EXCEPT);
f (64);
printf ("%d\n", fetestexcept (FE_INVALID) != 0); /* expect 0 */
}
```
`gcc -O3 -fno-math-errno -march=x86-64-v4 t.c -lm && ./a.out` prints 1 on an
AVX-512 machine (expected 0; -O0 prints 0).
lrint is only executed for in[0] = 1.0, but the loop is if-converted and the
conversion runs on every lane;
only the store is masked (14.2):
```
vpcmpd $4, %zmm1, %zmm0, %k1
vcvtpd2qq in(%rip), %zmm1
vmovdqa64 %zmm1, out(%rip){%k2}
```
- Same result with __builtin_llrint and __builtin_irint; on trunk also
__builtin_lfloor and __builtin_lceil.
- 12.5 and earlier don't vectorize the loop and print 0. 13.4 through 16.2 and
trunk (17.0.0 20261027) print 1.
- -fno-tree-vectorize avoids it. -fno-tree-loop-if-convert avoids it on 13 and
14, but not on trunk.
- trunk: https://godbolt.org/z/a65EdvWoe , 12.5:
https://godbolt.org/z/z8eKfjjfo