Commit 3c9aabbd by Marc Glisse Committed by Marc Glisse

re PR c++/54427 (Expose more vector extensions)

2014-10-03  Marc Glisse  <marc.glisse@inria.fr>

	PR c++/54427
	PR c++/57198
	PR c++/58845
gcc/c-family/
	* c-common.c (warn_logical_operator): Punt for vectors.
gcc/cp/
	* typeck.c (cp_build_binary_op): save_expr after convert to save
	redundant operations.
	[TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR]: Handle vectors.
	(cp_build_unary_op) [TRUTH_NOT_EXPR]: Likewise.
gcc/
	* doc/extend.texi (Vector Extensions): Document &&, ||, ! in C++.
gcc/testsuite/
	* g++.dg/ext/vector9.C: Update, not an error anymore.
	* g++.dg/ext/vector27.C: Replace with new test.
	* g++.dg/ext/vector28.C: New file.
	* g++.dg/other/error23.C: Update to a different error.

From-SVN: r215872
parent f9bb202b
2014-10-03 Marc Glisse <marc.glisse@inria.fr>
PR c++/54427
PR c++/57198
PR c++/58845
* doc/extend.texi (Vector Extensions): Document &&, ||, ! in C++.
2014-10-03 Jan Hubicka <hubicka@ucw.cz> 2014-10-03 Jan Hubicka <hubicka@ucw.cz>
* cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR * cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
2014-10-03 Marc Glisse <marc.glisse@inria.fr>
PR c++/54427
PR c++/57198
PR c++/58845
* c-common.c (warn_logical_operator): Punt for vectors.
2014-10-01 Edward Smith-Rowland <3dw4rd@verizon.net> 2014-10-01 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement SD-6: SG10 Feature Test Recommendations Implement SD-6: SG10 Feature Test Recommendations
......
...@@ -1677,6 +1677,10 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, ...@@ -1677,6 +1677,10 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
|| INTEGRAL_TYPE_P (TREE_TYPE (op_right)))) || INTEGRAL_TYPE_P (TREE_TYPE (op_right))))
return; return;
/* The range computations only work with scalars. */
if (VECTOR_TYPE_P (TREE_TYPE (op_left))
|| VECTOR_TYPE_P (TREE_TYPE (op_right)))
return;
/* We first test whether either side separately is trivially true /* We first test whether either side separately is trivially true
(with OR) or trivially false (with AND). If so, do not warn. (with OR) or trivially false (with AND). If so, do not warn.
......
2014-10-03 Marc Glisse <marc.glisse@inria.fr>
PR c++/54427
PR c++/57198
PR c++/58845
* typeck.c (cp_build_binary_op): save_expr after convert to save
redundant operations.
[TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR]: Handle vectors.
(cp_build_unary_op) [TRUTH_NOT_EXPR]: Likewise.
2014-10-03 Jason Merrill <jason@redhat.com> 2014-10-03 Jason Merrill <jason@redhat.com>
* decl.c (start_decl): Complain about static/thread_local vars * decl.c (start_decl): Complain about static/thread_local vars
......
...@@ -4045,8 +4045,8 @@ cp_build_binary_op (location_t location, ...@@ -4045,8 +4045,8 @@ cp_build_binary_op (location_t location,
return error_mark_node; return error_mark_node;
case stv_firstarg: case stv_firstarg:
{ {
op0 = save_expr (op0);
op0 = convert (TREE_TYPE (type1), op0); op0 = convert (TREE_TYPE (type1), op0);
op0 = save_expr (op0);
op0 = build_vector_from_val (type1, op0); op0 = build_vector_from_val (type1, op0);
type0 = TREE_TYPE (op0); type0 = TREE_TYPE (op0);
code0 = TREE_CODE (type0); code0 = TREE_CODE (type0);
...@@ -4055,8 +4055,8 @@ cp_build_binary_op (location_t location, ...@@ -4055,8 +4055,8 @@ cp_build_binary_op (location_t location,
} }
case stv_secondarg: case stv_secondarg:
{ {
op1 = save_expr (op1);
op1 = convert (TREE_TYPE (type0), op1); op1 = convert (TREE_TYPE (type0), op1);
op1 = save_expr (op1);
op1 = build_vector_from_val (type0, op1); op1 = build_vector_from_val (type0, op1);
type1 = TREE_TYPE (op1); type1 = TREE_TYPE (op1);
code1 = TREE_CODE (type1); code1 = TREE_CODE (type1);
...@@ -4191,11 +4191,49 @@ cp_build_binary_op (location_t location, ...@@ -4191,11 +4191,49 @@ cp_build_binary_op (location_t location,
case TRUTH_ORIF_EXPR: case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR: case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR: case TRUTH_OR_EXPR:
if (VECTOR_TYPE_P (type0) || VECTOR_TYPE_P (type1)) if (!VECTOR_TYPE_P (type0) && VECTOR_TYPE_P (type1))
{ {
sorry ("logical operation on vector type"); if (!COMPARISON_CLASS_P (op1))
return error_mark_node; op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
build_zero_cst (type1), complain);
if (code == TRUTH_ANDIF_EXPR)
{
tree z = build_zero_cst (TREE_TYPE (op1));
return build_conditional_expr (location, op0, op1, z, complain);
}
else if (code == TRUTH_ORIF_EXPR)
{
tree m1 = build_all_ones_cst (TREE_TYPE (op1));
return build_conditional_expr (location, op0, m1, op1, complain);
}
else
gcc_unreachable ();
} }
if (VECTOR_TYPE_P (type0))
{
if (!COMPARISON_CLASS_P (op0))
op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
build_zero_cst (type0), complain);
if (!VECTOR_TYPE_P (type1))
{
tree m1 = build_all_ones_cst (TREE_TYPE (op0));
tree z = build_zero_cst (TREE_TYPE (op0));
op1 = build_conditional_expr (location, op1, z, m1, complain);
}
else if (!COMPARISON_CLASS_P (op1))
op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
build_zero_cst (type1), complain);
if (code == TRUTH_ANDIF_EXPR)
code = BIT_AND_EXPR;
else if (code == TRUTH_ORIF_EXPR)
code = BIT_IOR_EXPR;
else
gcc_unreachable ();
return cp_build_binary_op (location, code, op0, op1, complain);
}
result_type = boolean_type_node; result_type = boolean_type_node;
break; break;
...@@ -5685,6 +5723,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, ...@@ -5685,6 +5723,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
break; break;
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg)))
return cp_build_binary_op (input_location, EQ_EXPR, arg,
build_zero_cst (TREE_TYPE (arg)), complain);
arg = perform_implicit_conversion (boolean_type_node, arg, arg = perform_implicit_conversion (boolean_type_node, arg,
complain); complain);
val = invert_truthvalue_loc (input_location, arg); val = invert_truthvalue_loc (input_location, arg);
......
...@@ -7918,6 +7918,13 @@ vector. If both @code{b} and @code{c} are scalars and the type of ...@@ -7918,6 +7918,13 @@ vector. If both @code{b} and @code{c} are scalars and the type of
@code{b} and @code{c} are converted to a vector type whose elements have @code{b} and @code{c} are converted to a vector type whose elements have
this type and with the same number of elements as @code{a}. this type and with the same number of elements as @code{a}.
In C++, the logic operators @code{!, &&, ||} are available for vectors.
@code{!v} is equivalent to @code{v == 0}, @code{a && b} is equivalent to
@code{a!=0 & b!=0} and @code{a || b} is equivalent to @code{a!=0 | b!=0}.
For mixed operations between a scalar @code{s} and a vector @code{v},
@code{s && v} is equivalent to @code{s?v!=0:0} (the evaluation is
short-circuit) and @code{v && s} is equivalent to @code{v!=0 & (s?-1:0)}.
Vector shuffling is available using functions Vector shuffling is available using functions
@code{__builtin_shuffle (vec, mask)} and @code{__builtin_shuffle (vec, mask)} and
@code{__builtin_shuffle (vec0, vec1, mask)}. @code{__builtin_shuffle (vec0, vec1, mask)}.
......
2014-10-03 Marc Glisse <marc.glisse@inria.fr>
PR c++/54427
PR c++/57198
PR c++/58845
* g++.dg/ext/vector9.C: Update, not an error anymore.
* g++.dg/ext/vector27.C: Replace with new test.
* g++.dg/ext/vector28.C: New file.
* g++.dg/other/error23.C: Update to a different error.
2014-10-03 Jakub Jelinek <jakub@redhat.com> 2014-10-03 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/torture/vshuf-v8df.c: New test. * gcc.dg/torture/vshuf-v8df.c: New test.
......
// PR c++/58845 /* { dg-do compile } */
void foo() typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
typedef float vecf __attribute__ ((vector_size (4 * sizeof (float))));
void f (veci *a, veci *b, int c)
{
*a = !*a || *b < ++c;
}
void g (vecf *a, vecf *b)
{ {
int v __attribute__((vector_size(8))); *a = (*a < 1 && !(*b > 2)) ? *a + *b : 3;
v = v || v; // { dg-bogus "" "" { xfail *-*-* } }
} }
/* { dg-do compile } */
typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
typedef float vecf __attribute__ ((vector_size (4 * sizeof (float))));
void f (veci *a, vecf *b, int c)
{
*a = c || *b;
*a = *a || c;
}
...@@ -6,5 +6,5 @@ typedef int v4i __attribute__((vector_size(8))); ...@@ -6,5 +6,5 @@ typedef int v4i __attribute__((vector_size(8)));
void foo() void foo()
{ {
v4f v; v4f v;
!(v4i)v; // { dg-error "v4i|argument" } !(v4i)v;
} }
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
// { dg-do compile } // { dg-do compile }
int v __attribute ((vector_size (8))); int v __attribute ((vector_size (8)));
bool b = !(v - v); // { dg-error "could not convert .\\(__vector.2. int\\)\\{0, 0\\}. from .__vector.2. int. to .bool.|in argument to unary" } bool b = !(v - v); // { dg-error "not convert .__vector.2. int. to .bool. in initialization" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment