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 <[email protected]>
Backported from mainline
2013-05-27 Richard Biener <[email protected]>
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 <[email protected]>
Backported from mainline
2013-05-27 Richard Biener <[email protected]>
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 <[email protected]>
Backported from mainline
2013-07-22 Georg-Johann Lay <[email protected]>
PR testsuite/52641
* gcc.dg/torture/pr57381.c: Add dg-require-effective-target int32plus.
2013-05-27 Richard Biener <[email protected]>
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 <[email protected]>
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;
+}