On 10/31/22 05:53, Tamar Christina wrote:
Hi All,

This adds a new test-and-branch optab that can be used to do a conditional test
of a bit and branch.   This is similar to the cbranch optab but instead can
test any arbitrary bit inside the register.

This patch recognizes boolean comparisons and single bit mask tests.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

        * dojump.cc (do_jump): Pass along value.
        (do_jump_by_parts_greater_rtx): Likewise.
        (do_jump_by_parts_zero_rtx): Likewise.
        (do_jump_by_parts_equality_rtx): Likewise.
        (do_compare_rtx_and_jump): Likewise.
        (do_compare_and_jump): Likewise.
        * dojump.h (do_compare_rtx_and_jump): New.
        * optabs.cc (emit_cmp_and_jump_insn_1): Refactor to take optab to check.
        (validate_test_and_branch): New.
        (emit_cmp_and_jump_insns): Optiobally take a value, and when value is
        supplied then check if it's suitable for tbranch.
        * optabs.def (tbranch$a4): New.
        * doc/md.texi (tbranch@var{mode}4): Document it.
        * optabs.h (emit_cmp_and_jump_insns):
        * tree.h (tree_zero_one_valued_p): New.

--- inline copy of patch --
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 
c08691ab4c9a4bfe55ae81e5e228a414d6242d78..f8b32ec12f46d3fb3815f121a16b5a8a1819b66a
 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -6972,6 +6972,13 @@ case, you can and should make operand 1's predicate 
reject some operators
  in the @samp{cstore@var{mode}4} pattern, or remove the pattern altogether
  from the machine description.
+@cindex @code{tbranch@var{mode}4} instruction pattern
+@item @samp{tbranch@var{mode}4}
+Conditional branch instruction combined with a bit test-and-compare
+instruction. Operand 0 is a comparison operator.  Operand 1 is the
+operand of the comparison. Operand 2 is the bit position of Operand 1 to test.
+Operand 3 is the @code{code_label} to jump to.

Should we refine/document the set of comparison operators allowed?    Is operand 1 an arbitrary RTL expression or more limited?  I'm guessing its relatively arbitrary given how you've massaged the existing branch-on-bit patterns from the aarch backend.


+
+  if (TREE_CODE (val) != SSA_NAME)
+    return false;
+
+  gimple *def = SSA_NAME_DEF_STMT (val);
+  if (!is_gimple_assign (def)
+      || gimple_assign_rhs_code (def) != BIT_AND_EXPR)
+    return false;
+
+  tree cst = gimple_assign_rhs2 (def);
+
+  if (!tree_fits_uhwi_p (cst))
+    return false;
+
+  tree op0 = gimple_assign_rhs1 (def);
+  if (TREE_CODE (op0) == SSA_NAME)
+    {
+      def = SSA_NAME_DEF_STMT (op0);
+      if (gimple_assign_cast_p (def))
+       op0 = gimple_assign_rhs1 (def);
+    }
+
+  wide_int wcst = wi::uhwi (tree_to_uhwi (cst),
+                           TYPE_PRECISION (TREE_TYPE (op0)));
+  int bitpos;
+
+  if ((bitpos = wi::exact_log2 (wcst)) == -1)
+    return false;

Do we have enough information lying around from Ranger to avoid the need to walk the def-use chain to discover that we're masking off all but one bit?



diff --git a/gcc/tree.h b/gcc/tree.h
index 
8f8a9660c9e0605eb516de194640b8c1b531b798..be3d2dee82f692e81082cf21c878c10f9fe9e1f1
 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4690,6 +4690,7 @@ extern tree signed_or_unsigned_type_for (int, tree);
  extern tree signed_type_for (tree);
  extern tree unsigned_type_for (tree);
  extern bool is_truth_type_for (tree, tree);
+extern bool tree_zero_one_valued_p (tree);

I don't see a definition of this anywhere.


jeff


Reply via email to