Hi!
When expanding
D.2070_29 = &MEM[(struct V *)0B].v[D.2034_30]{lb: 0 sz: 12};
expand_expr_addr_expr_1 is called with EXPAND_SUM, and result
ends up being (const_int 0) (from the NULL address), while
tmp (the offset) is a pseudo register. With EXPAND_SUM we want
to ensure no insns are emitted, so just gen_rtx_PLUS directly.
But having CONST_INT as the first argument and REG as second argument
of commutative RTL is invalid.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux
and Dave tested it on hppa. Ok for trunk/4.6 (it is a P1 regression)?
2011-03-17 Jakub Jelinek <[email protected]>
PR bootstrap/48161
* expr.c (expand_expr_addr_expr_1): Swap PLUS operands if
needed.
* gcc.c-torture/compile/pr48161.c: New test.
--- gcc/expr.c.jj 2011-03-14 14:12:15.000000000 +0100
+++ gcc/expr.c 2011-03-17 16:49:01.000000000 +0100
@@ -6971,7 +6971,12 @@ expand_expr_addr_expr_1 (tree exp, rtx t
tmp = convert_memory_address_addr_space (tmode, tmp, as);
if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
- result = gen_rtx_PLUS (tmode, result, tmp);
+ {
+ if (swap_commutative_operands_p (result, tmp))
+ result = gen_rtx_PLUS (tmode, tmp, result);
+ else
+ result = gen_rtx_PLUS (tmode, result, tmp);
+ }
else
{
subtarget = bitpos ? NULL_RTX : target;
--- gcc/testsuite/gcc.c-torture/compile/pr48161.c.jj 2011-03-09
16:32:56.855000001 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr48161.c 2011-03-17
17:20:34.000000000 +0100
@@ -0,0 +1,24 @@
+/* PR bootstrap/48161 */
+
+struct T { int u; };
+struct G { int l; int t; int r; };
+struct V { struct G v[10]; };
+struct { struct V b; } *h;
+void bar (void);
+
+struct G *
+baz (struct V *x, unsigned y)
+{
+ return &x->v[y];
+}
+
+int
+foo (struct T *x, struct T *y)
+{
+ if ((baz (&h->b, y->u)->t ? baz (&h->b, y->u)->t : 0)
+ - baz (h ? &h->b : 0, x->u)->r
+ - (baz (h ? &h->b : 0, x->u)->t > 0 ? 5 : 0))
+ return 1;
+ bar ();
+ return 0;
+}
Jakub