diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 74394b9115a..e46dc378744 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-10-09 Richard Guenther + + PR tree-optimization/45945 + * tree-ssa.c (execute_update_addresses_taken): Fixup LHS + scanning. + 2010-10-09 Eric Botcazou PR tree-optimization/45612 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c2d0df5abd..3641bf61858 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-10-09 Richard Guenther + + PR tree-optimization/45945 + * gcc.dg/lto/20101009-1_0.c: New testcase. + 2010-10-08 H.J. Lu PR target/45913 diff --git a/gcc/testsuite/gcc.dg/lto/20101009-1_0.c b/gcc/testsuite/gcc.dg/lto/20101009-1_0.c new file mode 100644 index 00000000000..6f280db060c --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20101009-1_0.c @@ -0,0 +1,16 @@ +/* { dg-lto-do link } */ + +static inline void +bar (unsigned *u) +{ + __asm__ ("":"=d" (*u)); +} + +void +foo (void) +{ + int i; + bar (&i); +} + +int main() { return 0; } diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 0b83b37e02f..e5acbf4cedb 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1980,8 +1980,10 @@ execute_update_addresses_taken (void) /* A plain decl does not need it set. */ if (lhs && !DECL_P (lhs)) { - if (handled_component_p (lhs)) - lhs = get_base_address (lhs); + tree orig_lhs = lhs; + + while (handled_component_p (lhs)) + lhs = TREE_OPERAND (lhs, 0); if (DECL_P (lhs)) bitmap_set_bit (not_reg_needs, DECL_UID (lhs)); @@ -1992,7 +1994,7 @@ execute_update_addresses_taken (void) if (DECL_P (decl) && (!integer_zerop (TREE_OPERAND (lhs, 1)) || (DECL_SIZE (decl) - != TYPE_SIZE (TREE_TYPE (lhs))))) + != TYPE_SIZE (TREE_TYPE (orig_lhs))))) bitmap_set_bit (not_reg_needs, DECL_UID (decl)); } } @@ -2020,8 +2022,29 @@ execute_update_addresses_taken (void) for (i = 0; i < gimple_asm_noutputs (stmt); ++i) { tree link = gimple_asm_output_op (stmt, i); - if ((decl = non_rewritable_mem_ref_base (TREE_VALUE (link)))) - bitmap_set_bit (not_reg_needs, DECL_UID (decl)); + tree lhs = TREE_VALUE (link); + + /* A plain decl does not need it set. */ + if (!DECL_P (lhs)) + { + tree orig_lhs = lhs; + + while (handled_component_p (lhs)) + lhs = TREE_OPERAND (lhs, 0); + + if (DECL_P (lhs)) + bitmap_set_bit (not_reg_needs, DECL_UID (lhs)); + else if (TREE_CODE (lhs) == MEM_REF + && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR) + { + decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0); + if (DECL_P (decl) + && (!integer_zerop (TREE_OPERAND (lhs, 1)) + || (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) + != TYPE_MAIN_VARIANT (TREE_TYPE (orig_lhs))))) + bitmap_set_bit (not_reg_needs, DECL_UID (decl)); + } + } } for (i = 0; i < gimple_asm_ninputs (stmt); ++i) {