https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127903
Bug ID: 127903
Summary: simplify-rtx: bit-cast of an unordered vector
comparison is folded to a constant zero
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: guojie at loongson dot cn
Target Milestone: ---
Testcase(t.c):
typedef float v4f32 __attribute__((vector_size (16)));
typedef int v4i32 __attribute__((vector_size (16)));
__attribute__((noinline)) v4f32
unord_cast3 (v4f32 a, v4f32 b)
{
v4i32 m;
for (int i = 0; i < 4; i++)
m[i] = __builtin_isunordered (a[i], b[i]) ? -1 : 0;
return (v4f32) m;
}
$ loongarch64-linux-gnu-gcc t.c -O3 -mlasx -S -o t.s #-O2 -mlsx behaves the
same
unord_cast3:
vrepli.b $vr0,0 <- constant zero, operands unused
vpickve2gr.du $r4,$vr0,0
vpickve2gr.du $r5,$vr0,1
jr $r1
Runtime check with NaNs in lanes 0/3:
got 00000000 00000000 00000000 00000000
want ffffffff 00000000 00000000 ffffffff
------ Analysis ------
The two insns that are affected, before and after fwprop1:
before fwprop1 (cse1) - both insns are still sane:
insn 7: (set (reg:V4SI 86 [ mask__12.12_25 ])
(unordered:V4SI (reg/v:V4SF 83 [ a ])
(reg/v:V4SF 84 [ b ]))) {lsx_vfcmp_cun_s}
insn 8: (set (reg:V4SF 82 [ <retval> ])
(subreg:V4SF (reg:V4SI 86 [ mask__12.12_25 ]) 0)) {movv4sf_simd}
after fwprop1 - insn 7 is unchanged, insn 8 gained a bogus constant:
insn 7: (set (reg:V4SI 86 [ mask__12.12_25 ])
(unordered:V4SI (reg/v:V4SF 83 [ a ])
(reg/v:V4SF 84 [ b ]))) {lsx_vfcmp_cun_s}
insn 8: (set (reg:V4SF 82 [ <retval> ])
(subreg:V4SF (reg:V4SI 86 [ mask__12.12_25 ]) 0)) {movv4sf_simd}
(REG_EQUAL (const_vector:V4SF [0.0 x4]) <-- the only real
change
(REG_DEAD (reg:V4SI 86 [ mask__12.12_25 ])))
How insn 8 gets that note - fwprop1 propagates insn 7's source into the subreg
of insn 8 and asks simplify_subreg() to fold it:
recog.cc:
insn_propagation::apply_to_rvalue_1(), SUBREG branch:
newx = simplify_subreg (V4SF, (unordered:V4SI ...), V4SI, 0);
simplify-rtx.cc:
simplify_subreg() -> simplify_gen_relational (UNORDERED, outermode =
V4SF, cmp_mode = innermode = V4SI, op0, op1);
simplify-rtx.cc:
simplify_const_relational_operation():
if (! HONOR_NANS (mode) && code == UNORDERED)
return const0_rtx; /* HONOR_NANS (V4SI) is false */
-> relational_result() -> (const_vector:V4SF [0.0 x4])