From 71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 18 Nov 2020 22:13:06 +0100 Subject: [PATCH] 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 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 | 6 ++--- .../gcc.c-torture/execute/pr97888-1.c | 24 +++++++++++++++++++ .../gcc.c-torture/execute/pr97888-2.c | 19 +++++++++++++++ gcc/testsuite/gcc.dg/pr91029.c | 3 ++- 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr97888-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr97888-2.c diff --git a/gcc/range-op.cc b/gcc/range-op.cc index f37796cac70..6be60073d19 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 00000000000..21fb6fc5f0a --- /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 00000000000..4f06ce6950c --- /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 8a4134c5d96..4904764e1ee 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) -- 2.30.2