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

Reply via email to