aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c15
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20021007-1.c11
3 files changed, 29 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b316453..47717e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2002-09-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c/7411
+ * expr.c (expand_expr) [PLUS]: Simplify after the operands
+ have been expanded in EXPAND_NORMAL mode.
+
2002-10-06 Richard Henderson <rth@redhat.com>
* config/rs6000/rs6000.md (load_toc_v4_PIC_2): Fix base constraint.
diff --git a/gcc/expr.c b/gcc/expr.c
index 01c3603..e33d814 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7899,16 +7899,23 @@ expand_expr (exp, target, tmode, modifier)
}
}
+ if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
+ subtarget = 0;
+
/* No sense saving up arithmetic to be done
if it's all in the wrong mode to form part of an address.
And force_operand won't know whether to sign-extend or
zero-extend. */
if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
|| mode != ptr_mode)
- goto binop;
-
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
+ {
+ op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
+ op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ temp = simplify_binary_operation (PLUS, mode, op0, op1);
+ if (temp)
+ return temp;
+ goto binop2;
+ }
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
diff --git a/gcc/testsuite/gcc.c-torture/compile/20021007-1.c b/gcc/testsuite/gcc.c-torture/compile/20021007-1.c
new file mode 100644
index 0000000..de4c0de
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20021007-1.c
@@ -0,0 +1,11 @@
+/* PR c/7411 */
+/* Verify that GCC simplifies the null addition to i before
+ virtual register substitution tries it and winds up with
+ a memory to memory move. */
+
+void foo ()
+{
+ int i = 0,j;
+
+ i+=j=0;
+}