http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58794
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- The issue being that &a.f and &a.f are not equal because even with OEP_CONSTANT_ADDRESS_OF set we get into case COMPONENT_REF: /* Handle operand 2 the same as for ARRAY_REF. Operand 0 may be NULL when we're called to compare MEM_EXPRs. */ if (!OP_SAME_WITH_NULL (0)) return 0; flags &= ~OEP_CONSTANT_ADDRESS_OF; return OP_SAME (1) && OP_SAME_WITH_NULL (2); and thus drop it before comparing the two FIELD_DECLs which have TREE_SIDE_EFFECTS set. Fixed with Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 203886) +++ gcc/fold-const.c (working copy) @@ -2715,10 +2715,11 @@ operand_equal_p (const_tree arg0, const_ case COMPONENT_REF: /* Handle operand 2 the same as for ARRAY_REF. Operand 0 may be NULL when we're called to compare MEM_EXPRs. */ - if (!OP_SAME_WITH_NULL (0)) + if (!OP_SAME_WITH_NULL (0) + || !OP_SAME (1)) return 0; flags &= ~OEP_CONSTANT_ADDRESS_OF; - return OP_SAME (1) && OP_SAME_WITH_NULL (2); + return OP_SAME_WITH_NULL (2); case BIT_FIELD_REF: if (!OP_SAME (0)) I spotted this earlier but for some reason chickeded out to make this change. Hmm. Trying to remember why ...