On Thu, 12 Nov 2020, Jan Hubicka wrote:

> > 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
> 
> Yep
> > 
> > You elided
> > 
> >           flags &= ~OEP_ADDRESS_OF;
> > -         return OP_SAME_WITH_NULL (2);
> > 
> > that was here when OP_SAME (1), please re-instantiate.
> Sorry for that, that was not very careful.
> Here is updated patch I re-tested x86_64-linux.

OK.

Richard.

> diff --git a/gcc/fold-const.c b/gcc/fold-const.c
> index c47557daeba..ddf18f27cb7 100644
> --- a/gcc/fold-const.c
> +++ b/gcc/fold-const.c
> @@ -3312,10 +3312,32 @@ 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.  */
>         flags &= ~OEP_ADDRESS_OF;
> +       if (!OP_SAME (1))
> +         {
> +           if (flags & OEP_ADDRESS_OF)
> +             {
> +               if (TREE_OPERAND (arg0, 2)
> +                   || TREE_OPERAND (arg1, 2))
> +                 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)
> +                   || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0),
> +                                        DECL_FIELD_BIT_OFFSET (field1),
> +                                        flags))
> +                 return false;
> +             }
> +           else
> +             return false;
> +         }
>         return OP_SAME_WITH_NULL (2);
>  
>       case BIT_FIELD_REF:
> @@ -3787,9 +3809,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