This is another case of ADDR_EXPRs not comparing equal from
operand_equal_p if they contain volatile field references.
The issue is that we should compare the FIELD_DECLs with
retaining OEP_CONSTANT_ADDRESS_OF (or maybe not set TREE_SIDE_EFFECTS
on them - but that's a bigger change).

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Richard.

2013-05-23  Richard Biener  <rguent...@suse.de>

        PR middle-end/57380
        * fold-const.c (operand_equal_p): Compare FIELD_DECLs with
        OEP_CONSTANT_ADDRESS_OF retained.

        * gcc.dg/torture/pr57381.c: New testcase.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c    (revision 199199)
--- gcc/fold-const.c    (working copy)
*************** operand_equal_p (const_tree arg0, const_
*** 2664,2673 ****
        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))
            return 0;
          flags &= ~OEP_CONSTANT_ADDRESS_OF;
!         return OP_SAME (1) && OP_SAME_WITH_NULL (2);
  
        case BIT_FIELD_REF:
          if (!OP_SAME (0))
--- 2664,2673 ----
        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))
            return 0;
          flags &= ~OEP_CONSTANT_ADDRESS_OF;
!         return OP_SAME_WITH_NULL (2);
  
        case BIT_FIELD_REF:
          if (!OP_SAME (0))
Index: gcc/testsuite/gcc.dg/torture/pr57381.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr57381.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr57381.c      (working copy)
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do compile } */
+ 
+ struct S0 { int  f0, f1, f2; };
+ 
+ struct S1 {
+     int  f0;
+     volatile struct S0 f2;
+ };
+ 
+ static struct S1 s = {0x47BED265,{0x06D4EB3E,5,0U}};
+ 
+ int foo(struct S0 p)
+ {
+   for (s.f2.f2 = 0; (s.f2.f2 <= 12); s.f2.f2++)
+     {
+       volatile int *l_61[5][2][2] = 
{{{&s.f2.f0,&s.f2.f0},{&s.f2.f0,&s.f2.f0}},{{&s.f2.f0,&s.f2.f0},{&s.f2.f0,&s.f2.f0}},{{&s.f2.f0,(void*)0},{&s.f2.f0,&s.f2.f0}},{{&s.f2.f0,&s.f2.f0},{&s.f2.f0,&s.f2.f0}},{{&s.f2.f0,&s.f2.f0},{(void*)0,&s.f2.f0}}};
+ 
+       volatile int **l_68 = &l_61[0][0][1];
+       volatile int *l_76 = &s.f2.f0;
+       (*l_68) = l_61[0][0][0];
+       if ((*l_76 = (p.f2 % 5))) ;
+     }
+   return p.f0;
+ }

Reply via email to