Hi, the problem in PR 50605 is that is_gimple_ip_invariant returns false for
&MEM[(struct tRecorderImp *)&recorder + 8B] where &reorder is an IP gimple invariant. This patch fixes that by copying the code that handles MEM_REFs from is_gimple_invariant_address (and only changing decl_address_invariant_p to decl_address_ip_invariant_p). Bootstrapped and tested on x86_64-linux. OK for trunk? Thanks, Martin 2011-11-11 Martin Jambor <mjam...@suse.cz> PR tree-optimization/50605 * gimple.c (is_gimple_ip_invariant_address): Also handle MEM_REFs of IPA invariant decls. * testsuite/g++.dg/ipa/pr50605.C: New test. Index: src/gcc/testsuite/g++.dg/ipa/pr50605.C =================================================================== --- /dev/null +++ src/gcc/testsuite/g++.dg/ipa/pr50605.C @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-early-inlining" } */ + +class A +{ +public: + int a; + void *stuff; +}; + +class B +{ +public: + int b; + void *other_stuff; + A array[50]; +}; + +extern B gb; + +int process_A (A *a) +{ + return a->a; +} + +int process_A_complex (A *a) +{ + return process_A (a+3); +} + +int process_B (B *b) +{ + return process_A_complex (&b->array[0]); +} + +int foo (void) +{ + return process_B (&gb); +} + Index: src/gcc/gimple.c =================================================================== --- src.orig/gcc/gimple.c +++ src/gcc/gimple.c @@ -2850,8 +2850,18 @@ is_gimple_ip_invariant_address (const_tr return false; op = strip_invariant_refs (TREE_OPERAND (t, 0)); + if (!op) + return false; + + if (TREE_CODE (op) == MEM_REF) + { + const_tree op0 = TREE_OPERAND (op, 0); + return (TREE_CODE (op0) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) + || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0)))); + } - return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op)); + return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op); } /* Return true if T is a GIMPLE minimal invariant. It's a restricted