aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2023-06-29 11:27:49 +0200
committerAldy Hernandez <aldyh@redhat.com>2023-07-12 18:21:29 +0200
commit602e824eec30a7c6792b8b27d61c40f1c1a2714c (patch)
tree523bbcde95a826173c3cfbab1d4292e3fe337d40
parent14b10ff30ad58265c5acd495c3b0e56563571b0c (diff)
downloadgcc-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.cc53
-rw-r--r--gcc/testsuite/gcc.dg/pr83073.c2
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" } } */