vrp: Fix operator_trunc_mod::op1_range [PR97888]
authorJakub Jelinek <jakub@redhat.com>
Wed, 18 Nov 2020 21:13:06 +0000 (22:13 +0100)
committerJakub Jelinek <jakub@redhat.com>
Wed, 18 Nov 2020 21:13:06 +0000 (22:13 +0100)
As mentioned in the PR, in (x % y) >= 0 && y >= 0, we can't deduce
x's range to be x >= 0, as e.g. -7 % 7 is 0.  But we can deduce it
from (x % y) > 0.  The patch also fixes up the comments.

2020-11-18  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/91029
PR tree-optimization/97888
* range-op.cc (operator_trunc_mod::op1_range): Only set op1
range to >= 0 if lhs is > 0, rather than >= 0.  Fix up comments.

* gcc.dg/pr91029.c: Add comment with PR number.
(f2): Use > 0 rather than >= 0.
* gcc.c-torture/execute/pr97888-1.c: New test.
* gcc.c-torture/execute/pr97888-2.c: New test.

gcc/range-op.cc
gcc/testsuite/gcc.c-torture/execute/pr97888-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr97888-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr91029.c

index f37796cac709e062591ee09f304cfe494495a9b3..6be60073d19fe71ed5055455e344a02a90bc064a 100644 (file)
@@ -2692,13 +2692,13 @@ operator_trunc_mod::op1_range (irange &r, tree type,
   if (TYPE_SIGN (type) == SIGNED && wi::ge_p (op2.lower_bound (), 0, SIGNED))
     {
       unsigned prec = TYPE_PRECISION (type);
-      // if a & b >=0 , then a >= 0.
-      if (wi::ge_p (lhs.lower_bound (), 0, SIGNED))
+      // if a % b > 0 , then a >= 0.
+      if (wi::gt_p (lhs.lower_bound (), 0, SIGNED))
        {
          r = value_range (type, wi::zero (prec), wi::max_value (prec, SIGNED));
          return true;
        }
-      // if a & b < 0 , then a <= 0.
+      // if a % b < 0 , then a <= 0.
       if (wi::lt_p (lhs.upper_bound (), 0, SIGNED))
        {
          r = value_range (type, wi::min_value (prec, SIGNED), wi::zero (prec));
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97888-1.c b/gcc/testsuite/gcc.c-torture/execute/pr97888-1.c
new file mode 100644 (file)
index 0000000..21fb6fc
--- /dev/null
@@ -0,0 +1,24 @@
+/* PR tree-optimization/97888 */
+
+int a = 1, c = 4, d, e;
+
+int
+main ()
+{
+  int f = -173;
+  int b;
+  for (b = 0; b < 10; b++)
+    {
+      int g = f % (~0 && a), h = 0, i = 0;
+      if (g)
+       __builtin_unreachable ();
+      if (c)
+       h = f;
+      if (h > -173)
+       e = d / i;
+      f = h;
+    }
+  if (f != -173)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97888-2.c b/gcc/testsuite/gcc.c-torture/execute/pr97888-2.c
new file mode 100644 (file)
index 0000000..4f06ce6
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR tree-optimization/97888 */
+
+__attribute__((noipa)) void
+foo (int i)
+{
+  if ((i % 7) >= 0)
+    {
+      if (i >= 0)
+        __builtin_abort ();
+    }
+}
+
+int
+main ()
+{
+  foo (-7);
+  foo (-21);
+  return 0;
+}
index 8a4134c5d96d88c99c4d4366e0a4bc5ed3888018..4904764e1ee7110bd11471ddc5aab1a6f4171c28 100644 (file)
@@ -1,3 +1,4 @@
+/* PR tree-optimization/91029 */
 /* { dg-do compile } */
 /* { dg-options "-O2 -fdump-tree-evrp" } */
 
@@ -16,7 +17,7 @@ void f1 (int i)
 
 void f2 (int i)
 {
-  if ((i % 7) >= 0)
+  if ((i % 7) > 0)
     {
       xx = (i < 0);
       if (xx)