From: Marc Glisse Date: Fri, 3 Oct 2014 19:57:01 +0000 (+0200) Subject: re PR c++/54427 (Expose more vector extensions) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3c9aabbde58e5c540b0718c0a585e3ca97910317;p=gcc.git re PR c++/54427 (Expose more vector extensions) 2014-10-03 Marc Glisse 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bf61ab5212..8c96f5225a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-10-03 Marc Glisse + + PR c++/54427 + PR c++/57198 + PR c++/58845 + * doc/extend.texi (Vector Extensions): Document &&, ||, ! in C++. + 2014-10-03 Jan Hubicka * cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index fef201b799b..8f448878edc 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2014-10-03 Marc Glisse + + 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> Implement SD-6: SG10 Feature Test Recommendations diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index b16d030ae2b..e69d128a2cd 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -1677,6 +1677,10 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, || INTEGRAL_TYPE_P (TREE_TYPE (op_right)))) 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 (with OR) or trivially false (with AND). If so, do not warn. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7a703aae203..c0b6fb5d1f9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2014-10-03 Marc Glisse + + 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 * decl.c (start_decl): Complain about static/thread_local vars diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 61d52bdb833..6a357bfca99 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4045,8 +4045,8 @@ cp_build_binary_op (location_t location, return error_mark_node; case stv_firstarg: { - op0 = save_expr (op0); op0 = convert (TREE_TYPE (type1), op0); + op0 = save_expr (op0); op0 = build_vector_from_val (type1, op0); type0 = TREE_TYPE (op0); code0 = TREE_CODE (type0); @@ -4055,8 +4055,8 @@ cp_build_binary_op (location_t location, } case stv_secondarg: { - op1 = save_expr (op1); op1 = convert (TREE_TYPE (type0), op1); + op1 = save_expr (op1); op1 = build_vector_from_val (type0, op1); type1 = TREE_TYPE (op1); code1 = TREE_CODE (type1); @@ -4191,11 +4191,49 @@ cp_build_binary_op (location_t location, case TRUTH_ORIF_EXPR: case TRUTH_AND_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"); - return error_mark_node; + 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) + { + 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; break; @@ -5685,6 +5723,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, break; 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, complain); val = invert_truthvalue_loc (input_location, arg); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index c78ffb2dabc..de056618226 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 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 @code{__builtin_shuffle (vec, mask)} and @code{__builtin_shuffle (vec0, vec1, mask)}. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2753273bd81..4c4c6049018 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2014-10-03 Marc Glisse + + 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 * gcc.dg/torture/vshuf-v8df.c: New test. diff --git a/gcc/testsuite/g++.dg/ext/vector27.C b/gcc/testsuite/g++.dg/ext/vector27.C index 288e13c558d..2f29577a4f0 100644 --- a/gcc/testsuite/g++.dg/ext/vector27.C +++ b/gcc/testsuite/g++.dg/ext/vector27.C @@ -1,7 +1,13 @@ -// 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))); - v = v || v; // { dg-bogus "" "" { xfail *-*-* } } + *a = (*a < 1 && !(*b > 2)) ? *a + *b : 3; } diff --git a/gcc/testsuite/g++.dg/ext/vector28.C b/gcc/testsuite/g++.dg/ext/vector28.C new file mode 100644 index 00000000000..ea48c961244 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector28.C @@ -0,0 +1,10 @@ +/* { 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; +} diff --git a/gcc/testsuite/g++.dg/ext/vector9.C b/gcc/testsuite/g++.dg/ext/vector9.C index 52b3f171444..42d150dd345 100644 --- a/gcc/testsuite/g++.dg/ext/vector9.C +++ b/gcc/testsuite/g++.dg/ext/vector9.C @@ -6,5 +6,5 @@ typedef int v4i __attribute__((vector_size(8))); void foo() { v4f v; - !(v4i)v; // { dg-error "v4i|argument" } + !(v4i)v; } diff --git a/gcc/testsuite/g++.dg/other/error23.C b/gcc/testsuite/g++.dg/other/error23.C index 959fe4075e6..c60603e8ff5 100644 --- a/gcc/testsuite/g++.dg/other/error23.C +++ b/gcc/testsuite/g++.dg/other/error23.C @@ -2,4 +2,4 @@ // { dg-do compile } 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" }