diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2023-06-29 11:27:49 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2023-07-12 18:21:29 +0200 |
commit | 602e824eec30a7c6792b8b27d61c40f1c1a2714c (patch) | |
tree | 523bbcde95a826173c3cfbab1d4292e3fe337d40 | |
parent | 14b10ff30ad58265c5acd495c3b0e56563571b0c (diff) | |
download | gcc-602e824eec30a7c6792b8b27d61c40f1c1a2714c.zip gcc-602e824eec30a7c6792b8b27d61c40f1c1a2714c.tar.gz gcc-602e824eec30a7c6792b8b27d61c40f1c1a2714c.tar.bz2 |
[range-op] Enable value/mask propagation in range-op.
Throw the switch in range-ops to make full use of the value/mask
information instead of only the nonzero bits. This will cause most of
the operators implemented in range-ops to use the value/mask
information calculated by CCP's bit_value_binop() function which
range-ops uses. This opens up more optimization opportunities.
In follow-up patches I will change the global range setter
(set_range_info) to be able to save the value/mask pair, and make both
CCP and IPA be able to save the known ones bit info, instead of
throwing it away.
gcc/ChangeLog:
* range-op.cc (irange_to_masked_value): Remove.
(update_known_bitmask): Update irange value/mask pair instead of
only updating nonzero bits.
gcc/testsuite/ChangeLog:
* gcc.dg/pr83073.c: Adjust testcase.
-rw-r--r-- | gcc/range-op.cc | 53 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr83073.c | 2 |
2 files changed, 23 insertions, 32 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index cb58431..56e80c9 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -367,23 +367,6 @@ range_op_handler::op1_op2_relation (const vrange &lhs) const } -// Convert irange bitmasks into a VALUE MASK pair suitable for calling CCP. - -static void -irange_to_masked_value (const irange &r, widest_int &value, widest_int &mask) -{ - if (r.singleton_p ()) - { - mask = 0; - value = widest_int::from (r.lower_bound (), TYPE_SIGN (r.type ())); - } - else - { - mask = widest_int::from (r.get_nonzero_bits (), TYPE_SIGN (r.type ())); - value = 0; - } -} - // Update the known bitmasks in R when applying the operation CODE to // LH and RH. @@ -391,25 +374,33 @@ void update_known_bitmask (irange &r, tree_code code, const irange &lh, const irange &rh) { - if (r.undefined_p () || lh.undefined_p () || rh.undefined_p ()) + if (r.undefined_p () || lh.undefined_p () || rh.undefined_p () + || r.singleton_p ()) return; - widest_int value, mask, lh_mask, rh_mask, lh_value, rh_value; + widest_int widest_value, widest_mask; tree type = r.type (); signop sign = TYPE_SIGN (type); int prec = TYPE_PRECISION (type); - signop lh_sign = TYPE_SIGN (lh.type ()); - signop rh_sign = TYPE_SIGN (rh.type ()); - int lh_prec = TYPE_PRECISION (lh.type ()); - int rh_prec = TYPE_PRECISION (rh.type ()); - - irange_to_masked_value (lh, lh_value, lh_mask); - irange_to_masked_value (rh, rh_value, rh_mask); - bit_value_binop (code, sign, prec, &value, &mask, - lh_sign, lh_prec, lh_value, lh_mask, - rh_sign, rh_prec, rh_value, rh_mask); - wide_int tmp = wide_int::from (value | mask, prec, sign); - r.set_nonzero_bits (tmp); + irange_bitmask lh_bits = lh.get_bitmask (); + irange_bitmask rh_bits = rh.get_bitmask (); + + bit_value_binop (code, sign, prec, &widest_value, &widest_mask, + TYPE_SIGN (lh.type ()), + TYPE_PRECISION (lh.type ()), + widest_int::from (lh_bits.value (), sign), + widest_int::from (lh_bits.mask (), sign), + TYPE_SIGN (rh.type ()), + TYPE_PRECISION (rh.type ()), + widest_int::from (rh_bits.value (), sign), + widest_int::from (rh_bits.mask (), sign)); + + wide_int mask = wide_int::from (widest_mask, prec, sign); + wide_int value = wide_int::from (widest_value, prec, sign); + // Bitmasks must have the unknown value bits cleared. + value &= ~mask; + irange_bitmask bm (value, mask); + r.update_bitmask (bm); } // Return the upper limit for a type. diff --git a/gcc/testsuite/gcc.dg/pr83073.c b/gcc/testsuite/gcc.dg/pr83073.c index 1168ae82..228e189 100644 --- a/gcc/testsuite/gcc.dg/pr83073.c +++ b/gcc/testsuite/gcc.dg/pr83073.c @@ -7,4 +7,4 @@ int f(int x) return x & 1; } -/* { dg-final { scan-tree-dump "gimple_simplified to.* = 1" "evrp" } } */ +/* { dg-final { scan-tree-dump "Folded into: return 1;" "evrp" } } */ |