diff mbox series

tree-optimization/104519 - adjust PR100499 niter fix

Message ID 20220215103751.628C913C16@imap2.suse-dmz.suse.de
State New
Headers show
Series tree-optimization/104519 - adjust PR100499 niter fix | expand

Commit Message

Richard Biener Feb. 15, 2022, 10:37 a.m. UTC
The following adjusts the PR100499 niter fix to use the appropriate
types when checking whether the difference between the final and base
values of the IV are a multiple of the step.  It also gets rid of
an always false condition in multiple_of_p which lead me to a
wrong solution first.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

2022-02-15  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/104519
	* fold-const.cc (multiple_of_p): Remove never true condition.
	* tree-ssa-loop-niter.cc (number_of_iterations_ne): Use
	the appropriate types for determining whether the difference
	of final and base is a multiple of the step.

	* gcc.dg/torture/pr104519.c: New testcase.
---
 gcc/fold-const.cc          |  6 +-----
 gcc/tree-ssa-loop-niter.cc | 16 +++++++++++-----
 2 files changed, 12 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 386d5732ea0..9d9939642f6 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -14208,11 +14208,7 @@  multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
 	      && multiple_of_p (type, TREE_OPERAND (top, 2), bottom, nowrap));
 
     case INTEGER_CST:
-      if (TREE_CODE (bottom) != INTEGER_CST
-	  || integer_zerop (bottom)
-	  || (TYPE_UNSIGNED (type)
-	      && (tree_int_cst_sgn (top) < 0
-		  || tree_int_cst_sgn (bottom) < 0)))
+      if (TREE_CODE (bottom) != INTEGER_CST || integer_zerop (bottom))
 	return 0;
       return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom),
 				SIGNED);
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 318d10c8fac..9bb5097379b 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -1048,13 +1048,19 @@  number_of_iterations_ne (class loop *loop, tree type, affine_iv *iv,
      which the loop exits immediately, and the iv does not overflow.
 
      Also note, we prove condition 2) by checking base and final seperately
-     along with condition 1) or 1').  */
+     along with condition 1) or 1').  Since we ensure the difference
+     computation of c does not wrap with cond below and the adjusted s
+     will fit a signed type as well as an unsigned we can safely do
+     this using the type of the IV if it is not pointer typed.  */
+  tree mtype = type;
+  if (POINTER_TYPE_P (type))
+    mtype = niter_type;
   if (!niter->control.no_overflow
       && (integer_onep (s)
-	  || (multiple_of_p (type, fold_convert (niter_type, iv->base), s,
-			     false)
-	      && multiple_of_p (type, fold_convert (niter_type, final), s,
-				false))))
+	  || (multiple_of_p (mtype, fold_convert (mtype, iv->base),
+			     fold_convert (mtype, s), false)
+	      && multiple_of_p (mtype, fold_convert (mtype, final),
+				fold_convert (mtype, s), false))))
     {
       tree t, cond, relaxed_cond = boolean_false_node;