diff --git a/gcc/testsuite/gcc.dg/pr68317.c b/gcc/testsuite/gcc.dg/pr68317.c
index 06cd2e1da9c..bd053a7522b 100644
--- a/gcc/testsuite/gcc.dg/pr68317.c
+++ b/gcc/testsuite/gcc.dg/pr68317.c
@@ -12,8 +12,8 @@ foo ()
 {
  int32_t index = 0;
 
- for (index; index <= 10; index--) /* { dg-warning "iteration \[0-9\]+ invokes undefined behavior" } */
+ for (index; index <= 10; index--) // expected warning here
    /* Result of the following multiply will overflow
       when converted to signed int32_t.  */
-   bar ((0xcafe + index) * 0xdead);
+   bar ((0xcafe + index) * 0xdead);  /* { dg-warning "iteration \[0-9\]+ invokes undefined behavior" } */
 }
diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc
index 1b2ed753551..8b7982a2dbe 100644
--- a/gcc/tree-chrec.cc
+++ b/gcc/tree-chrec.cc
@@ -38,8 +38,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "tree-ssa-loop.h"
 #include "dumpfile.h"
-#include "value-range.h"
-#include "value-query.h"
 #include "tree-scalar-evolution.h"
 
 /* Extended folder for chrecs.  */
@@ -475,41 +473,36 @@ chrec_fold_multiply (tree type,
 
 	  /* When overflow is undefined and CHREC_LEFT/RIGHT do not have the
 	     same sign or CHREC_LEFT is zero then folding the multiply into
-	     the addition does not have the same behavior on overflow.  Use
-	     unsigned arithmetic in that case.  */
-	  value_range rl, rr;
-	  if (!ANY_INTEGRAL_TYPE_P (type)
-	      || TYPE_OVERFLOW_WRAPS (type)
-	      || integer_zerop (CHREC_LEFT (op0))
-	      || (TREE_CODE (CHREC_LEFT (op0)) == INTEGER_CST
-		  && TREE_CODE (CHREC_RIGHT (op0)) == INTEGER_CST
-		  && (tree_int_cst_sgn (CHREC_LEFT (op0))
-		      == tree_int_cst_sgn (CHREC_RIGHT (op0))))
-	      || (get_range_query (cfun)->range_of_expr (rl, CHREC_LEFT (op0))
-		  && !rl.undefined_p ()
-		  && (rl.nonpositive_p () || rl.nonnegative_p ())
-		  && get_range_query (cfun)->range_of_expr (rr,
-							    CHREC_RIGHT (op0))
-		  && !rr.undefined_p ()
-		  && ((rl.nonpositive_p () && rr.nonpositive_p ())
-		      || (rl.nonnegative_p () && rr.nonnegative_p ()))))
-	    {
-	      tree left = chrec_fold_multiply (type, CHREC_LEFT (op0), op1);
-	      tree right = chrec_fold_multiply (type, CHREC_RIGHT (op0), op1);
-	      return build_polynomial_chrec (CHREC_VARIABLE (op0), left, right);
-	    }
-	  else
+	     the addition does not have the same behavior on overflow.
+	     Using unsigned arithmetic in that case causes too many performance
+	     regressions, but catch the constant case where the multiplication
+	     of the step overflows.  */
+	  if (INTEGRAL_TYPE_P (type)
+	      && TYPE_OVERFLOW_UNDEFINED (type)
+	      && !integer_zerop (CHREC_LEFT (op0))
+	      && TREE_CODE (op1) == INTEGER_CST
+	      && TREE_CODE (CHREC_RIGHT (op0)) == INTEGER_CST)
 	    {
-	      tree utype = unsigned_type_for (type);
-	      tree uop1 = chrec_convert_rhs (utype, op1);
-	      tree uleft0 = chrec_convert_rhs (utype, CHREC_LEFT (op0));
-	      tree uright0 = chrec_convert_rhs (utype, CHREC_RIGHT (op0));
-	      tree left = chrec_fold_multiply (utype, uleft0, uop1);
-	      tree right = chrec_fold_multiply (utype, uright0, uop1);
-	      tree tem = build_polynomial_chrec (CHREC_VARIABLE (op0),
-						 left, right);
-	      return chrec_convert_rhs (type, tem);
+	      wi::overflow_type ovf = wi::OVF_NONE;
+	      wide_int res
+		= wi::mul (wi::to_wide (CHREC_RIGHT (op0)),
+			   wi::to_wide (op1), TYPE_SIGN (type), &ovf);
+	      if (ovf != wi::OVF_NONE)
+		{
+		  tree utype = unsigned_type_for (type);
+		  tree uop1 = chrec_convert_rhs (utype, op1);
+		  tree uleft0 = chrec_convert_rhs (utype, CHREC_LEFT (op0));
+		  tree uright0 = chrec_convert_rhs (utype, CHREC_RIGHT (op0));
+		  tree left = chrec_fold_multiply (utype, uleft0, uop1);
+		  tree right = chrec_fold_multiply (utype, uright0, uop1);
+		  tree tem = build_polynomial_chrec (CHREC_VARIABLE (op0),
+						     left, right);
+		  return chrec_convert_rhs (type, tem);
+		}
 	    }
+	  tree left = chrec_fold_multiply (type, CHREC_LEFT (op0), op1);
+	  tree right = chrec_fold_multiply (type, CHREC_RIGHT (op0), op1);
+	  return build_polynomial_chrec (CHREC_VARIABLE (op0), left, right);
 	}
 
     CASE_CONVERT:
