[Bug target/123022] [16 Regression] [RISCV] [Miscompile] GCC - riscv64 target, miscompiles at -O3 since 4e2a2d6ad2d1bfe1269bc78da4251814505eb42e
law at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sun Dec 7 18:26:23 GMT 2025
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123022
Jeffrey A. Law <law at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |rdapp at gcc dot gnu.org
Last reconfirmed| |2025-12-07
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
--- Comment #6 from Jeffrey A. Law <law at gcc dot gnu.org> ---
As we leave gimple we have:
; basic block 10, loop depth 0
;; pred: 9
vect_cst__43 = {_23, _23, _23, _23, _23, _23, _23, _23};
vect__4.9_44 = (vector(8) long int) vect_cst__43;
vect_iftmp.10_46 = vect__4.9_44 + { 3326195747, 3326195747, 3326195747,
3326195747, 3326195747, 3326195747, 3326195747, 3326195747 };
_26 = .VEC_EXTRACT (vect_iftmp.10_46, 2);
goto <bb 12>; [100.00%]
That's reasonable. Note we extract element #2. Not great, but it's correct
given the IL. But we muck things up later in the RTL phases.
If we look at a bit of this code just before avl-prop:
(insn 142 141 143 12 (set (reg:DI 197)
(unspec:DI [
(const_int 64 [0x40])
] UNSPEC_VLMAX)) "j.c":13:43 discrim 1 -1
(nil))
(insn 143 142 77 12 (set (reg:RVVM1DI 180 [ vect_iftmp.10_46 ])
(if_then_else:RVVM1DI (unspec:RVVMF64BI [
(const_vector:RVVMF64BI [
(const_int 1 [0x1]) repeated x8
])
(reg:DI 197)
(const_int 2 [0x2]) repeated x2
(const_int 1 [0x1])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(plus:RVVM1DI (reg:RVVM1DI 181)
(zero_extend:RVVM1DI (vec_duplicate:RVVMF2SI (subreg:SI (reg:DI
139 [ _23 ]) 0))))
(unspec:RVVM1DI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "j.c":13:43 discrim 1 -1
(nil))
After AVL propagation:
(insn 142 141 143 12 (set (reg:DI 197)
(unspec:DI [
(const_int 64 [0x40])
] UNSPEC_VLMAX)) "j.c":13:43 discrim 1 2842 {vlmax_avldi}
(nil))
(insn 143 142 77 12 (set (reg:RVVM1DI 180 [ vect_iftmp.10_46 ])
(if_then_else:RVVM1DI (unspec:RVVMF64BI [
(const_vector:RVVMF64BI [
(const_int 1 [0x1]) repeated x8
])
(const_int 1 [0x1])
(const_int 2 [0x2]) repeated x2
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(plus:RVVM1DI (reg:RVVM1DI 181)
(zero_extend:RVVM1DI (vec_duplicate:RVVMF2SI (subreg:SI (reg:DI
139 [ _23 ]) 0))))
(unspec:RVVM1DI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "j.c":13:43 discrim 1 10478
{pred_single_widen_addurvvm1di_scalar}
(nil))
Note the change in length. That's going to cause headaches as we end up with
this code:
li a5,831549440 # 162 [c=4 l=4] *movdi_64bit/1
slli a5,a5,2 # 163 [c=4 l=4] ashldi3
vsetivli zero,8,e64,m1,ta,ma # 183 [c=0 l=4]
vsetvl_discard_resultdi
addi a5,a5,-2013 # 164 [c=4 l=4] *adddi3/1
vmv.v.x v1,a5 # 141 [c=12 l=4] *pred_broadcastrvvm1di/0
vsetivli zero,1,e32,mf2,ta,ma # 184 [c=0 l=4]
vsetvl_discard_resultdi
vwaddu.wx v1,v1,a3 # 143 [c=12 l=4]
pred_single_widen_addurvvm1di_scalar/2
vsetivli zero,8,e64,m1,ta,ma # 185 [c=0 l=4]
vsetvl_discard_resultdi
vslidedown.vi v1,v1,2 # 78 [c=4 l=4] pred_slidedownrvvm1di/2
vmv.x.s a1,v1 # 79 [c=12 l=4] *pred_extract_firstrvvm1di
So the vwaddu is only going to set the 0th element in the expected way. So
extracting the 2nd element isn't guaranteed to give us what we want.
More information about the Gcc-bugs
mailing list