> >     * 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)
> > +           {
> 
> actually if OP2 is not NULL for both you can just compare that (and that's
> more correct then).
> 
> > +             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);
> 
> Why does the representative matter?  For a 32bit bitfield if you'd
> have two addresses at 8bit boundary but different you'd make them
> equal this way.  Soo ...
> 
> > +             /* Assume that different FIELD_DECLs never overlap within a
> > +                RECORD_TYPE.  */
> > +             if (type0 == type1 && TREE_CODE (type0) == RECORD_TYPE)
> > +               return false;
> 
> this isn't really about "overlap", OEP_ADDRESS_OF is just about
> the address (not it's extent).

We discussed this with Jakub, so I have already tested version dropping
both of these, but indeed I should check for OPERAND2.  Will do that
now.

Thanks!
Honza
> 
> > +             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;
> 
> So this should suffice (on the original fields).
> 
> > +           }
> > +         else
> > +           return false;
> > +       }
> >       flags &= ~OEP_ADDRESS_OF;
> >       return OP_SAME_WITH_NULL (2);
> >  
> > @@ -3787,9 +3819,28 @@ operand_compare::hash_operand (const_tree t, 
> > inchash::hash &hstate,
> >           sflags = flags;
> >           break;
> >  
> > +       case COMPONENT_REF:
> > +         if (flags & OEP_ADDRESS_OF)
> > +           {
> > +             tree field = TREE_OPERAND (t, 1);
> > +             tree type = DECL_CONTEXT (field);
> > +
> > +             if (TREE_CODE (type) == RECORD_TYPE
> > +                 && DECL_BIT_FIELD_REPRESENTATIVE (field))
> > +               field = DECL_BIT_FIELD_REPRESENTATIVE (field);
> 
> see above.
> 
> > +             hash_operand (TREE_OPERAND (t, 0), hstate, flags);
> > +             hash_operand (DECL_FIELD_OFFSET (field),
> > +                           hstate, flags & ~OEP_ADDRESS_OF);
> > +             hash_operand (DECL_FIELD_BIT_OFFSET (field),
> > +                           hstate, flags & ~OEP_ADDRESS_OF);
> > +             hash_operand (TREE_OPERAND (t, 2), hstate,
> > +                           flags & ~OEP_ADDRESS_OF);
> 
> otherwise this looks ok.
> 
> > +             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