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-optimizaiton/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 <[email protected]>
---
gcc/lra-eliminations.cc | 12 ++++++++++--
gcc/testsuite/gcc.dg/pr123295-1.c | 20 ++++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr123295-1.c
diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc
index 9103ef10cb5..dd4b4d175b8 100644
--- a/gcc/lra-eliminations.cc
+++ b/gcc/lra-eliminations.cc
@@ -655,8 +655,16 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode
mem_mode,
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;
diff --git a/gcc/testsuite/gcc.dg/pr123295-1.c
b/gcc/testsuite/gcc.dg/pr123295-1.c
new file mode 100644
index 00000000000..ebb4bc2bdad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr123295-1.c
@@ -0,0 +1,20 @@
+/* { 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];
+}
--
2.43.0