https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123108
--- Comment #2 from Robin Dapp <rdapp at gcc dot gnu.org> ---
So once I added
diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 3ebce87562b..0ee3b639abd 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2004,7 +2004,8 @@ (define_insn_and_split "*pred_cmp_swapped<mode>_scalar"
DONE;
}
- [(set_attr "type" "vicmp")])
+ [(set_attr "type" "vicmp")
+ (set_attr "mode" "<MODE>")])
we get past the ratio error but emit the (bogus) vsetvl with immediate 32.
Before reload we have
(insn 71 19 72 2 (set (reg:DI 180)
(const_int 32 [0x20])) "pr123108.c":7:14 275 {*movdi_64bit}
(expr_list:REG_EQUIV (const_int 32 [0x20])
(nil)))
(insn 72 71 11 2 (set (reg:V32BI 155 [ _2 ])
(if_then_else:V32BI (unspec:V32BI [
(const_vector:V32BI [
(const_int 1 [0x1]) repeated x32
])
(reg:DI 180)
(const_int 2 [0x2]) repeated x2
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(gtu:V32BI (vec_duplicate:V32HI (subreg:HI (reg:DI 137 [
BS_ARG_0.0_4 ]) 0))
(reg:V32HI 156))
(unspec:V32BI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "pr123108.c":7:14 38311
{*pred_cmp_swappedv32hi_scalar}
(expr_list:REG_DEAD (reg:DI 180)
(expr_list:REG_DEAD (reg:V32HI 156)
(nil))))
which is correct, "32" needs to be in a register. During reload, though:
Removing equiv init insn 71 (freq=1000)
71: r180:DI=0x20
REG_EQUIV 0x20
deleting insn with uid = 71.
which leaves us with
(note 71 19 72 2 NOTE_INSN_DELETED)
(insn 72 71 11 2 (set (reg:V32BI 96 v0 [orig:155 _2 ] [155])
(if_then_else:V32BI (unspec:V32BI [
(const_vector:V32BI [
(const_int 1 [0x1]) repeated x32
])
(const_int 32 [0x20])
(const_int 2 [0x2]) repeated x2
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(gtu:V32BI (vec_duplicate:V32HI (reg:HI 10 a0 [orig:137
BS_ARG_0.0_4 ] [137]))
(reg:V32HI 100 v4 [156]))
(unspec:V32BI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "pr123108.c":7:14 38311
{*pred_cmp_swappedv32hi_scalar}
(nil))
Here we have the (const_int 32) again.
I don't get that. lra-constraints says:
/* This is equiv init insn of pseudo which did not get a
hard register -- remove the insn. */
Why didn't it get a hard register?
Interestingly enough, directly after insn 72 we have:
(insn 11 72 14 2 (set (reg:DI 15 a5 [158])
(const_int 32 [0x20])) "pr123108.c":7:14 275 {*movdi_64bit}
(expr_list:REG_EQUIV (const_int 32 [0x20])
(nil)))
(insn 14 11 20 2 (set (reg:V32HI 100 v4 [159])
(if_then_else:V32HI (unspec:V32BI [
(const_vector:V32BI [
(const_int 1 [0x1]) repeated x32
])
(reg:DI 15 a5 [158])
(const_int 2 [0x2]) repeated x3
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(const_vector:V32HI [
(const_int 0 [0]) repeated x32
])
(unspec:V32HI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "pr123108.c":7:14 4674
{*pred_broadcastv32hi_imm}
(expr_list:REG_EQUIV (const_vector:V32HI [
(const_int 0 [0]) repeated x32
])
(nil)))
which works as designed with 32 in a hard reg. Could this be an lra issue?