On Thu, Nov 12, 2020 at 10:36:28AM +0100, Jan Hubicka wrote:
> * fold-const.c (operand_compare::operand_equal_p): When comparing
> addresses
> look info field offsets for COMPONENT_REFs.
> (operand_compare::hash_operand): Likewise.
> diff --git a/gcc/fold-const.c b/gcc/fold-const.c
> index c47557daeba..a4e8cccb1b7 100644
> --- a/gcc/fold-const.c
> +++ b/gcc/fold-const.c
> @@ -3312,9 +3312,41 @@ 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;
> + /* 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. */
> + if (!OP_SAME (1))
> + {
> + if (flags & OEP_ADDRESS_OF)
> + {
> + tree field0 = TREE_OPERAND (arg0, 1);
> + tree field1 = TREE_OPERAND (arg1, 1);
> + tree type0 = DECL_CONTEXT (field0);
> + tree type1 = DECL_CONTEXT (field1);
> +
> + if (TREE_CODE (type0) == RECORD_TYPE
> + && DECL_BIT_FIELD_REPRESENTATIVE (field0))
> + field0 = DECL_BIT_FIELD_REPRESENTATIVE (field0);
> + if (TREE_CODE (type1) == RECORD_TYPE
> + && DECL_BIT_FIELD_REPRESENTATIVE (field1))
> + field1 = DECL_BIT_FIELD_REPRESENTATIVE (field1);
> + /* Assume that different FIELD_DECLs never overlap within a
> + RECORD_TYPE. */
> + if (type0 == type1 && TREE_CODE (type0) == RECORD_TYPE)
> + return false;
> + 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))
If it is an address, why do you need to handle
DECL_BIT_FIELD_REPRESENTATIVE? Taking address of a bit-field is not allowed.
Perhaps just return false if the fields are bit-fields (or assert they
aren't), and just compare DECL_FIELD*OFFSET of the fields themselves?
Jakub