diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2025-03-26 10:34:42 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2025-03-28 10:25:30 -0400 |
commit | dd9ed951f4002419ceff744bbd87ae9b8affdaf4 (patch) | |
tree | 7b30ffedee0f05f8c3ab7d3edb8e8bbeea78f159 | |
parent | dcb7009efc5358207d1b0612732a0608915a3ef7 (diff) | |
download | gcc-dd9ed951f4002419ceff744bbd87ae9b8affdaf4.zip gcc-dd9ed951f4002419ceff744bbd87ae9b8affdaf4.tar.gz gcc-dd9ed951f4002419ceff744bbd87ae9b8affdaf4.tar.bz2 |
If the LHS does not contain zero, neither do multiply operands.
Given ~[0,0] = op1 * op2, range-ops should determine that neither op1 nor
op2 is zero. Add this to the operator_mult for op1_range. op2_range
simply invokes op1_range, so both will be covered.
PR tree-optimzation/110992.c
PR tree-optimzation/119471.c
gcc/
* range-op.cc (operator_mult::op1_range): If the LHS does not
contain zero, return non-zero.
gcc/testsuite/
* gcc.dg/pr110992.c: New.
* gcc.dg/pr119471.c: New.
-rw-r--r-- | gcc/range-op.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr110992.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr119471.c | 19 |
3 files changed, 44 insertions, 0 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 6310ce2..f72b4ae 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -2220,6 +2220,13 @@ operator_mult::op1_range (irange &r, tree type, wide_int offset; if (op2.singleton_p (offset) && offset != 0) return range_op_handler (TRUNC_DIV_EXPR).fold_range (r, type, lhs, op2); + + // ~[0, 0] = op1 * op2 defines op1 and op2 as non-zero. + if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ())))) + { + r.set_nonzero (type); + return true; + } return false; } diff --git a/gcc/testsuite/gcc.dg/pr110992.c b/gcc/testsuite/gcc.dg/pr110992.c new file mode 100644 index 0000000..05e9b92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110992.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +void foo (int); + +int f(unsigned b, short c) +{ + int bt = b; + int bt1 = bt; + int t = bt1 & -(c!=0); + // int t = bt1 * (c!=0); + + if (!t) return 0; + foo(bt == 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "foo \\(0\\)" 1 "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/pr119471.c b/gcc/testsuite/gcc.dg/pr119471.c new file mode 100644 index 0000000..4c55d85 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119471.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +int fa(int a, int b) +{ + int c = a * b; + if (c != 0) + return (a != 0); + return 0; +} +int fb(int a, int b) +{ + int c = a * b; + if (c != 0) + return (b != 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "PHI <1" 2 "evrp" } } */ |