2013-08-29 Jakub Jelinek Backported from mainline 2013-07-22 Georg-Johann Lay PR testsuite/52641 * gcc.dg/torture/pr57381.c: Add dg-require-effective-target int32plus. 2013-05-27 Richard Biener PR middle-end/57381 PR tree-optimization/57417 * tree-ssa-sccvn.c (vn_reference_fold_indirect): Fix test for unchanged base. (set_ssa_val_to): Compare addresses using get_addr_base_and_unit_offset. PR tree-optimization/57417 * gcc.dg/torture/pr57417.c: New testcase. 2013-05-23 Richard Biener PR middle-end/57381 * gcc.dg/torture/pr57381.c: New testcase. --- gcc/tree-ssa-sccvn.c (revision 199355) +++ gcc/tree-ssa-sccvn.c (revision 199356) @@ -1145,7 +1145,7 @@ vn_reference_fold_indirect (vecop0, 0), &addr_offset); gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF); - if (addr_base != op->op0) + if (addr_base != TREE_OPERAND (op->op0, 0)) { double_int off = tree_to_double_int (mem_op->op0); off = off.sext (TYPE_PRECISION (TREE_TYPE (mem_op->op0))); @@ -2608,6 +2608,7 @@ static inline bool set_ssa_val_to (tree from, tree to) { tree currval = SSA_VAL (from); + HOST_WIDE_INT toff, coff; if (from != to) { @@ -2643,7 +2644,17 @@ set_ssa_val_to (tree from, tree to) print_generic_expr (dump_file, to, 0); } - if (currval != to && !operand_equal_p (currval, to, OEP_PURE_SAME)) + if (currval != to + && !operand_equal_p (currval, to, 0) + /* ??? For addresses involving volatile objects or types operand_equal_p + does not reliably detect ADDR_EXPRs as equal. We know we are only + getting invariant gimple addresses here, so can use + get_addr_base_and_unit_offset to do this comparison. */ + && !(TREE_CODE (currval) == ADDR_EXPR + && TREE_CODE (to) == ADDR_EXPR + && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff) + == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff)) + && coff == toff)) { VN_INFO (from)->valnum = to; if (dump_file && (dump_flags & TDF_DETAILS)) --- gcc/testsuite/gcc.dg/torture/pr57417.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr57417.c (revision 199356) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +int a, b; +volatile int *c; + +void foo () +{ + volatile int d[1]; + b = 0; + for (;; a--) + c = &d[b]; +} --- gcc/testsuite/gcc.dg/torture/pr57381.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr57381.c (revision 201119) @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target int32plus } */ + +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; +}