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

Reply via email to