diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2012-10-09 08:18:29 +0200 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2012-10-09 06:18:29 +0000 |
commit | a212e43fca22f730987ad4d15a0bd58efae9677e (patch) | |
tree | 41770fbb2dff0d56518b79bce3dd01c52d1b2759 /gcc/c-family | |
parent | f5220359f4b2ee333e38994e3c275180ff09035f (diff) | |
download | gcc-a212e43fca22f730987ad4d15a0bd58efae9677e.zip gcc-a212e43fca22f730987ad4d15a0bd58efae9677e.tar.gz gcc-a212e43fca22f730987ad4d15a0bd58efae9677e.tar.bz2 |
re PR c++/54427 (Expose more vector extensions)
2012-10-09 Marc Glisse <marc.glisse@inria.fr>
PR c++/54427
c/
* c-typeck.c: Include c-common.h.
(enum stv_conv): Moved to c-common.h.
(scalar_to_vector): Moved to c-common.c.
(build_binary_op): Adapt to scalar_to_vector's new prototype.
* Make-lang.in: c-typeck.c depends on c-common.h.
c-family/
* c-common.c (scalar_to_vector): Moved from c-typeck.c. Support
more operations. Make error messages optional.
* c-common.h (enum stv_conv): Moved from c-typeck.c.
(scalar_to_vector): Declare.
cp/
* typeck.c (cp_build_binary_op): Handle mixed scalar-vector
operations.
[LSHIFT_EXPR, RSHIFT_EXPR]: Likewise.
gcc/
* fold-const.c (fold_binary_loc): Use build_zero_cst instead of
build_int_cst for a potential vector.
testsuite/
* c-c++-common/vector-scalar.c: New testcase.
* g++.dg/ext/vector18.C: New testcase.
* g++.dg/ext/vector5.C: This is not an error anymore.
* gcc.dg/init-vec-1.c: Move ...
* c-c++-common/init-vec-1.c: ... here. Adapt error message.
* gcc.c-torture/execute/vector-shift1.c: Move ...
* c-c++-common/torture/vector-shift1.c: ... here.
* gcc.dg/scal-to-vec1.c: Move ...
* c-c++-common/scal-to-vec1.c: ... here. Avoid narrowing for
C++11. Adapt error messages.
* gcc.dg/convert-vec-1.c: Move ...
* c-c++-common/convert-vec-1.c: ... here.
* gcc.dg/scal-to-vec2.c: Move ...
* c-c++-common/scal-to-vec2.c: ... here.
From-SVN: r192238
Diffstat (limited to 'gcc/c-family')
-rw-r--r-- | gcc/c-family/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 103 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 11 |
3 files changed, 122 insertions, 0 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 36bab2e..c86eb69 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * c-common.c (scalar_to_vector): Moved from c-typeck.c. Support + more operations. Make error messages optional. + * c-common.h (enum stv_conv): Moved from c-typeck.c. + (scalar_to_vector): Declare. + 2012-10-08 Jason Merrill <jason@redhat.com> * c-common.c (c_common_reswords): Add thread_local. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index bb18c39..edd25aa 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -11253,6 +11253,109 @@ convert_vector_to_pointer_for_subscript (location_t loc, } } +/* Determine which of the operands, if any, is a scalar that needs to be + converted to a vector, for the range of operations. */ +enum stv_conv +scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1, + bool complain) +{ + tree type0 = TREE_TYPE (op0); + tree type1 = TREE_TYPE (op1); + bool integer_only_op = false; + enum stv_conv ret = stv_firstarg; + + gcc_assert (TREE_CODE (type0) == VECTOR_TYPE + || TREE_CODE (type1) == VECTOR_TYPE); + switch (code) + { + /* Most GENERIC binary expressions require homogeneous arguments. + LSHIFT_EXPR and RSHIFT_EXPR are exceptions and accept a first + argument that is a vector and a second one that is a scalar, so + we never return stv_secondarg for them. */ + case RSHIFT_EXPR: + case LSHIFT_EXPR: + if (TREE_CODE (type0) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) + { + if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) + { + if (complain) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", type0, type1); + return stv_error; + } + else + return stv_firstarg; + } + break; + + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + case BIT_AND_EXPR: + integer_only_op = true; + /* ... fall through ... */ + + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case EXACT_DIV_EXPR: + case TRUNC_MOD_EXPR: + case FLOOR_MOD_EXPR: + case RDIV_EXPR: + case EQ_EXPR: + case NE_EXPR: + case LE_EXPR: + case GE_EXPR: + case LT_EXPR: + case GT_EXPR: + /* What about UNLT_EXPR? */ + if (TREE_CODE (type0) == VECTOR_TYPE) + { + tree tmp; + ret = stv_secondarg; + /* Swap TYPE0 with TYPE1 and OP0 with OP1 */ + tmp = type0; type0 = type1; type1 = tmp; + tmp = op0; op0 = op1; op1 = tmp; + } + + if (TREE_CODE (type0) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) + { + if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) + { + if (complain) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", type0, type1); + return stv_error; + } + return ret; + } + else if (!integer_only_op + /* Allow integer --> real conversion if safe. */ + && (TREE_CODE (type0) == REAL_TYPE + || TREE_CODE (type0) == INTEGER_TYPE) + && SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1))) + { + if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) + { + if (complain) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", type0, type1); + return stv_error; + } + return ret; + } + default: + break; + } + + return stv_nothing; +} + /* Return true iff ALIGN is an integral constant that is a fundamental alignment, as defined by [basic.align] in the c++-11 specifications. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 5b23bd3..481c3ed 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1123,4 +1123,15 @@ extern tree build_userdef_literal (tree suffix_id, tree value, tree num_string); extern void convert_vector_to_pointer_for_subscript (location_t, tree*, tree); +/* Possibe cases of scalar_to_vector conversion. */ +enum stv_conv { + stv_error, /* Error occured. */ + stv_nothing, /* Nothing happened. */ + stv_firstarg, /* First argument must be expanded. */ + stv_secondarg /* Second argument must be expanded. */ +}; + +extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code, + tree op0, tree op1, bool); + #endif /* ! GCC_C_COMMON_H */ |