So the problem here is during LRA we are eliminating argp and trying to
simplify the RTL as we go but inside a debug insn, almost all subreg
are valid due to gen_lowpart_for_debug done during debug insn simplification.
So simplify_gen_subreg will fail on some subregs and return null.
This causes problems later on. The solution is create a raw SUBREG
like what is done in lra_substitute_pseudo for debug insns.
Bootstrapped and tested on x86_64-linux-gnu.
PR rtl-optimization/123295
gcc/ChangeLog:
* lra-eliminations.cc (lra_eliminate_regs_1): For a debug
insn, create a raw SUBREG if simplify_gen_subreg fails.
gcc/testsuite/ChangeLog:
* gcc.dg/pr123295-1.c: New test.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
return x;
}
else
- return simplify_gen_subreg (GET_MODE (x), new_rtx,
- GET_MODE (new_rtx), SUBREG_BYTE (x));
+ {
+ rtx nx = simplify_gen_subreg (GET_MODE (x), new_rtx,
+ GET_MODE (new_rtx), SUBREG_BYTE (x));
+ /* If inside a debug insn, then generate the subreg manually as it might
+ be an invalid one for outside of a debug insn. */
+ if (DEBUG_INSN_P (insn) && !nx)
+ nx = gen_rtx_raw_SUBREG (GET_MODE (x), new_rtx, SUBREG_BYTE (x));
+ gcc_assert (nx);
+ return nx;
+ }
}
return x;
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Wno-psabi -O1 -g" } */
+
+typedef unsigned long V __attribute__((__vector_size__(64)));
+typedef __int128 U __attribute__((__vector_size__(64)));
+U g;
+
+static inline U
+bar(V v)
+{
+ v += ~0;
+ v += (V)(U){(unsigned)v[7], 0, 0, 2};
+ return (U)v + g;
+}
+
+__int128
+foo(V v)
+{
+ return bar(v)[3];
+}