Hi! I've bootstrapped/regtested on x86_64-linux and i686-linux these 3 backports (last patch is actually combined from 3 separate commits), all applied cleanly to 4.8 branch.
Ok for 4.8? Jakub
2013-08-29 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2013-05-27 Richard Biener <rguent...@suse.de> PR tree-optimization/57343 * tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED. (number_of_iterations_cond): Do not build the folded tree. * gcc.dg/torture/pr57343.c: New testcase. --- gcc/tree-ssa-loop-niter.c (revision 199356) +++ gcc/tree-ssa-loop-niter.c (revision 199357) @@ -552,10 +552,18 @@ number_of_iterations_ne_max (mpz_t bnd, { double_int max; mpz_t d; + tree type = TREE_TYPE (c); bool bnds_u_valid = ((no_overflow && exit_must_be_taken) || mpz_sgn (bnds->below) >= 0); - if (multiple_of_p (TREE_TYPE (c), c, s)) + if (integer_onep (s) + || (TREE_CODE (c) == INTEGER_CST + && TREE_CODE (s) == INTEGER_CST + && tree_to_double_int (c).mod (tree_to_double_int (s), + TYPE_UNSIGNED (type), + EXACT_DIV_EXPR).is_zero ()) + || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (c)) + && multiple_of_p (type, c, s))) { /* If C is an exact multiple of S, then its value will be reached before the induction variable overflows (unless the loop is exited in some @@ -572,16 +580,15 @@ number_of_iterations_ne_max (mpz_t bnd, the whole # of iterations analysis will fail). */ if (!no_overflow) { - max = double_int::mask (TYPE_PRECISION (TREE_TYPE (c)) - - tree_low_cst (num_ending_zeros (s), 1)); + max = double_int::mask (TYPE_PRECISION (type) + - tree_low_cst (num_ending_zeros (s), 1)); mpz_set_double_int (bnd, max, true); return; } /* Now we know that the induction variable does not overflow, so the loop iterates at most (range of type / S) times. */ - mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (TREE_TYPE (c))), - true); + mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (type)), true); /* If the induction variable is guaranteed to reach the value of C before overflow, ... */ @@ -1311,7 +1318,8 @@ number_of_iterations_cond (struct loop * } /* If the loop exits immediately, there is nothing to do. */ - if (integer_zerop (fold_build2 (code, boolean_type_node, iv0->base, iv1->base))) + tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base); + if (tem && integer_zerop (tem)) { niter->niter = build_int_cst (unsigned_type_for (type), 0); niter->max = double_int_zero; --- gcc/testsuite/gcc.dg/torture/pr57343.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr57343.c (revision 199357) @@ -0,0 +1,22 @@ +/* { dg-do run } */ + +int c = 0; + +int +main () +{ + int i, f = 1; + for (i = 0; i < 5; i++) + { + --c; + unsigned char h = c * 100; + if (h == 0) + { + f = 0; + break; + } + } + if (f != 1) + __builtin_abort (); + return 0; +}
2013-08-29 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2013-05-27 Richard Biener <rguent...@suse.de> PR tree-optimization/57396 * tree-affine.c (double_int_constant_multiple_p): Properly return false for val == 0 and div != 0. * gfortran.fortran-torture/execute/pr57396.f90: New testcase. --- gcc/tree-affine.c (revision 199349) +++ gcc/tree-affine.c (revision 199350) @@ -736,11 +736,10 @@ free_affine_expand_cache (struct pointer } /* If VAL != CST * DIV for any constant CST, returns false. - Otherwise, if VAL != 0 (and hence CST != 0), and *MULT_SET is true, - additionally compares CST and MULT, and if they are different, - returns false. Finally, if neither of these two cases occur, - true is returned, and if CST != 0, CST is stored to MULT and - MULT_SET is set to true. */ + Otherwise, if *MULT_SET is true, additionally compares CST and MULT, + and if they are different, returns false. Finally, if neither of these + two cases occur, true is returned, and CST is stored to MULT and MULT_SET + is set to true. */ static bool double_int_constant_multiple_p (double_int val, double_int div, @@ -749,7 +748,13 @@ double_int_constant_multiple_p (double_i double_int rem, cst; if (val.is_zero ()) - return true; + { + if (*mult_set && !mult->is_zero ()) + return false; + *mult_set = true; + *mult = double_int_zero; + return true; + } if (div.is_zero ()) return false; --- gcc/testsuite/gfortran.fortran-torture/execute/pr57396.f90 (revision 0) +++ gcc/testsuite/gfortran.fortran-torture/execute/pr57396.f90 (revision 199350) @@ -0,0 +1,33 @@ +module testmod + implicit none + + contains + + subroutine foo(n) + integer, intent(in) :: n + real :: r(0:n,-n:n), a(0:n,-n:n), dj + integer :: k, j + + ! initialize with some dummy values + do j = -n, n + a(:, j) = j + r(:,j) = j + 1 + end do + + ! here be dragons + do k = 0, n + dj = r(k, k - 2) * a(k, k - 2) + r(k,k) = a(k, k - 1) * dj + enddo + + if (r(0,0) .ne. -2.) call abort + + end subroutine + +end module + +program test + use testmod + implicit none + call foo(5) +end program
2013-08-29 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2013-07-22 Georg-Johann Lay <a...@gjlay.de> PR testsuite/52641 * gcc.dg/torture/pr57381.c: Add dg-require-effective-target int32plus. 2013-05-27 Richard Biener <rguent...@suse.de> 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 <rguent...@suse.de> 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 (vec<vn_refer addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (op->op0, 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; +}