]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[range-op] Enable value/mask propagation in range-op.
authorAldy Hernandez <aldyh@redhat.com>
Thu, 29 Jun 2023 09:27:49 +0000 (11:27 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Wed, 12 Jul 2023 16:21:29 +0000 (18:21 +0200)
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.

gcc/range-op.cc
gcc/testsuite/gcc.dg/pr83073.c

index cb584314f4cfc93aeec50c7f888829997a7dc8eb..56e80c9f3ae878ed3829782c3b8a026901576d1a 100644 (file)
@@ -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.
index 1168ae822a41b8656b253d3b186b9c21d6dfe206..228e1890086b481d9723007605d3104d9bb21fa6 100644 (file)
@@ -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" } }  */