On Thu, 12 Nov 2020, Jan Hubicka wrote: > Hi, > this is updated patch I am re-testing and plan to commit if it suceeds. > > * fold-const.c (operand_compare::operand_equal_p): Compare > offsets of fields in component_refs when comparing addresses. > (operand_compare::hash_operand): Likewise. > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > index c47557daeba..273ee25ceda 100644 > --- a/gcc/fold-const.c > +++ b/gcc/fold-const.c > @@ -3312,11 +3312,36 @@ operand_compare::operand_equal_p (const_tree arg0, > const_tree arg1, > 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) > - || !OP_SAME (1)) > + if (!OP_SAME_WITH_NULL (0)) > return false; > - flags &= ~OEP_ADDRESS_OF; > - return OP_SAME_WITH_NULL (2); > + /* Most of time we only need to compare FIELD_DECLs for equality. > + However when determining address look into actual offsets. > + These may match for unions and unshared record types. */
looks like you can simplify by doing flags &= ~OEP_ADDRESS_OF; here. Neither the FIELD_DECL compare nor the offsets need it > + if (!OP_SAME (1)) > + { > + if (flags & OEP_ADDRESS_OF) > + { > + if (TREE_OPERAND (arg0, 2) > + || TREE_OPERAND (arg1, 2)) > + { > + flags &= ~OEP_ADDRESS_OF; > + return OP_SAME_WITH_NULL (2); > + } > + tree field0 = TREE_OPERAND (arg0, 1); > + tree field1 = TREE_OPERAND (arg1, 1); > + > + if (!operand_equal_p (DECL_FIELD_OFFSET (field0), > + DECL_FIELD_OFFSET (field1), > + flags & ~OEP_ADDRESS_OF) > + || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0), > + DECL_FIELD_BIT_OFFSET (field1), > + flags & ~OEP_ADDRESS_OF)) > + return false; > + } > + else > + return false; > + } You elided flags &= ~OEP_ADDRESS_OF; - return OP_SAME_WITH_NULL (2); that was here when OP_SAME (1), please re-instantiate. > + return true; > > case BIT_FIELD_REF: > if (!OP_SAME (0)) > @@ -3787,9 +3812,26 @@ operand_compare::hash_operand (const_tree t, > inchash::hash &hstate, > sflags = flags; > break; > > + case COMPONENT_REF: > + if (sflags & OEP_ADDRESS_OF) > + { > + hash_operand (TREE_OPERAND (t, 0), hstate, flags); > + if (TREE_OPERAND (t, 2)) > + hash_operand (TREE_OPERAND (t, 2), hstate, > + flags & ~OEP_ADDRESS_OF); > + else > + { > + tree field = TREE_OPERAND (t, 1); > + hash_operand (DECL_FIELD_OFFSET (field), > + hstate, flags & ~OEP_ADDRESS_OF); > + hash_operand (DECL_FIELD_BIT_OFFSET (field), > + hstate, flags & ~OEP_ADDRESS_OF); > + } > + return; > + } > + break; > case ARRAY_REF: > case ARRAY_RANGE_REF: > - case COMPONENT_REF: > case BIT_FIELD_REF: > sflags &= ~OEP_ADDRESS_OF; > break; > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imend