http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57381
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- The usual &a.b.c with volatile fields do not compare equal thing ... Value numbering l_61$0$0$0_6 stmt = l_61$0$0$0_6 = MEM[(volatile int *[5][2][2] *)&*.LC0]; RHS MEM[(volatile int *[5][2][2] *)&*.LC0] simplified to &s.f2.f0 has constants 1 Setting value number of l_61$0$0$0_6 to &s.f2.f0 (changed) and &s.f2.f0 never comparing equal because we unshare it in every iteration. Which is because operand_equal_p compares the FIELD_DECLs of COMPONENT_REFs after clearing OEP_CONSTANT_ADDRESS_OF but those have TREE_SIDE_EFFECTS set as well and we hit /* If ARG0 and ARG1 are the same SAVE_EXPR, they are necessarily equal. We don't care about side effects in that case because the SAVE_EXPR takes care of that for us. In all other cases, two expressions are 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. 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;