aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2022-03-14 14:49:09 +0100
committerJakub Jelinek <jakub@redhat.com>2022-03-14 14:49:09 +0100
commit77eb0461abe61a85f69270048ad81b25b1cc95d6 (patch)
treeb0451db695ef69ebc0e544054005af10123c425f
parent8f7b7c1495f92c72da154d32317943a2cc276ca8 (diff)
downloadgcc-77eb0461abe61a85f69270048ad81b25b1cc95d6.zip
gcc-77eb0461abe61a85f69270048ad81b25b1cc95d6.tar.gz
gcc-77eb0461abe61a85f69270048ad81b25b1cc95d6.tar.bz2
lra: Fix up debug_p handling in lra_substitute_pseudo [PR104778]
The following testcase ICEs on powerpc-linux, because lra_substitute_pseudo substitutes (const_int 1) into a subreg operand. First a subreg of subreg of a reg appears in a debug insn (which surely is invalid outside of debug insns, but in debug insns we allow even what is normally invalid in RTL like subregs which the target doesn't like, because either dwarf2out is able to handle it, or we just throw away the location expression, making some var <optimized out>. lra_substitute_pseudo already has some code to deal with specifically SUBREG of REG with the REG being substituted for VOIDmode constant, but that doesn't cover this case, so the following patch extends lra_substitute_pseudo for debug_p mode to treat stuff like e.g. combiner's subst function to ensure we don't lose mode which is essential for the IL. 2022-03-14 Jakub Jelinek <jakub@redhat.com> PR debug/104778 * lra.cc (lra_substitute_pseudo): For debug_p mode, simplify SUBREG, ZERO_EXTEND, SIGN_EXTEND, FLOAT or UNSIGNED_FLOAT if recursive call simplified the first operand into VOIDmode constant. * gcc.target/powerpc/pr104778.c: New test.
-rw-r--r--gcc/lra.cc35
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr104778.c51
2 files changed, 84 insertions, 2 deletions
diff --git a/gcc/lra.cc b/gcc/lra.cc
index 5ef077c..1444cb7 100644
--- a/gcc/lra.cc
+++ b/gcc/lra.cc
@@ -2015,8 +2015,39 @@ lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p,
{
if (fmt[i] == 'e')
{
- if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
- new_reg, subreg_p, debug_p))
+ if (debug_p
+ && i == 0
+ && (code == SUBREG
+ || code == ZERO_EXTEND
+ || code == SIGN_EXTEND
+ || code == FLOAT
+ || code == UNSIGNED_FLOAT))
+ {
+ rtx y = XEXP (x, 0);
+ if (lra_substitute_pseudo (&y, old_regno,
+ new_reg, subreg_p, debug_p))
+ {
+ result = true;
+ if (CONST_SCALAR_INT_P (y))
+ {
+ if (code == SUBREG)
+ y = simplify_subreg (GET_MODE (x), y,
+ GET_MODE (SUBREG_REG (x)),
+ SUBREG_BYTE (x));
+ else
+ y = simplify_unary_operation (code, GET_MODE (x), y,
+ GET_MODE (XEXP (x, 0)));
+ if (y)
+ *loc = y;
+ else
+ *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
+ }
+ else
+ XEXP (x, 0) = y;
+ }
+ }
+ else if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
+ new_reg, subreg_p, debug_p))
result = true;
}
else if (fmt[i] == 'E')
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104778.c b/gcc/testsuite/gcc.target/powerpc/pr104778.c
new file mode 100644
index 0000000..3866f18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104778.c
@@ -0,0 +1,51 @@
+/* PR debug/104778 */
+/* { dg-do compile } */
+/* { dg-options "-mcmpb -Og -g" } */
+/* { dg-additional-options "-fpie" { target pie } } */
+
+unsigned long long int p;
+short int m, n;
+
+void
+foo (double u, int v, int x, int y, int z)
+{
+ long long int a = v;
+ short int b = v;
+ int c = 0, d = m, e = u;
+
+ if (n)
+ {
+ int q = b;
+
+ while (p / 1.0)
+ c = 0;
+
+ if (n * n == (d + 1) / (1LL << x))
+ a = 1;
+
+ b = u;
+ while (d)
+ {
+ u = m + 1ULL;
+ b = a - (unsigned long long int) u + a + (char) (u + 1.0);
+ d = (v - 1LL) * n / d + q + x;
+ q = m;
+ }
+ }
+
+ while (c < 1)
+ {
+ int r;
+
+ if (m == y)
+ m = e * z;
+
+ e = !a;
+
+ while (!r)
+ ;
+
+ if (b)
+ m = d;
+ }
+}