Patchwork Fix some VEC_COND_EXPR ICEs (PR tree-optimization/55281)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 12, 2012, 7:43 p.m.
Message ID <20121112194357.GS1886@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/198443/
State New
Headers show

Comments

Jakub Jelinek - Nov. 12, 2012, 7:43 p.m.
Hi!

This patch fixes two ICEs on the testcases, one is ICE in
expand_vector_condition which wouldn't handle VECTOR_CST as first argument
of VEC_COND_EXPR (plus a change to make sure it is folded earlier if
possible), and the vectorizable_condition change makes sure the condition
is actually using a vector of integers instead of vector of floats and
similar, which crashes because fold-const.c isn't anywhere close to be
prepared for floating point type (or vector float) of NE_EXPR and other
comparison tree codes.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-11-12  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/55281
	* tree-vect-generic.c (expand_vector_condition): Accept any
	is_gimple_val rather than just SSA_NAME if not COMPARISON_CLASS_P.
	* fold-const.c (fold_ternary_loc): Fold VEC_COND_EXPR if arg0 is
	either integer_all_onesp or integer_zerop.
	* tree-vect-stmts.c (vectorizable_condition): Build the condition
	using corresponding vector integer type instead of vectype.

	* gcc.dg/vect/fast-math-pr55281.c: New test.
	* g++.dg/opt/pr55281.C: New test.


	Jakub
Richard Henderson - Nov. 12, 2012, 8:19 p.m.
On 11/12/2012 11:43 AM, Jakub Jelinek wrote:
> 2012-11-12  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/55281
> 	* tree-vect-generic.c (expand_vector_condition): Accept any
> 	is_gimple_val rather than just SSA_NAME if not COMPARISON_CLASS_P.
> 	* fold-const.c (fold_ternary_loc): Fold VEC_COND_EXPR if arg0 is
> 	either integer_all_onesp or integer_zerop.
> 	* tree-vect-stmts.c (vectorizable_condition): Build the condition
> 	using corresponding vector integer type instead of vectype.
> 
> 	* gcc.dg/vect/fast-math-pr55281.c: New test.
> 	* g++.dg/opt/pr55281.C: New test.

Ok.


r~

Patch

--- gcc/tree-vect-generic.c.jj	2012-11-02 09:01:55.000000000 +0100
+++ gcc/tree-vect-generic.c	2012-11-12 12:14:49.978619417 +0100
@@ -892,7 +892,7 @@  expand_vector_condition (gimple_stmt_ite
   int i;
   location_t loc = gimple_location (gsi_stmt (*gsi));
 
-  if (TREE_CODE (a) != SSA_NAME)
+  if (!is_gimple_val (a))
     {
       gcc_assert (COMPARISON_CLASS_P (a));
       a_is_comparison = true;
--- gcc/fold-const.c.jj	2012-11-08 21:08:25.000000000 +0100
+++ gcc/fold-const.c	2012-11-12 15:51:45.118969684 +0100
@@ -14036,6 +14036,16 @@  fold_ternary_loc (location_t loc, enum t
 
       return NULL_TREE;
 
+    case VEC_COND_EXPR:
+      if (TREE_CODE (arg0) == VECTOR_CST)
+	{
+	  if (integer_all_onesp (arg0) && !TREE_SIDE_EFFECTS (op2))
+	    return pedantic_non_lvalue_loc (loc, op1);
+	  if (integer_zerop (arg0) && !TREE_SIDE_EFFECTS (op1))
+	    return pedantic_non_lvalue_loc (loc, op2);
+	}
+      return NULL_TREE;
+
     case CALL_EXPR:
       /* CALL_EXPRs used to be ternary exprs.  Catch any mistaken uses
 	 of fold_ternary on them.  */
--- gcc/tree-vect-stmts.c.jj	2012-11-07 08:42:08.000000000 +0100
+++ gcc/tree-vect-stmts.c	2012-11-12 15:29:12.012684236 +0100
@@ -5310,6 +5310,7 @@  vectorizable_condition (gimple stmt, gim
   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
   VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
   VEC (tree, heap) *vec_oprnds2 = NULL, *vec_oprnds3 = NULL;
+  tree vec_cmp_type = vectype;
 
   if (slp_node || PURE_SLP_STMT (stmt_info))
     ncopies = 1;
@@ -5382,6 +5383,15 @@  vectorizable_condition (gimple stmt, gim
 	   && TREE_CODE (else_clause) != FIXED_CST)
     return false;
 
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype)))
+    {
+      unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
+      tree cmp_type = build_nonstandard_integer_type (prec, 1);
+      vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
+      if (vec_cmp_type == NULL_TREE)
+	return false;
+    }
+
   if (!vec_stmt)
     {
       STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
@@ -5488,8 +5498,8 @@  vectorizable_condition (gimple stmt, gim
           vec_then_clause = VEC_index (tree, vec_oprnds2, i);
           vec_else_clause = VEC_index (tree, vec_oprnds3, i);
 
-          vec_compare = build2 (TREE_CODE (cond_expr), vectype,
-  			       vec_cond_lhs, vec_cond_rhs);
+	  vec_compare = build2 (TREE_CODE (cond_expr), vec_cmp_type,
+				vec_cond_lhs, vec_cond_rhs);
           vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
  		         vec_compare, vec_then_clause, vec_else_clause);
 
--- gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c.jj	2012-11-12 15:55:58.069579547 +0100
+++ gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c	2012-11-12 15:56:29.550402151 +0100
@@ -0,0 +1,30 @@ 
+/* PR tree-optimization/55281 */
+/* { dg-do compile } */
+
+static inline float
+bar (float k, float j)
+{
+  float l = 0.0f;
+  if (k > j)
+    l = k;
+  float t = k / j;
+  float v = t * t;
+  if (k == 0)
+    v = 0.0f;
+  if (t > 0.4f)
+    v += 0.7;
+  if (l != 0)
+    v = 1.5 - v;
+  return v;
+}
+
+void
+foo (int *a, int b, float *d, float *e, int *f)
+{
+  int i, l;
+  for (l = 0; l != b; ++l)
+    for (i = 0; i != 8; ++i)
+      f[i] = e[i] + bar (a[i], d[i]);
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- gcc/testsuite/g++.dg/opt/pr55281.C.jj	2012-11-12 15:53:50.523289232 +0100
+++ gcc/testsuite/g++.dg/opt/pr55281.C	2012-11-12 15:54:11.529173469 +0100
@@ -0,0 +1,17 @@ 
+// PR tree-optimization/55281
+// { dg-do compile }
+// { dg-options "-Ofast" }
+
+typedef float VF __attribute__((vector_size (16)));
+
+VF x;
+
+void
+foo (void)
+{
+  VF a, b, c;
+  a = (VF) { 1.0, 2.0, 3.0, 4.0 };
+  b = (VF) { 5.0, 6.0, 7.0, 8.0 };
+  c = (VF) { 0.0, 0.0, 0.0, 0.0 };
+  x = c == ((VF) { 0.0, 0.0, 0.0, 0.0 }) ? a : b;
+}