diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8f90f6f108af..1aa0dec00110 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2473,9 +2473,12 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) equal if they have no side effects. If we have two identical expressions with side effects that should be treated the same due to the only side effects being identical SAVE_EXPR's, that will - be detected in the recursive calls below. */ + be detected in the recursive calls below. + If we are taking an invariant address of two identical objects + they are necessarily equal as well. */ if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST) && (TREE_CODE (arg0) == SAVE_EXPR + || (flags & OEP_CONSTANT_ADDRESS_OF) || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1)))) return 1; @@ -2538,7 +2541,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case ADDR_EXPR: return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), - 0); + TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1) + ? OEP_CONSTANT_ADDRESS_OF : 0); default: break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f464fa416195..5efb6b164b54 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-04-26 Richard Guenther + + PR middle-end/48694 + * gcc.dg/torture/pr48694-1.c: New testcase. + * gcc.dg/torture/pr48694-2.c: Likewise. + 2011-04-25 Paolo Carlini * g++.dg/ext/underlying_type1.C: New. diff --git a/gcc/testsuite/gcc.dg/torture/pr48694-1.c b/gcc/testsuite/gcc.dg/torture/pr48694-1.c new file mode 100644 index 000000000000..810366bc8b43 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr48694-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +extern volatile int g_89[5][9]; +extern int g, *gp; +void func_64() +{ + int i; + for (i = 0; i < 1; ) + { + for (g = 0; g < 1; ) + return; + gp = (int *)&g_89[g][0]; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr48694-2.c b/gcc/testsuite/gcc.dg/torture/pr48694-2.c new file mode 100644 index 000000000000..4791ac3f70c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr48694-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +extern volatile int g_4[1][4]; +extern int g_7; +void modify(int *); +void func_2() +{ + int l_46 = 4; + if (g_7) + modify(&l_46); + else + { + int i; + for (i = 0; i != 5; i += 1) + { + volatile int *vp = &g_4[0][l_46]; + *vp = 0; + } + } +} diff --git a/gcc/tree.h b/gcc/tree.h index 0bc98cd01b46..8f25832589f5 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5118,7 +5118,8 @@ extern tree fold_fma (location_t, tree, tree, tree, tree); enum operand_equal_flag { OEP_ONLY_CONST = 1, - OEP_PURE_SAME = 2 + OEP_PURE_SAME = 2, + OEP_CONSTANT_ADDRESS_OF = 4 }; extern int operand_equal_p (const_tree, const_tree, unsigned int);