[gcc r17-3336] range-op: add VREL_NE relation effect for bit_ior [PR126743]
Daniel Barboza via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:9a54dbee11c890546b0bad8e3022296f02449181 commit r17-3336-g9a54dbee11c890546b0bad8e3022296f02449181 Author: Daniel Barboza <[email protected]> Date: Wed Aug 12 06:25:15 2026 -0300 range-op: add VREL_NE relation effect for bit_ior [PR126743] Given a bit_ior in the format A | B, if we know for certain that A != B then we can infer that A | B will always be nonzero. Bootstrapped and regression tested in x86_64, aarch64 and riscv64. PR tree-optimization/126743 gcc/ChangeLog: * range-op-mixed.h: declare. * range-op.cc (operator_bitwise_or::op1_op2_relation_effect): add op1 NE op2 relation range for op1 | op2 as nonzero. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr126743.c: New test. Diff: --- gcc/range-op-mixed.h | 6 ++++++ gcc/range-op.cc | 25 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr126743.c | 23 +++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index a870a0c12116..0e97fb11688c 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -849,6 +849,7 @@ public: using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation_effect; using range_operator::update_bitmask; bool fold_range (prange &r, tree type, @@ -861,6 +862,11 @@ public: bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, relation_trio rel = TRIO_VARYING) const override; + bool op1_op2_relation_effect (irange &lhs_range, + tree type, + const irange &op1_range, + const irange &op2_range, + relation_kind rel) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const override; // Check compatibility of all operands. diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 71f1a91f0790..bb0556238728 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -4102,6 +4102,31 @@ operator_bitwise_or::wi_fold (irange &r, tree type, value_range_with_overflow (r, type, new_lb, new_ub); } +bool +operator_bitwise_or::op1_op2_relation_effect (irange &lhs_range, + tree type, + const irange &, + const irange &, + relation_kind rel) const +{ + if (rel == VREL_VARYING) + return false; + + int_range<2> rel_range; + + switch (rel) + { + case VREL_NE: + rel_range.set_nonzero (type); + break; + default: + return false; + } + + lhs_range.intersect (rel_range); + return true; +} + bool operator_bitwise_or::op1_range (irange &r, tree type, const irange &lhs, diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126743.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126743.c new file mode 100644 index 000000000000..a99e6efbff9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126743.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +unsigned int +or_eq_zero (int a, int b) +{ + if (a == b) + __builtin_unreachable (); + // return 0; + return (a | b) == 0; +} + +unsigned int +or_ne_zero (int a, int b) +{ + if (a == b) + __builtin_unreachable (); + // return 1; + return (a | b) != 0; +} + +/* { dg-final { scan-tree-dump-times "return 0;" 1 "evrp" } } */ +/* { dg-final { scan-tree-dump-times "return 1;" 1 "evrp" } } */