Gimple isel already handles x CMP y ? -1 : 0 when lowering vector cond
operations, but this can be generalized further when the comparison
forms a natural mask so that we can also handle x CMP y ? z : 0 by
transforming it into (x CMP y) & z.  This will, in most cases save
having to load a register with the zero vector.

gcc/ChangeLog:
        * gimple-isel.cc (gimple_expand_vec_cond_expr): Handle
        x CMP y ? z : 0.
---
 gcc/gimple-isel.cc | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index a8f7a0d25d0..5bf4a4eccc1 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -190,16 +190,33 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi,
 	    can_compute_op0 = expand_vec_cmp_expr_p (op0a_type, op0_type,
 						     tcode);
 
-	  /* Try to fold x CMP y ? -1 : 0 to x CMP y.  */
+	  /* Try to fold x CMP y ? z : 0.  */
 	  if (can_compute_op0
-	      && integer_minus_onep (op1)
 	      && integer_zerop (op2)
 	      && TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (TREE_TYPE (op0)))
 	    {
-	      tree conv_op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), op0);
-	      gassign *new_stmt = gimple_build_assign (lhs, conv_op);
-	      gsi_replace (gsi, new_stmt, true);
-	      return new_stmt;
+	      /* If Z is -1, then the result is just the comparison.  */
+	      if (integer_minus_onep (op1))
+		{
+		  tree conv_op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
+					 op0);
+		  gassign *new_stmt = gimple_build_assign (lhs, conv_op);
+		  gsi_replace (gsi, new_stmt, true);
+		  return new_stmt;
+		}
+	      /* Otherwise, use the comparison as a mask for Z.  */
+	      else
+		{
+		  gimple_seq stmts = NULL;
+		  tree type = TREE_TYPE (lhs);
+		  location_t loc = gimple_location (stmt);
+		  tree tem0 = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
+					    type, op0);
+		  tree tem1 = gimple_build (&stmts, loc, BIT_AND_EXPR, type,
+					    tem0, op1);
+		  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+		  return gimple_build_assign (lhs, tem1);
+		}
 	    }
 
 	  /* When the compare has EH we do not want to forward it when

Reply via email to