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.