Hi All,

This adds vector constant simplification for EQ and NE.  This is useful since
the vectorizer generates a lot more vector compares now, in particular NE and EQ
and so these help us optimize cases where the values were not known at GIMPLE
but instead only at RTL.

Bootstrapped Regtested on aarch64-none-linux-gnu, arm-none-linux-gnueabihf,
x86_64-pc-linux-gnu -m32, -m64 and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

        * simplify-rtx.cc (simplify_context::simplify_unary_operation): Try
        simplifying operand.
        (simplify_const_relational_operation): Simplify vector EQ and NE.
        (test_vector_int_const_compare): New.
        (test_vector_int_const_compare_ops): New.
        (simplify_rtx_cc_tests): Use them.

---
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 
a20a61c5dddbc80b23a9489d925a2c31b2163458..7e83e80246b70c81c388e77967f645d171efe983
 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -886,6 +886,10 @@ simplify_context::simplify_unary_operation (rtx_code code, 
machine_mode mode,
 
   trueop = avoid_constant_pool_reference (op);
 
+  /* If the operand is not a reg or constant try simplifying it first.  */
+  if (rtx tmp_op = simplify_rtx (op))
+    op = tmp_op;
+
   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
   if (tem)
     return tem;
@@ -6354,6 +6358,35 @@ simplify_const_relational_operation (enum rtx_code code,
        return 0;
     }
 
+  /* Check if the operands are a vector EQ or NE comparison.  */
+  if (VECTOR_MODE_P (mode)
+      && INTEGRAL_MODE_P (mode)
+      && GET_CODE (op0) == CONST_VECTOR
+      && GET_CODE (op1) == CONST_VECTOR
+      && (code == EQ || code == NE))
+    {
+      if (rtx_equal_p (op0, op1))
+       return code == EQ ? const_true_rtx : const0_rtx;
+
+      unsigned int npatterns0, npatterns1;
+      if (CONST_VECTOR_NUNITS (op0).is_constant (&npatterns0)
+         && CONST_VECTOR_NUNITS (op1).is_constant (&npatterns1))
+       {
+         if (npatterns0 != npatterns1)
+           return code == EQ ? const0_rtx : const_true_rtx;
+
+         for (unsigned i = 0; i < npatterns0; i++)
+           {
+             rtx val0 = CONST_VECTOR_ELT (op0, i);
+             rtx val1 = CONST_VECTOR_ELT (op1, i);
+             if (!rtx_equal_p (val0, val1))
+               return code == EQ ? const0_rtx : const_true_rtx;
+           }
+
+         return code == EQ ? const_true_rtx : const0_rtx;
+       }
+    }
+
   /* We can't simplify MODE_CC values since we don't know what the
      actual comparison is.  */
   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
@@ -8820,6 +8853,55 @@ test_vector_ops ()
     }
 }
 
+/* Verify vector constant comparisons for EQ and NE.  */
+
+static void
+test_vector_int_const_compare (machine_mode mode)
+{
+  rtx zeros = CONST0_RTX (mode);
+  rtx minusone = CONSTM1_RTX (mode);
+  rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
+  ASSERT_RTX_EQ (const0_rtx,
+                simplify_const_relational_operation (EQ, mode, zeros,
+                                                     CONST1_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+                simplify_const_relational_operation (EQ, mode, zeros,
+                                                     CONST0_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+                simplify_const_relational_operation (EQ, mode, minusone,
+                                                     CONSTM1_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+                simplify_const_relational_operation (NE, mode, zeros,
+                                                     CONST1_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+                simplify_const_relational_operation (NE, mode, zeros,
+                                                     series_0_1));
+  ASSERT_RTX_EQ (const0_rtx,
+                simplify_const_relational_operation (EQ, mode, zeros,
+                                                     series_0_1));
+}
+
+/* Verify some simplifications involving vectors integer comparisons.  */
+
+static void
+test_vector_int_const_compare_ops ()
+{
+  for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
+    {
+      machine_mode mode = (machine_mode) i;
+      if (VECTOR_MODE_P (mode)
+         && INTEGRAL_MODE_P (mode)
+         && GET_MODE_NUNITS (mode).is_constant ())
+       {
+         if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+             && maybe_gt (GET_MODE_NUNITS (mode), 2))
+           {
+             test_vector_int_const_compare (mode);
+           }
+       }
+    }
+}
+
 template<unsigned int N>
 struct simplify_const_poly_int_tests
 {
@@ -8875,6 +8957,7 @@ simplify_rtx_cc_tests ()
 {
   test_scalar_ops ();
   test_vector_ops ();
+  test_vector_int_const_compare_ops ();
   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
 }
 




-- 
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index a20a61c5dddbc80b23a9489d925a2c31b2163458..7e83e80246b70c81c388e77967f645d171efe983 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -886,6 +886,10 @@ simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
 
   trueop = avoid_constant_pool_reference (op);
 
+  /* If the operand is not a reg or constant try simplifying it first.  */
+  if (rtx tmp_op = simplify_rtx (op))
+    op = tmp_op;
+
   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
   if (tem)
     return tem;
@@ -6354,6 +6358,35 @@ simplify_const_relational_operation (enum rtx_code code,
 	return 0;
     }
 
+  /* Check if the operands are a vector EQ or NE comparison.  */
+  if (VECTOR_MODE_P (mode)
+      && INTEGRAL_MODE_P (mode)
+      && GET_CODE (op0) == CONST_VECTOR
+      && GET_CODE (op1) == CONST_VECTOR
+      && (code == EQ || code == NE))
+    {
+      if (rtx_equal_p (op0, op1))
+	return code == EQ ? const_true_rtx : const0_rtx;
+
+      unsigned int npatterns0, npatterns1;
+      if (CONST_VECTOR_NUNITS (op0).is_constant (&npatterns0)
+	  && CONST_VECTOR_NUNITS (op1).is_constant (&npatterns1))
+	{
+	  if (npatterns0 != npatterns1)
+	    return code == EQ ? const0_rtx : const_true_rtx;
+
+	  for (unsigned i = 0; i < npatterns0; i++)
+	    {
+	      rtx val0 = CONST_VECTOR_ELT (op0, i);
+	      rtx val1 = CONST_VECTOR_ELT (op1, i);
+	      if (!rtx_equal_p (val0, val1))
+		return code == EQ ? const0_rtx : const_true_rtx;
+	    }
+
+	  return code == EQ ? const_true_rtx : const0_rtx;
+	}
+    }
+
   /* We can't simplify MODE_CC values since we don't know what the
      actual comparison is.  */
   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
@@ -8820,6 +8853,55 @@ test_vector_ops ()
     }
 }
 
+/* Verify vector constant comparisons for EQ and NE.  */
+
+static void
+test_vector_int_const_compare (machine_mode mode)
+{
+  rtx zeros = CONST0_RTX (mode);
+  rtx minusone = CONSTM1_RTX (mode);
+  rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
+  ASSERT_RTX_EQ (const0_rtx,
+		 simplify_const_relational_operation (EQ, mode, zeros,
+						      CONST1_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+		 simplify_const_relational_operation (EQ, mode, zeros,
+						      CONST0_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+		 simplify_const_relational_operation (EQ, mode, minusone,
+						      CONSTM1_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+		 simplify_const_relational_operation (NE, mode, zeros,
+						      CONST1_RTX (mode)));
+  ASSERT_RTX_EQ (const_true_rtx,
+		 simplify_const_relational_operation (NE, mode, zeros,
+						      series_0_1));
+  ASSERT_RTX_EQ (const0_rtx,
+		 simplify_const_relational_operation (EQ, mode, zeros,
+						      series_0_1));
+}
+
+/* Verify some simplifications involving vectors integer comparisons.  */
+
+static void
+test_vector_int_const_compare_ops ()
+{
+  for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
+    {
+      machine_mode mode = (machine_mode) i;
+      if (VECTOR_MODE_P (mode)
+	  && INTEGRAL_MODE_P (mode)
+	  && GET_MODE_NUNITS (mode).is_constant ())
+	{
+	  if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+	      && maybe_gt (GET_MODE_NUNITS (mode), 2))
+	    {
+	      test_vector_int_const_compare (mode);
+	    }
+	}
+    }
+}
+
 template<unsigned int N>
 struct simplify_const_poly_int_tests
 {
@@ -8875,6 +8957,7 @@ simplify_rtx_cc_tests ()
 {
   test_scalar_ops ();
   test_vector_ops ();
+  test_vector_int_const_compare_ops ();
   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
 }
 



Reply via email to