]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LRA: Fix eliminate regs into a subreg inside a debug insn [PR123295]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 26 Dec 2025 22:30:22 +0000 (14:30 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Mon, 29 Dec 2025 00:21:44 +0000 (16:21 -0800)
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>
gcc/lra-eliminations.cc
gcc/testsuite/gcc.dg/pr123295-1.c [new file with mode: 0644]

index 9103ef10cb5c33b27d6cc5c1fa236de70d162f01..dd4b4d175b8cf669de1c3711133231f164f2c873 100644 (file)
@@ -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 (file)
index 0000000..ebb4bc2
--- /dev/null
@@ -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];
+}