aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cselib.c34
-rw-r--r--gcc/reload1.c5
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/pr94526.c21
5 files changed, 54 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dcdfae1..20fe7e2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2020-04-08 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/94526
+ * cselib.c (autoinc_split): Handle e->val_rtx being SP_DERIVED_VALUE_P
+ with zero offset.
+ * reload1.c (eliminate_regs_1): Avoid creating
+ (plus (reg) (const_int 0)) in DEBUG_INSNs.
+
PR tree-optimization/94524
* tree-vect-generic.c (expand_vector_divmod): If any elt of op1 is
negative for signed TRUNC_MOD_EXPR, multiply with absolute value of
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 69c9ca5..0de6836 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -884,21 +884,29 @@ autoinc_split (rtx x, rtx *off, machine_mode memmode)
else
e = cselib_lookup (x, GET_MODE (x), 0, memmode);
if (e)
- for (struct elt_loc_list *l = e->locs; l; l = l->next)
- if (GET_CODE (l->loc) == PLUS
- && GET_CODE (XEXP (l->loc, 0)) == VALUE
- && SP_DERIVED_VALUE_P (XEXP (l->loc, 0))
- && CONST_INT_P (XEXP (l->loc, 1)))
+ {
+ if (SP_DERIVED_VALUE_P (e->val_rtx)
+ && (*off == NULL_RTX || *off == const0_rtx))
{
- if (*off == NULL_RTX)
- *off = XEXP (l->loc, 1);
- else
- *off = plus_constant (Pmode, *off,
- INTVAL (XEXP (l->loc, 1)));
- if (*off == const0_rtx)
- *off = NULL_RTX;
- return XEXP (l->loc, 0);
+ *off = NULL_RTX;
+ return e->val_rtx;
}
+ for (struct elt_loc_list *l = e->locs; l; l = l->next)
+ if (GET_CODE (l->loc) == PLUS
+ && GET_CODE (XEXP (l->loc, 0)) == VALUE
+ && SP_DERIVED_VALUE_P (XEXP (l->loc, 0))
+ && CONST_INT_P (XEXP (l->loc, 1)))
+ {
+ if (*off == NULL_RTX)
+ *off = XEXP (l->loc, 1);
+ else
+ *off = plus_constant (Pmode, *off,
+ INTVAL (XEXP (l->loc, 1)));
+ if (*off == const0_rtx)
+ *off = NULL_RTX;
+ return XEXP (l->loc, 0);
+ }
+ }
}
return x;
}
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 2f02c3e..88f4727 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -2607,8 +2607,9 @@ eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn,
structure of the insn in a way that reload can't handle.
We special-case the commonest situation in
eliminate_regs_in_insn, so just replace a PLUS with a
- PLUS here, unless inside a MEM. */
- if (mem_mode != 0
+ PLUS here, unless inside a MEM. In DEBUG_INSNs, it is
+ always ok to replace a PLUS with just a REG. */
+ if ((mem_mode != 0 || (insn && DEBUG_INSN_P (insn)))
&& CONST_INT_P (XEXP (x, 1))
&& known_eq (INTVAL (XEXP (x, 1)), -ep->previous_offset))
return ep->to_rtx;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 134280d..6f26fc6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2020-04-08 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/94526
+ * gcc.dg/pr94526.c: New test.
+
PR tree-optimization/94524
* gcc.c-torture/execute/pr94524-1.c: New test.
* gcc.c-torture/execute/pr94524-2.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr94526.c b/gcc/testsuite/gcc.dg/pr94526.c
new file mode 100644
index 0000000..9864c4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94526.c
@@ -0,0 +1,21 @@
+/* PR middle-end/94526 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+struct S { int val[8 * sizeof (int)]; };
+
+void
+foo (struct S *x)
+{
+ struct S *a = x;
+}
+
+void baz (struct S);
+
+void
+bar (void)
+{
+ struct S b;
+ foo (&b);
+ baz (b);
+}