On Thu, May 23, 2013 at 4:29 PM, Richard Biener <[email protected]> wrote:
>
> 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 <[email protected]>
>
> PR middle-end/57380
Typo?
> * 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;
> + }
--
Best Regards.