diff mbox

Fix extract_range_from_assert for signed 1-bit precision types (PR tree-optimization/51247)

Message ID 20111124151159.GJ27242@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 24, 2011, 3:11 p.m. UTC
Hi!

Since Richard's build_int_cst changes to make it effectively
build_int_cst_type when extract_range_from_assert wants to subtract
or add 1 to min or max of a signed 1-bit precision type,
build_int_cst (..., 1) returns actually -1 constant and that overflows
on the fold_build2, leading to ICEs later on.

This patch in that case adds resp. subtracts -1 instead of subtracting
resp. adding 1.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-11-24  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/51247
	* tree-vrp.c (extract_range_from_assert): For signed 1-bit precision
	types instead of adding 1 subtract -1 and instead of subtracting 1
	add -1 to avoid overflows.

	* gcc.c-torture/compile/pr51247.c: New test.


	Jakub

Comments

Jeff Law Nov. 29, 2011, 7:47 p.m. UTC | #1
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/24/11 08:11, Jakub Jelinek wrote:
> Hi!
> 
> Since Richard's build_int_cst changes to make it effectively 
> build_int_cst_type when extract_range_from_assert wants to
> subtract or add 1 to min or max of a signed 1-bit precision type, 
> build_int_cst (..., 1) returns actually -1 constant and that
> overflows on the fold_build2, leading to ICEs later on.
> 
> This patch in that case adds resp. subtracts -1 instead of
> subtracting resp. adding 1.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
> 
> 2011-11-24  Jakub Jelinek  <jakub@redhat.com>
> 
> PR tree-optimization/51247 * tree-vrp.c
> (extract_range_from_assert): For signed 1-bit precision types
> instead of adding 1 subtract -1 and instead of subtracting 1 add -1
> to avoid overflows.
> 
> * gcc.c-torture/compile/pr51247.c: New test.
OK.
jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJO1TbpAAoJEBRtltQi2kC71WEH/245Qoeaa/F+aUlSNPT8b+6o
kDXV7/GOyS+ruCswd+FYFn9pEE2bmhFq1o98oyqHqjFAXYeAlRxF+pbAL1X8DN0y
ANcdlbBxIYC0aKpLVn+VvS5ans/LgIZbon8yQ0iZhdcUDwAU66H57HBZ6d8kWr1K
j5c3AsdTRmsTE9/e98XHo9xEcBXtEUcIfp841ABJ046xq7i4zixIDtx+L9El633U
cGgBhz42e94eelfEOzqPQ9KE/+3Xfm7Z8mpc3Tr8su7vEmrDP2EaKw9F0daDOavb
zCIYfi1Svwdq1ZZgTG3XOZ2cGt51x4VQ25aOCahXXYMpsZrW/6t/0Lsf9xydrD4=
=FXf4
-----END PGP SIGNATURE-----
diff mbox

Patch

--- gcc/tree-vrp.c.jj	2011-10-17 22:27:42.000000000 +0200
+++ gcc/tree-vrp.c	2011-11-24 11:23:23.032335859 +0100
@@ -1693,8 +1693,13 @@  extract_range_from_assert (value_range_t
 	  /* For LT_EXPR, we create the range [MIN, MAX - 1].  */
 	  if (cond_code == LT_EXPR)
 	    {
-	      tree one = build_int_cst (TREE_TYPE (max), 1);
-	      max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, one);
+	      if (TYPE_PRECISION (TREE_TYPE (max)) == 1
+		  && !TYPE_UNSIGNED (TREE_TYPE (max)))
+		max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max,
+				   build_int_cst (TREE_TYPE (max), -1));
+	      else
+		max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max,
+				   build_int_cst (TREE_TYPE (max), 1));
 	      if (EXPR_P (max))
 		TREE_NO_WARNING (max) = 1;
 	    }
@@ -1728,8 +1733,13 @@  extract_range_from_assert (value_range_t
 	  /* For GT_EXPR, we create the range [MIN + 1, MAX].  */
 	  if (cond_code == GT_EXPR)
 	    {
-	      tree one = build_int_cst (TREE_TYPE (min), 1);
-	      min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min, one);
+	      if (TYPE_PRECISION (TREE_TYPE (min)) == 1
+		  && !TYPE_UNSIGNED (TREE_TYPE (min)))
+		min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min,
+				   build_int_cst (TREE_TYPE (min), -1));
+	      else
+		min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min,
+				   build_int_cst (TREE_TYPE (min), 1));
 	      if (EXPR_P (min))
 		TREE_NO_WARNING (min) = 1;
 	    }
@@ -1915,9 +1925,19 @@  extract_range_from_assert (value_range_t
 		  min = positive_overflow_infinity (TREE_TYPE (var_vr->min));
 		}
 	      else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
-		min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
-				   anti_max,
-				   build_int_cst (TREE_TYPE (var_vr->min), 1));
+		{
+		  if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1
+		      && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min)))
+		    min = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
+				       anti_max,
+				       build_int_cst (TREE_TYPE (var_vr->min),
+						      -1));
+		  else
+		    min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
+				       anti_max,
+				       build_int_cst (TREE_TYPE (var_vr->min),
+						      1));
+		}
 	      else
 		min = fold_build_pointer_plus_hwi (anti_max, 1);
 	      max = real_max;
@@ -1942,9 +1962,19 @@  extract_range_from_assert (value_range_t
 		  max = negative_overflow_infinity (TREE_TYPE (var_vr->min));
 		}
 	      else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
-		max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
-				   anti_min,
-				   build_int_cst (TREE_TYPE (var_vr->min), 1));
+		{
+		  if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1
+		      && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min)))
+		    max = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
+				       anti_min,
+				       build_int_cst (TREE_TYPE (var_vr->min),
+						      -1));
+		  else
+		    max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
+				       anti_min,
+				       build_int_cst (TREE_TYPE (var_vr->min),
+						      1));
+		}
 	      else
 		max = fold_build_pointer_plus_hwi (anti_min, -1);
 	      min = real_min;
--- gcc/testsuite/gcc.c-torture/compile/pr51247.c.jj	2011-11-24 11:28:18.293592580 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr51247.c	2011-11-24 11:27:53.000000000 +0100
@@ -0,0 +1,16 @@ 
+/* PR tree-optimization/51247 */
+
+struct S { int s : 1; };
+int a;
+
+void
+foo (int x, int y)
+{
+  struct S s;
+  s.s = !!y;
+  while (1)
+    {
+      unsigned l = 94967295;
+      a = x || (s.s &= l);
+    }
+}