[PATCH] Fix VRP LSHIFT_EXPR non-singleton shift count handling (PR tree-optimization/57083)

Jakub Jelinek jakub@redhat.com
Sat Apr 27 04:23:00 GMT 2013


Hi!

If shift count range is [0, 1], then for unsigned LSHIFT_EXPR
bound is the topmost bit, but as llshift method always sign-extends
the result into double_int, the test don't properly find out that
deriving the value range is unsafe.  In this case
vr0 is [0x7fff8001, 0x80000001], thus when shifting up by 0 or one bit
we might shift out either zero or 1.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2013-04-26  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/57083
	* tree-vrp.c (extract_range_from_binary_expr_1): For LSHIFT_EXPR with
	non-singleton shift count range, zero extend low_bound for uns case.

	* gcc.dg/torture/pr57083.c: New test.

--- gcc/tree-vrp.c.jj	2013-04-24 12:07:07.000000000 +0200
+++ gcc/tree-vrp.c	2013-04-26 17:59:41.077938198 +0200
@@ -2837,7 +2837,7 @@ extract_range_from_binary_expr_1 (value_
 
 	      if (uns)
 		{
-		  low_bound = bound;
+		  low_bound = bound.zext (prec);
 		  high_bound = complement.zext (prec);
 		  if (tree_to_double_int (vr0.max).ult (low_bound))
 		    {
--- gcc/testsuite/gcc.dg/torture/pr57083.c.jj	2013-04-26 18:09:05.396031875 +0200
+++ gcc/testsuite/gcc.dg/torture/pr57083.c	2013-04-26 18:08:51.000000000 +0200
@@ -0,0 +1,15 @@
+/* PR tree-optimization/57083 */
+/* { dg-do run { target int32plus } } */
+
+extern void abort (void);
+short x = 1;
+int y = 0;
+
+int
+main ()
+{
+  unsigned t = (0x7fff8001U - x) << (y == 0);
+  if (t != 0xffff0000U)
+    abort ();
+  return 0;
+}

	Jakub



More information about the Gcc-patches mailing list