diff mbox

[Boolean,Vector,3/5] Use boolean vector in C/C++ FE

Message ID 20151002140449.GG26618@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich Oct. 2, 2015, 2:04 p.m. UTC
Hi,

This patch makes C/C++ FE to use boolean vector as a resulting type for vector comparison.  As a result vector comparison in source code now parsed into VEC_COND_EXPR, it required a testcase fix-up.

Thanks,
Ilya
--
gcc/c

2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* c-typeck.c (build_conditional_expr): Use boolean vector
	type for vector comparison.
	(build_vec_cmp): New.
	(build_binary_op): Use build_vec_cmp for comparison.

gcc/cp

2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* call.c (build_conditional_expr_1): Use boolean vector
	type for vector comparison.
	* typeck.c (build_vec_cmp): New.
	(cp_build_binary_op): Use build_vec_cmp for comparison.

gcc/testsuite/

2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* g++.dg/ext/vector22.C: Allow VEC_COND_EXPR.

Comments

Jeff Law Oct. 9, 2015, 8:51 p.m. UTC | #1
On 10/02/2015 08:04 AM, Ilya Enkovich wrote:
> Hi,
>
> This patch makes C/C++ FE to use boolean vector as a resulting type for vector comparison.  As a result vector comparison in source code now parsed into VEC_COND_EXPR, it required a testcase fix-up.
>
> Thanks,
> Ilya
> --
> gcc/c
>
> 2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>
>
> 	* c-typeck.c (build_conditional_expr): Use boolean vector
> 	type for vector comparison.
> 	(build_vec_cmp): New.
> 	(build_binary_op): Use build_vec_cmp for comparison.
>
> gcc/cp
>
> 2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>
>
> 	* call.c (build_conditional_expr_1): Use boolean vector
> 	type for vector comparison.
> 	* typeck.c (build_vec_cmp): New.
> 	(cp_build_binary_op): Use build_vec_cmp for comparison.
>
> gcc/testsuite/
>
> 2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>
>
> 	* g++.dg/ext/vector22.C: Allow VEC_COND_EXPR.
>
>
> diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> index 3b26231..3f64d76 100644
> --- a/gcc/c/c-typeck.c
> +++ b/gcc/c/c-typeck.c
> @@ -10220,6 +10232,19 @@ push_cleanup (tree decl, tree cleanup, bool eh_only)
>     STATEMENT_LIST_STMT_EXPR (list) = stmt_expr;
>   }
>   
> +/* Build a vector comparison using VEC_COND_EXPR.  */
Please make sure your function comments include descriptions of all the 
arguments and return values.


> +
> +static tree
> +build_vec_cmp (tree_code code, tree type,
> +	       tree arg0, tree arg1)
> +{
> +  tree zero_vec = build_zero_cst (type);
> +  tree minus_one_vec = build_minus_one_cst (type);
> +  tree cmp_type = build_same_sized_truth_vector_type (type);
> +  tree cmp = build2 (code, cmp_type, arg0, arg1);
> +  return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
> +}
Isn't this implementation the same for C & C++?  Does it make sense to 
put it in c-family/c-common.c?


> +
>   /* Build a binary-operation expression without default conversions.
>      CODE is the kind of expression to build.
>      LOCATION is the operator's location.
> @@ -10786,7 +10811,8 @@ build_binary_op (location_t location, enum tree_code code,
>             result_type = build_opaque_vector_type (intt,
>   						  TYPE_VECTOR_SUBPARTS (type0));
>             converted = 1;
> -          break;
> +	  ret = build_vec_cmp (resultcode, result_type, op0, op1);
> +          goto return_build_binary_op;
I suspect there's some kind of whitespace/tab problem.  Those two lines 
should be indented the same, right?


>           }
>         if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1))
>   	warning_at (location,
> @@ -10938,7 +10964,8 @@ build_binary_op (location_t location, enum tree_code code,
>             result_type = build_opaque_vector_type (intt,
>   						  TYPE_VECTOR_SUBPARTS (type0));
>             converted = 1;
> -          break;
> +	  ret = build_vec_cmp (resultcode, result_type, op0, op1);
> +          goto return_build_binary_op;
Similarly here.

With the items above fixed, this is OK.

However, more generally, do we need to do anything for the other languages?

Jeff
diff mbox

Patch

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 3b26231..3f64d76 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -4771,6 +4771,18 @@  build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
 		       && TREE_CODE (orig_op2) == INTEGER_CST
 		       && !TREE_OVERFLOW (orig_op2)));
     }
+
+  /* Need to convert condition operand into a vector mask.  */
+  if (VECTOR_TYPE_P (TREE_TYPE (ifexp)))
+    {
+      tree vectype = TREE_TYPE (ifexp);
+      tree elem_type = TREE_TYPE (vectype);
+      tree zero = build_int_cst (elem_type, 0);
+      tree zero_vec = build_vector_from_val (vectype, zero);
+      tree cmp_type = build_same_sized_truth_vector_type (vectype);
+      ifexp = build2 (NE_EXPR, cmp_type, ifexp, zero_vec);
+    }
+
   if (int_const || (ifexp_bcp && TREE_CODE (ifexp) == INTEGER_CST))
     ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2);
   else
@@ -10220,6 +10232,19 @@  push_cleanup (tree decl, tree cleanup, bool eh_only)
   STATEMENT_LIST_STMT_EXPR (list) = stmt_expr;
 }
 
+/* Build a vector comparison using VEC_COND_EXPR.  */
+
+static tree
+build_vec_cmp (tree_code code, tree type,
+	       tree arg0, tree arg1)
+{
+  tree zero_vec = build_zero_cst (type);
+  tree minus_one_vec = build_minus_one_cst (type);
+  tree cmp_type = build_same_sized_truth_vector_type (type);
+  tree cmp = build2 (code, cmp_type, arg0, arg1);
+  return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
+}
+
 /* Build a binary-operation expression without default conversions.
    CODE is the kind of expression to build.
    LOCATION is the operator's location.
@@ -10786,7 +10811,8 @@  build_binary_op (location_t location, enum tree_code code,
           result_type = build_opaque_vector_type (intt,
 						  TYPE_VECTOR_SUBPARTS (type0));
           converted = 1;
-          break;
+	  ret = build_vec_cmp (resultcode, result_type, op0, op1);
+          goto return_build_binary_op;
         }
       if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1))
 	warning_at (location,
@@ -10938,7 +10964,8 @@  build_binary_op (location_t location, enum tree_code code,
           result_type = build_opaque_vector_type (intt,
 						  TYPE_VECTOR_SUBPARTS (type0));
           converted = 1;
-          break;
+	  ret = build_vec_cmp (resultcode, result_type, op0, op1);
+          goto return_build_binary_op;
         }
       build_type = integer_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 367d42b..0488b82 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4615,6 +4615,15 @@  build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
 
   if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1)))
     {
+      /* If arg1 is another cond_expr choosing between -1 and 0,
+	 then we can use its comparison.  It may help to avoid
+	 additional comparison, produce more accurate diagnostics
+	 and enables folding.  */
+      if (TREE_CODE (arg1) == VEC_COND_EXPR
+	  && integer_minus_onep (TREE_OPERAND (arg1, 1))
+	  && integer_zerop (TREE_OPERAND (arg1, 2)))
+	arg1 = TREE_OPERAND (arg1, 0);
+
       arg1 = force_rvalue (arg1, complain);
       arg2 = force_rvalue (arg2, complain);
       arg3 = force_rvalue (arg3, complain);
@@ -4727,8 +4736,10 @@  build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
 	}
 
       if (!COMPARISON_CLASS_P (arg1))
-	arg1 = cp_build_binary_op (loc, NE_EXPR, arg1,
-				   build_zero_cst (arg1_type), complain);
+	{
+	  tree cmp_type = build_same_sized_truth_vector_type (arg1_type);
+	  arg1 = build2 (NE_EXPR, cmp_type, arg1, build_zero_cst (arg1_type));
+	}
       return fold_build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
     }
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 482e42c..96b1683 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3900,6 +3900,19 @@  build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
   return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
 }
 
+/* Build a vector comparison using VEC_COND_EXPR.  */
+
+static tree
+build_vec_cmp (tree_code code, tree type,
+	       tree arg0, tree arg1)
+{
+  tree zero_vec = build_zero_cst (type);
+  tree minus_one_vec = build_minus_one_cst (type);
+  tree cmp_type = build_same_sized_truth_vector_type(type);
+  tree cmp = build2 (code, cmp_type, arg0, arg1);
+  cmp = fold_if_not_in_template (cmp);
+  return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
+}
 
 /* Build a binary-operation expression without default conversions.
    CODE is the kind of expression to build.
@@ -4769,7 +4782,7 @@  cp_build_binary_op (location_t location,
 	  result_type = build_opaque_vector_type (intt,
 						  TYPE_VECTOR_SUBPARTS (type0));
 	  converted = 1;
-	  break;
+	  return build_vec_cmp (resultcode, result_type, op0, op1);
 	}
       build_type = boolean_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
diff --git a/gcc/testsuite/g++.dg/ext/vector22.C b/gcc/testsuite/g++.dg/ext/vector22.C
index daf4e19..5d28637 100644
--- a/gcc/testsuite/g++.dg/ext/vector22.C
+++ b/gcc/testsuite/g++.dg/ext/vector22.C
@@ -18,4 +18,3 @@  void h(vec*a){
 }
 
 /* { dg-final { scan-tree-dump-not "~" "gimple" } } */
-/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "gimple" } } */