diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2024-10-31 14:07:00 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2024-11-01 15:24:10 -0400 |
commit | 253fe0f6269516e37b3ef12a0d18e539b3cabd62 (patch) | |
tree | 71d80c21ee2b6be000cb45b59887a28c71164bea | |
parent | 62420dbd105bbc4fe732881875c5c85aa55b6069 (diff) | |
download | gcc-253fe0f6269516e37b3ef12a0d18e539b3cabd62.zip gcc-253fe0f6269516e37b3ef12a0d18e539b3cabd62.tar.gz gcc-253fe0f6269516e37b3ef12a0d18e539b3cabd62.tar.bz2 |
Update bitwise_or op_range.
If the LHS of a bitwise OR is positive, then so are both operands when
using op1_range or op2_range.
gcc/
* range-op.cc (operator_bitwise_or::op1_range): If LHS is signed
positive, so are both operands.
gcc/testsuite
* g++.dg/cpp23/attr-assume-opt.C (f2b): Alternate flow test.
-rw-r--r-- | gcc/range-op.cc | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C | 37 |
2 files changed, 49 insertions, 1 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 58734cd..5a1eb59 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -3822,6 +3822,19 @@ operator_bitwise_or::op1_range (irange &r, tree type, r.set_zero (type); return true; } + + // if (A < 0 && B < 0) + // Sometimes gets translated to + // _1 = A | B + // if (_1 < 0)) + // It is useful for ranger to recognize a positive LHS means the RHS + // operands are also positive when dealing with the ELSE range.. + if (TYPE_SIGN (type) == SIGNED && wi::ge_p (lhs.lower_bound (), 0, SIGNED)) + { + unsigned prec = TYPE_PRECISION (type); + r.set (type, wi::zero (prec), wi::max_value (prec, SIGNED)); + return true; + } r.set_varying (type); return true; } diff --git a/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C b/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C index 88d5e78..e61ba7a 100644 --- a/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C +++ b/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C @@ -38,5 +38,40 @@ f3 (int x, int y, int z) return 1; } +// This is the same as f2, except there is more complicated flow and +// required a range-op update to bitwise or. + +void barn(int x); +// assume (x+12 == 14 && y >= 0 && y + 10 < 13 && z + 4 >= 4 && z - 2 < 18) +// in different order and form with function calls to cause branches. +bool assume_func (int x, int y, int z) +{ + if (z - 2 >= 18) + return false; + if (x+12 != 14) + return false; + barn (x); + if (y < 0) + return false; + if (z + 4 < 4) + return false; + barn (y); + if (y + 10 >= 13) + return false; + barn (z); + return true; +} + +int +f2b (int x, int y, int z) +{ + [[assume (assume_func (x, y, z))]]; + unsigned q = x + y + z; + if (q*2 > 46) + return 0; + return 1; +} + + /* { dg-final { scan-tree-dump-times "return 0" 0 "vrp2" } } */ -/* { dg-final { scan-tree-dump-times "return 1" 3 "vrp2" } } */ +/* { dg-final { scan-tree-dump-times "return 1" 4 "vrp2" } } */ |