]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/61725 (__builtin_ffs(0) leads to wrong code generation)
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 Jul 2014 09:39:57 +0000 (11:39 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 8 Jul 2014 09:39:57 +0000 (11:39 +0200)
PR tree-optimization/61725
* tree-vrp.c (extract_range_basic): Don't assume vr0 is unsigned
range, use range_includes_zerop_p instead of integer_zerop on
vr0->min, only use log2 of max if min is not negative.

* gcc.dg/tree-ssa/vrp93.c: New test.
* gcc.c-torture/execute/pr61725.c: New test.

From-SVN: r212353

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr61725.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/vrp93.c [new file with mode: 0644]
gcc/tree-vrp.c

index f333d614847435e81fa6ead369125d77251aeada..c4563baf6be676731fd832d63aed895f0df1c634 100644 (file)
@@ -1,3 +1,10 @@
+2014-07-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/61725
+       * tree-vrp.c (extract_range_basic): Don't assume vr0 is unsigned
+       range, use range_includes_zerop_p instead of integer_zerop on
+       vr0->min, only use log2 of max if min is not negative.
+
 2014-07-08  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-dom.h (loop_depth_of_name): Remove.
index d933972ff5b3137b95cf00769e3b790d6f5e738a..765eb9f41f3aaaf4538d411af61b11fe23646e07 100644 (file)
@@ -1,3 +1,9 @@
+2014-07-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/61725
+       * gcc.dg/tree-ssa/vrp93.c: New test.
+       * gcc.c-torture/execute/pr61725.c: New test.
+
 2014-07-08  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-dom.h (loop_depth_of_name): Remove.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61725.c b/gcc/testsuite/gcc.c-torture/execute/pr61725.c
new file mode 100644 (file)
index 0000000..0aa6daf
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR tree-optimization/61725 */
+
+int
+main ()
+{
+  int x;
+  for (x = -128; x <= 128; x++)
+    {
+      int a = __builtin_ffs (x);
+      if (x == 0 && a != 0)
+        __builtin_abort ();
+    }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp93.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp93.c
new file mode 100644 (file)
index 0000000..d78c399
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR target/29776 */
+/* PR tree-optimization/61725 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+/* { dg-final { scan-tree-dump-not "link_error" "vrp1"} } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
+#define A(fn, arg, min, max) \
+  if (__builtin_##fn (arg) < min || __builtin_##fn (arg) > max) \
+    link_error ();
+#define B(fn, min, max) \
+  A (fn, a, min, max) A (fn##l, b, min, max) A (fn##ll, c, min, max)
+#define C(fn, min, sub) \
+  A (fn, a, min, ((int) sizeof (a) * __CHAR_BIT__ - sub)) \
+  A (fn##l, b, min, ((int) sizeof (b) * __CHAR_BIT__ - sub)) \
+  A (fn##ll, c, min, ((int) sizeof (c) * __CHAR_BIT__ - sub))
+
+extern void link_error (void);
+
+unsigned int d;
+unsigned long e;
+unsigned long long f;
+
+void
+foo (int a, long b, long long c)
+{
+  C (ffs, 0, 0)
+  a &= 63; b &= 63; c &= 63;
+  B (ffs, 0, 6)
+  a++; b++; c++;
+  B (ffs, 1, 7)
+  a -= 2; b -= 2; c -= 2;
+  C (ffs, 0, 0)
+  a -= 63; b -= 63; c -= 63;
+  C (ffs, 1, 0)
+}
index 3d0916d457a664dd917c4450bbff473a58ee6474..5fc135146a6e2afd43c803ae07265cee8bb4dabf 100644 (file)
@@ -3536,15 +3536,18 @@ extract_range_basic (value_range_t *vr, gimple stmt)
              /* If arg is non-zero, then ffs or popcount
                 are non-zero.  */
              if (((vr0->type == VR_RANGE
-                   && integer_nonzerop (vr0->min))
+                   && range_includes_zero_p (vr0->min, vr0->max) == 0)
                   || (vr0->type == VR_ANTI_RANGE
-                      && integer_zerop (vr0->min)))
-                 && !is_overflow_infinity (vr0->min))
+                      && range_includes_zero_p (vr0->min, vr0->max) == 1))
+                 && !is_overflow_infinity (vr0->min)
+                 && !is_overflow_infinity (vr0->max))
                mini = 1;
              /* If some high bits are known to be zero,
                 we can decrease the maximum.  */
              if (vr0->type == VR_RANGE
                  && TREE_CODE (vr0->max) == INTEGER_CST
+                 && !operand_less_p (vr0->min,
+                                     build_zero_cst (TREE_TYPE (vr0->min)))
                  && !is_overflow_infinity (vr0->max))
                maxi = tree_floor_log2 (vr0->max) + 1;
            }