aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-11-18 22:13:06 +0100
committerJakub Jelinek <jakub@redhat.com>2020-11-18 22:13:06 +0100
commit71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4 (patch)
treedbc66d21164a5d8b90a15b1bd222d78b50d0cd2c
parent84e0549ce206357dcd384cf8db14322c686d1eb2 (diff)
downloadgcc-71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4.zip
gcc-71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4.tar.gz
gcc-71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4.tar.bz2
vrp: Fix operator_trunc_mod::op1_range [PR97888]
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.
-rw-r--r--gcc/range-op.cc6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr97888-1.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr97888-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr91029.c3
4 files changed, 48 insertions, 4 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index f37796c..6be6007 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -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
index 0000000..21fb6fc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97888-1.c
@@ -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
index 0000000..4f06ce6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97888-2.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/pr91029.c b/gcc/testsuite/gcc.dg/pr91029.c
index 8a4134c..4904764 100644
--- a/gcc/testsuite/gcc.dg/pr91029.c
+++ b/gcc/testsuite/gcc.dg/pr91029.c
@@ -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)