diff mbox

[4.8] 3 backports

Message ID 20130829123821.GB21876@tucnak.zalov.cz
State New
Headers show

Commit Message

Jakub Jelinek Aug. 29, 2013, 12:38 p.m. UTC
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  <jakub@redhat.com>

	Backported from mainline
	2013-05-27  Richard Biener  <rguenther@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.
2013-08-29  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-05-27  Richard Biener  <rguenther@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  <jakub@redhat.com>

	Backported from mainline
	2013-07-22  Georg-Johann Lay  <avr@gjlay.de>

	PR testsuite/52641
	* gcc.dg/torture/pr57381.c: Add dg-require-effective-target int32plus.

	2013-05-27  Richard Biener  <rguenther@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  <rguenther@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;
+}

Comments

Richard Biener Aug. 29, 2013, 1:02 p.m. UTC | #1
On Thu, 29 Aug 2013, Jakub Jelinek wrote:

> 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?

Ok.

Thanks,
Richard.
diff mbox

Patch

--- 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;
+}