diff mbox series

Fix PR88651

Message ID alpine.LSU.2.20.1901021448160.23386@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR88651 | expand

Commit Message

Richard Biener Jan. 2, 2019, 1:50 p.m. UTC
The following should fix PR88651 (don't have UBSAN GCC to verify).
We mangle HWI max_stmt_execution result in ways not considering
overflow but max_stmt_execution can return quite large numbers.

The following switches the code over to widest_ints.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2019-01-02  Richard Biener  <rguenther@suse.de>

	PR middle-end/88651
	* tree-data-ref.c (analyze_subscript_affine_affine): Use
	widest_ints when mangling max_stmt_execution results.
diff mbox series

Patch

diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index d9a8d3a7d9d..7d1f03c66af 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -3761,10 +3761,6 @@  analyze_subscript_affine_affine (tree chrec_a,
 
 	      if (niter > 0)
 		{
-		  HOST_WIDE_INT tau2 = MIN (FLOOR_DIV (niter_a - i0, i1),
-					    FLOOR_DIV (niter_b - j0, j1));
-		  HOST_WIDE_INT last_conflict = tau2 - (x1 - i0)/i1;
-
 		  /* If the overlap occurs outside of the bounds of the
 		     loop, there is no dependence.  */
 		  if (x1 >= niter_a || y1 >= niter_b)
@@ -3774,8 +3770,20 @@  analyze_subscript_affine_affine (tree chrec_a,
 		      *last_conflicts = integer_zero_node;
 		      goto end_analyze_subs_aa;
 		    }
+
+		  /* max stmt executions can get quite large, avoid
+		     overflows by using wide ints here.  */
+		  widest_int tau2
+		    = wi::smin (wi::sdiv_floor (wi::sub (niter_a, i0), i1),
+				wi::sdiv_floor (wi::sub (niter_b, j0), j1));
+		  widest_int last_conflict = wi::sub (tau2, (x1 - i0)/i1);
+		  if (wi::min_precision (last_conflict, SIGNED)
+		      <= TYPE_PRECISION (integer_type_node))
+		    *last_conflicts
+		       = build_int_cst (integer_type_node,
+					last_conflict.to_shwi ());
 		  else
-		    *last_conflicts = build_int_cst (NULL_TREE, last_conflict);
+		    *last_conflicts = chrec_dont_know;
 		}
 	      else
 		*last_conflicts = chrec_dont_know;