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  <ja...@redhat.com>

        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

Reply via email to