On Sun, Jun 14, 2026 at 7:23 PM Roger Sayle <[email protected]> wrote:
>
>
> Hongtao did warn me there might be corner cases in STV when
> converting DImode SUBREGs to use V2DImode vector registers.
> https://gcc.gnu.org/pipermail/gcc-patches/2026-May/718615.html
> is exactly such a case, where with -m32 -O2 -march=cascadelake
> we attempt to convert a comparison containing (subreg:DI (reg:DD) 0)
> where the resulting call to gen_lowpart (V2DImode, ...) triggers
> an ICE. It's the lack of transitivity: DDmode may be SUBREGed to
> DImode, and DImode may be SUBREGed to V2DImode, but DDmode can't
> (directly) be SUBREGed to V2DImode.
>
> Alas my attempts to reduce a testcase (simpler than the one
> already in the testsuite) haven't be successful... The example
> below contains the problematic SUBREG in a comparison, but in
> this case, STV doesn't consider converting the chain profitable.
@@ -1169,7 +1169,16 @@ scalar_chain::convert_op (rtx *op, rtx_insn *insn)
{
gcc_assert (SUBREG_P (*op));
if (GET_MODE (*op) != vmode)
- *op = gen_lowpart (vmode, *op);
+ {
+ if (!targetm.modes_tieable_p (vmode, GET_MODE (SUBREG_REG (*op))))
+ {
+ tmp = gen_reg_rtx (GET_MODE (*op));
+ emit_insn_before (gen_rtx_SET (tmp, *op), insn);
+ *op = gen_rtx_SUBREG (vmode, tmp, 0);
+ }
+ else
+ *op = gen_lowpart (vmode, *op);
+ }
modes_tieable_p doesn't prove that gen_lowpart is valid, I think a
more robust fix should be as below(also add validate_subreg)
rtx inner = SUBREG_REG (*op);
poly_uint64 byte = SUBREG_BYTE (*op);
if (targetm.modes_tieable_p (vmode, GET_MODE (inner))
&& validate_subreg (vmode, GET_MODE (inner), inner, byte))
*op = gen_lowpart (vmode, *op);
else
{
tmp = gen_reg_rtx (GET_MODE (*op));
emit_insn_before (gen_rtx_SET (tmp, *op), insn);
*op = gen_rtx_SUBREG (vmode, tmp, 0);
}
>
--
BR,
Hongtao