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