]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
isel: Fold more in gimple_expand_vec_cond_expr with andc and iorc [PR115659]
authorKewen Lin <linkw@linux.ibm.com>
Mon, 8 Jul 2024 05:14:59 +0000 (00:14 -0500)
committerKewen Lin <linkw@gcc.gnu.org>
Mon, 8 Jul 2024 05:14:59 +0000 (00:14 -0500)
As PR115659 shows, assuming c = x CMP y, there are some
folding chances for patterns r = c ? 0/z : z/-1:
  - for r = c ? 0 : z, it can be folded into r = ~c & z.
  - for r = c ? z : -1, it can be folded into r = ~c | z.

But BIT_AND/BIT_IOR applied on one BIT_NOT operand is a
compound operation, it's arguable to consider it beats
vector selection.  So this patch is to introduce new
optabs andc, iorc and its corresponding internal functions
BIT_{ANDC,IORC}, and if targets defines such optabs for
vector modes, it means targets support these hardware
insns and should be not worse than vector selection.

PR tree-optimization/115659

gcc/ChangeLog:

* doc/md.texi: Document andcm3 and iorcm3.
* gimple-isel.cc (gimple_expand_vec_cond_expr): Add more foldings for
patterns x CMP y ? 0 : z and x CMP y ? z : -1.
* internal-fn.def (BIT_ANDC): New internal function.
(BIT_IORC): Likewise.
* optabs.def (andc, iorc): New optab.

gcc/doc/md.texi
gcc/gimple-isel.cc
gcc/internal-fn.def
gcc/optabs.def

index 4fd7da095feb90e612fb4cde30367f11a660b2da..7f4335e0aac19c074393e3eac5692ff8123e1094 100644 (file)
@@ -5543,6 +5543,16 @@ means of constraints requiring operands 1 and 0 to be the same location.
 @itemx @samp{and@var{m}3}, @samp{ior@var{m}3}, @samp{xor@var{m}3}
 Similar, for other arithmetic operations.
 
+@cindex @code{andc@var{m}3} instruction pattern
+@item @samp{andc@var{m}3}
+Like @code{and@var{m}3}, but it uses bitwise-complement of operand 2
+rather than operand 2 itself.
+
+@cindex @code{iorc@var{m}3} instruction pattern
+@item @samp{iorc@var{m}3}
+Like @code{ior@var{m}3}, but it uses bitwise-complement of operand 2
+rather than operand 2 itself.
+
 @cindex @code{addv@var{m}4} instruction pattern
 @item @samp{addv@var{m}4}
 Like @code{add@var{m}3} but takes a @code{code_label} as operand 3 and
index 60719eafc6514621fa367393f412bec3e5f3c85f..e4ab42ad05ba000177fc65232360eb5659bc4aeb 100644 (file)
@@ -284,6 +284,32 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi,
                  /* r = c ? z : c */
                  op2 = new_op2;
                }
+             bool op1_zerop = integer_zerop (op1);
+             bool op2_minus_onep = integer_minus_onep (op2);
+             /* Try to fold r = c ? 0 : z to r = .BIT_ANDC (z, c).  */
+             if (op1_zerop
+                 && (direct_internal_fn_supported_p (IFN_BIT_ANDC, vtype,
+                                                     OPTIMIZE_FOR_BOTH)))
+               {
+                 tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
+                 tree new_op = make_ssa_name (vtype);
+                 gassign *new_stmt = gimple_build_assign (new_op, conv_op);
+                 gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
+                 return gimple_build_call_internal (IFN_BIT_ANDC, 2, op2,
+                                                    new_op);
+               }
+             /* Try to fold r = c ? z : -1 to r = .BIT_IORC (z, c).  */
+             else if (op2_minus_onep
+                      && (direct_internal_fn_supported_p (IFN_BIT_IORC, vtype,
+                                                          OPTIMIZE_FOR_BOTH)))
+               {
+                 tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
+                 tree new_op = make_ssa_name (vtype);
+                 gassign *new_stmt = gimple_build_assign (new_op, conv_op);
+                 gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
+                 return gimple_build_call_internal (IFN_BIT_IORC, 2, op1,
+                                                    new_op);
+               }
            }
 
          /* When the compare has EH we do not want to forward it when
index 915d329c05a00074072d10e81f81d6eef7467bc9..0b45f322f0db0969e53a2dc691d01321624fabea 100644 (file)
@@ -595,6 +595,10 @@ DEF_INTERNAL_FN (DIVMODBITINT, ECF_LEAF, ". O . O . R . R . ")
 DEF_INTERNAL_FN (FLOATTOBITINT, ECF_LEAF | ECF_NOTHROW, ". O . . ")
 DEF_INTERNAL_FN (BITINTTOFLOAT, ECF_PURE | ECF_LEAF, ". R . ")
 
+/* Bitwise functions.  */
+DEF_INTERNAL_OPTAB_FN (BIT_ANDC, ECF_CONST, andc, binary)
+DEF_INTERNAL_OPTAB_FN (BIT_IORC, ECF_CONST, iorc, binary)
+
 #undef DEF_INTERNAL_WIDENING_OPTAB_FN
 #undef DEF_INTERNAL_SIGNED_COND_FN
 #undef DEF_INTERNAL_COND_FN
index a69af51d60120712922f754f75704d204d6fde6f..45e117a7f508c00062762b0f3a2bbd2986b0563f 100644 (file)
@@ -545,3 +545,5 @@ OPTAB_D (vec_shl_insert_optab, "vec_shl_insert_$a")
 OPTAB_D (len_load_optab, "len_load_$a")
 OPTAB_D (len_store_optab, "len_store_$a")
 OPTAB_D (select_vl_optab, "select_vl$a")
+OPTAB_D (andc_optab, "andc$a3")
+OPTAB_D (iorc_optab, "iorc$a3")