This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/63464] compare one character to many: faster


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63464

--- Comment #16 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, I had a brief look at the #c14 issues.

--- gcc/match.pd.jj    2015-01-05 13:07:14.000000000 +0100
+++ gcc/match.pd    2015-01-16 16:27:08.053817209 +0100
@@ -614,6 +614,16 @@ (define_operator_list inverted_tcc_compa
   (cmp (bit_and (lshift integer_onep @0) integer_onep) integer_zerop)
   (icmp @0 { build_zero_cst (TREE_TYPE (@0)); })))

+/* ((type) ((A & 1) ^ 1)) == 0 -> (A & 1) != 0
+   ((type) ((A & 1) ^ 1)) != 0 -> (A & 1) == 0 */
+(for cmp (ne eq)
+     icmp (eq ne)
+ (simplify
+  (cmp (convert?@0 (bit_xor (bit_and@1 @2 integer_onep) integer_onep))
+       integer_zerop)
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) && INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+   (icmp @1 { build_zero_cst (TREE_TYPE (@1)); }))))
+
 /* Simplifications of conversions.  */

 /* Basic strip-useless-type-conversions / strip_nops.  */

worked (tried vrp66.c only) and managed to simplify *.optimized dump, though
there isn't DCE post forwprop4 so the dead ^1 and casts still stayed.
But apparently RTL optimization passes managed to fix that up and we get the
same assembly, so not sure if the above is worth pushing in.

Then I wanted to do at least something with the useless andl $1, %eax; xorl $1,
%eax; andl $1, %eax where the second andl is definitely complete unneeded.
I see two issues there.  One is that the ^ 1 does not have range info on it, as
it has been created by VRP2 pass.  For that I have:

--- gcc/tree-vrp.c.jj    2015-01-15 20:25:11.000000000 +0100
+++ gcc/tree-vrp.c    2015-01-16 17:33:21.041941783 +0100
@@ -8993,11 +8993,21 @@ simplify_truth_ops_using_ranges (gimple_
   /* For A != B we substitute A ^ B.  Either with conversion.  */
   else if (need_conversion)
     {
-      tree tem = make_ssa_name (TREE_TYPE (op0));
+      tree type = TREE_TYPE (op0);
+      tree tem = make_ssa_name (type);
       gassign *newop
     = gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
       gsi_insert_before (gsi, newop, GSI_SAME_STMT);
       gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
+
+      /* Record value range info for TEM.  */
+      value_range_t vr = VR_INITIALIZER;
+      extract_range_from_binary_expr (&vr, BIT_XOR_EXPR, type, op0, op1);
+      if (INTEGRAL_TYPE_P (type)
+      && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+      && TREE_CODE (vr.min) == INTEGER_CST
+      && TREE_CODE (vr.max) == INTEGER_CST)
+    set_range_info (tem, vr.type, vr.min, vr.max);
     }
   /* Or without.  */
   else

patch (also tested just on vrp66.c).  And the second issue is that nothing
actually uses the range info during expansion.  In particular, this is from
reduce_to_bit_field_precision, but unfortunately we don't pass the original
tree to that function.  If we did, say by adding (optionally NULL?) an extra
tree argument to REDUCE_BIT_FIELD macro, then we could in that function check
if it is an SSA_NAME for which we do have range info, and if the range info
suggests we don't have to mask (for unsigned types) or shift left/right (for
signed types), then it could avoid that step.  Richard, what do you think about
that?  Of course, for rtxes that don't have any corresponding tree we would
just pass NULL or some other value to make it clear that we don't know the
range info.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]