re PR rtl-optimization/68217 (Wrong constant folding)
authorKugan Vivekanandarajah <kuganv@linaro.org>
Fri, 29 Jul 2016 00:35:23 +0000 (00:35 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Fri, 29 Jul 2016 00:35:23 +0000 (00:35 +0000)
gcc/ChangeLog:

2016-07-29  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/68217
* tree-vrp.c (extract_range_from_binary_expr_1): In case of signed
& sign-bit-CST, generate [-INF, 0] instead of [-INF, INF].

gcc/testsuite/ChangeLog:

2016-07-29  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/68217
* gcc.dg/pr68217.c: New test.

From-SVN: r238846

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr68217.c [new file with mode: 0644]
gcc/tree-vrp.c

index e51cc01..b0da5b3 100644 (file)
@@ -1,3 +1,9 @@
+2016-07-29  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/68217
+       * tree-vrp.c (extract_range_from_binary_expr_1): In case of signed
+       & sign-bit-CST, generate [-INF, 0] instead of [-INF, INF].
+
 2016-07-28  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000-protos.h (rs6000_split_vec_extract_var):
index a588afe..ebb2c2f 100644 (file)
@@ -1,3 +1,8 @@
+2016-07-29  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/68217
+       * gcc.dg/pr68217.c: New test.
+
 2016-07-28  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/71067
diff --git a/gcc/testsuite/gcc.dg/pr68217.c b/gcc/testsuite/gcc.dg/pr68217.c
new file mode 100644 (file)
index 0000000..426a99a
--- /dev/null
@@ -0,0 +1,14 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int foo (void)
+{
+    volatile int a = -1;
+    long long b = (1LL << (sizeof (b) * 8 - 1)); // LLONG_MIN
+    long long x = (a & b); // x == 0x8000000000000000
+    if (x < 1LL) { ; } else { __builtin_abort(); }
+    return 0;
+}
+
+/* { dg-final { scan-tree-dump "\\\[-INF, 0\\\]" "vrp1" } } */
index 77c3014..41c870f 100644 (file)
@@ -3067,6 +3067,24 @@ extract_range_from_binary_expr_1 (value_range *vr,
          if (int_cst_range1 && tree_int_cst_sgn (vr1.min) >= 0)
            wmax = wi::min (wmax, vr1.max, TYPE_SIGN (expr_type));
          max = wide_int_to_tree (expr_type, wmax);
+         cmp = compare_values (min, max);
+         /* PR68217: In case of signed & sign-bit-CST should
+            result in [-INF, 0] instead of [-INF, INF].  */
+         if (cmp == -2 || cmp == 1)
+           {
+             wide_int sign_bit
+               = wi::set_bit_in_zero (TYPE_PRECISION (expr_type) - 1,
+                                      TYPE_PRECISION (expr_type));
+             if (!TYPE_UNSIGNED (expr_type)
+                 && ((value_range_constant_singleton (&vr0)
+                      && !wi::cmps (vr0.min, sign_bit))
+                     || (value_range_constant_singleton (&vr1)
+                         && !wi::cmps (vr1.min, sign_bit))))
+               {
+                 min = TYPE_MIN_VALUE (expr_type);
+                 max = build_int_cst (expr_type, 0);
+               }
+           }
        }
       else if (code == BIT_IOR_EXPR)
        {