diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2023-10-25 09:46:50 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2023-11-03 12:54:50 -0400 |
commit | 7ab79a40b546a1470abaf76bec74c63e9990fe47 (patch) | |
tree | 6e109809952740cce8211058a0b44f70aea973c5 /gcc/range-op.cc | |
parent | a291237b628f419d7f7ac264dd7b42947b565222 (diff) | |
download | gcc-7ab79a40b546a1470abaf76bec74c63e9990fe47.zip gcc-7ab79a40b546a1470abaf76bec74c63e9990fe47.tar.gz gcc-7ab79a40b546a1470abaf76bec74c63e9990fe47.tar.bz2 |
Adjust operators equal and not_equal to check bitmasks against constants
Check to see if a comparison to a constant can be determined to always
be not-equal based on the bitmask.
PR tree-optimization/111766
gcc/
* range-op.cc (operator_equal::fold_range): Check constants
against the bitmask.
(operator_not_equal::fold_range): Ditto.
* value-range.h (irange_bitmask::member_p): New.
gcc/testsuite/
* gcc.dg/pr111766.c: New.
Diffstat (limited to 'gcc/range-op.cc')
-rw-r--r-- | gcc/range-op.cc | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 33b193b..6137f2a 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -931,8 +931,9 @@ operator_equal::fold_range (irange &r, tree type, // We can be sure the values are always equal or not if both ranges // consist of a single value, and then compare them. - if (wi::eq_p (op1.lower_bound (), op1.upper_bound ()) - && wi::eq_p (op2.lower_bound (), op2.upper_bound ())) + bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ()); + bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ()); + if (op1_const && op2_const) { if (wi::eq_p (op1.lower_bound (), op2.upper_bound())) r = range_true (type); @@ -947,6 +948,11 @@ operator_equal::fold_range (irange &r, tree type, tmp.intersect (op2); if (tmp.undefined_p ()) r = range_false (type); + // Check if a constant cannot satisfy the bitmask requirements. + else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ())) + r = range_false (type); + else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ())) + r = range_false (type); else r = range_true_and_false (type); } @@ -1033,8 +1039,9 @@ operator_not_equal::fold_range (irange &r, tree type, // We can be sure the values are always equal or not if both ranges // consist of a single value, and then compare them. - if (wi::eq_p (op1.lower_bound (), op1.upper_bound ()) - && wi::eq_p (op2.lower_bound (), op2.upper_bound ())) + bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ()); + bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ()); + if (op1_const && op2_const) { if (wi::ne_p (op1.lower_bound (), op2.upper_bound())) r = range_true (type); @@ -1049,6 +1056,11 @@ operator_not_equal::fold_range (irange &r, tree type, tmp.intersect (op2); if (tmp.undefined_p ()) r = range_true (type); + // Check if a constant cannot satisfy the bitmask requirements. + else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ())) + r = range_true (type); + else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ())) + r = range_true (type); else r = range_true_and_false (type); } |