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 <[email protected]>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend