The following fixes comparing of &i and &i if i is volatile. We were using operand_equal_p to compare i with i which of course results in a false negative. The following restricts us to the interesting cases (SSA names and decls) and then simply use ==.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2015-08-05 Richard Biener <rguent...@suse.de> PR middle-end/67120 * match.pd: Compare address bases with == if they are decls or SSA names, not operand_equal_p. Otherwise fail. * gcc.dg/torture/pr67120.c: New testcase. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 226612) +++ gcc/match.pd (working copy) @@ -1848,13 +1920,14 @@ (define_operator_list CBRT BUILT_IN_CBRT (if (base0 && base1) (with { - int equal; + int equal = 2; if (decl_in_symtab_p (base0) && decl_in_symtab_p (base1)) equal = symtab_node::get_create (base0) ->equal_address_to (symtab_node::get_create (base1)); - else - equal = operand_equal_p (base0, base1, 0); + else if ((DECL_P (base0) || TREE_CODE (base0) == SSA_NAME) + && (DECL_P (base1) || TREE_CODE (base1) == SSA_NAME)) + equal = (base0 == base1); } (if (equal == 1 && (cmp == EQ_EXPR || cmp == NE_EXPR Index: gcc/testsuite/gcc.dg/torture/pr67120.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr67120.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr67120.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do run } */ + +volatile int *volatile *a; +static volatile int *volatile **b = &a; + +int +main () +{ + volatile int *volatile c; + *b = &c; + + if (a != &c) + __builtin_abort (); + + return 0; +}