diff options
Diffstat (limited to 'gcc')
19 files changed, 252 insertions, 107 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3879f38..661af2a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * fold-const.c (fold_binary_loc): Use build_zero_cst instead of + build_int_cst for a potential vector. + 2012-10-08 Uros Bizjak <ubizjak@gmail.com> * config/i386/atom.md (atom_sse_4): Merge atom_sse_attr attibutes. 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 */ diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 257b752..93c72f0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * 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. + 2012-10-04 Arnaud Charlet <charlet@adacore.com> * c-decl.c (c_write_global_declarations): Fix handling of diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in index a39c91c..93b8f64 100644 --- a/gcc/c/Make-lang.in +++ b/gcc/c/Make-lang.in @@ -192,5 +192,5 @@ c/c-parser.o : c/c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ c/c-typeck.o : c/c-typeck.c c/c-lang.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(C_TREE_H) $(TARGET_H) $(FLAGS_H) intl.h \ langhooks.h tree-iterator.h $(BITMAP_H) $(GIMPLE_H) \ - c-family/c-objc.h + c-family/c-objc.h c-family/c-common.h diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 5b4ad28..ae6b348 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "bitmap.h" #include "gimple.h" #include "c-family/c-objc.h" +#include "c-family/c-common.h" /* Possible cases of implicit bad conversions. Used to select diagnostic messages in convert_for_assignment. */ @@ -50,14 +51,6 @@ enum impl_conv { ic_return }; -/* 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. */ -}; - /* The level of nesting inside "__alignof__". */ int in_alignof; @@ -9375,88 +9368,6 @@ push_cleanup (tree decl, tree cleanup, bool eh_only) TREE_OPERAND (stmt, 0) = list; STATEMENT_LIST_STMT_EXPR (list) = stmt_expr; } - -/* Convert scalar to vector for the range of operations. */ -static enum stv_conv -scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1) -{ - 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) - { - 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)) - { - error_at (loc, "conversion of scalar to vector " - "involves truncation"); - 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 TRUNC_MOD_EXPR: - case RDIV_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)) - { - error_at (loc, "conversion of scalar to vector " - "involves truncation"); - 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)) - { - error_at (loc, "conversion of scalar to vector " - "involves truncation"); - return stv_error; - } - return ret; - } - default: - break; - } - - return stv_nothing; -} /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. @@ -9647,7 +9558,8 @@ build_binary_op (location_t location, enum tree_code code, a vector and another is a scalar -- convert scalar to vector. */ if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE)) { - enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1); + enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1, + true); switch (convert_flag) { diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f4e7e6a..4c1d01ab 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * typeck.c (cp_build_binary_op): Handle mixed scalar-vector + operations. + [LSHIFT_EXPR, RSHIFT_EXPR]: Likewise. + 2012-10-08 Jakub Jelinek <jakub@redhat.com> PR c++/54858 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ae4d0a4..94e17c5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3912,6 +3912,40 @@ cp_build_binary_op (location_t location, warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic"); } + /* In case when one of the operands of the binary operation is + a vector and another is a scalar -- convert scalar to vector. */ + if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE)) + { + enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1, + complain & tf_error); + + switch (convert_flag) + { + case stv_error: + return error_mark_node; + case stv_firstarg: + { + op0 = convert (TREE_TYPE (type1), op0); + op0 = build_vector_from_val (type1, op0); + type0 = TREE_TYPE (op0); + code0 = TREE_CODE (type0); + converted = 1; + break; + } + case stv_secondarg: + { + op1 = convert (TREE_TYPE (type0), op1); + op1 = build_vector_from_val (type0, op1); + type1 = TREE_TYPE (op1); + code1 = TREE_CODE (type1); + converted = 1; + break; + } + default: + break; + } + } + switch (code) { case MINUS_EXPR: @@ -4035,7 +4069,13 @@ cp_build_binary_op (location_t location, Also set SHORT_SHIFT if shifting rightward. */ case RSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) + { + result_type = type0; + converted = 1; + } + else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) @@ -4072,7 +4112,13 @@ cp_build_binary_op (location_t location, break; case LSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) + { + result_type = type0; + converted = 1; + } + else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index fd0075c..9dabfab 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -12857,7 +12857,7 @@ fold_binary_loc (location_t loc, arg00 = fold_convert_loc (loc, itype, arg00); } return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR, - type, arg00, build_int_cst (itype, 0)); + type, arg00, build_zero_cst (itype)); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08e0a69..dc99653 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2012-10-09 Marc Glisse <marc.glisse@inria.fr> + + PR c++/54427 + * 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. + 2012-10-08 Marc Glisse <marc.glisse@inria.fr> PR target/54400 diff --git a/gcc/testsuite/gcc.dg/convert-vec-1.c b/gcc/testsuite/c-c++-common/convert-vec-1.c index 4987298..4987298 100644 --- a/gcc/testsuite/gcc.dg/convert-vec-1.c +++ b/gcc/testsuite/c-c++-common/convert-vec-1.c diff --git a/gcc/testsuite/gcc.dg/init-vec-1.c b/gcc/testsuite/c-c++-common/init-vec-1.c index 9921b16..68243cd 100644 --- a/gcc/testsuite/gcc.dg/init-vec-1.c +++ b/gcc/testsuite/c-c++-common/init-vec-1.c @@ -1,4 +1,4 @@ /* Don't ICE or emit spurious errors when init a vector with a scalar. */ /* { dg-do compile } */ typedef float v2sf __attribute__ ((vector_size (8))); -v2sf a = 0.0; /* { dg-error "incompatible types" } */ +v2sf a = 0.0; /* { dg-error "incompatible types|cannot convert" } */ diff --git a/gcc/testsuite/gcc.dg/scal-to-vec1.c b/gcc/testsuite/c-c++-common/scal-to-vec1.c index 0c1a509..beb450d 100644 --- a/gcc/testsuite/gcc.dg/scal-to-vec1.c +++ b/gcc/testsuite/c-c++-common/scal-to-vec1.c @@ -13,7 +13,7 @@ extern int sint; extern long long sll; int main (int argc, char *argv[]) { - vector(8, short) v0 = {argc, 1,2,3,4,5,6,7}; + vector(8, short) v0 = {(short)argc, 1,2,3,4,5,6,7}; vector(8, short) v1; vector(4, float) f0 = {1., 2., 3., 4.}; @@ -26,18 +26,18 @@ int main (int argc, char *argv[]) { int i = 12; double d = 3.; - v1 = i + v0; /* { dg-error "conversion of scalar to vector" } */ - v1 = 99999 + v0; /* { dg-error "conversion of scalar to vector" } */ + v1 = i + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + v1 = 99999 + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ - f1 = d + f0; /* { dg-error "conversion of scalar to vector" } */ - f1 = 1.3 + f0; /* { dg-error "conversion of scalar to vector" } */ - f1 = sll + f0; /* { dg-error "conversion of scalar to vector" } */ - f1 = ((int)998769576) + f0; /* { dg-error "conversion of scalar to vector" } */ + f1 = d + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + f1 = 1.3 + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + f1 = sll + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ + f1 = ((int)998769576) + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */ /* convert.c should take care of this. */ - i1 = sfl + i0; /* { dg-error "can't convert value to a vector" } */ - i1 = 1.5 + i0; /* { dg-error "can't convert value to a vector" } */ - v1 = d + v0; /* { dg-error "can't convert value to a vector" } */ + i1 = sfl + i0; /* { dg-error "can't convert value to a vector|invalid operands" } */ + i1 = 1.5 + i0; /* { dg-error "can't convert value to a vector|invalid operands" } */ + v1 = d + v0; /* { dg-error "can't convert value to a vector|invalid operands" } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/scal-to-vec2.c b/gcc/testsuite/c-c++-common/scal-to-vec2.c index 1897b93..1897b93 100644 --- a/gcc/testsuite/gcc.dg/scal-to-vec2.c +++ b/gcc/testsuite/c-c++-common/scal-to-vec2.c diff --git a/gcc/testsuite/gcc.c-torture/execute/vector-shift1.c b/gcc/testsuite/c-c++-common/torture/vector-shift1.c index 6041fc3..e6e31da 100644 --- a/gcc/testsuite/gcc.c-torture/execute/vector-shift1.c +++ b/gcc/testsuite/c-c++-common/torture/vector-shift1.c @@ -1,3 +1,4 @@ +/* { dg-do run } */ #define vector __attribute__((vector_size(8*sizeof(short)))) int main (int argc, char *argv[]) { diff --git a/gcc/testsuite/c-c++-common/vector-scalar.c b/gcc/testsuite/c-c++-common/vector-scalar.c new file mode 100644 index 0000000..1b32cc6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/vector-scalar.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ + +typedef float vecf __attribute__ ((vector_size (4 * sizeof (float)))); +typedef short veci __attribute__ ((vector_size (8 * sizeof (short)))); + +void f (vecf *d, veci *i) +{ + (void) ((*d *= 2) < 0); + (void) ((((*i - 1) >> 2) != 0) | *i); +} diff --git a/gcc/testsuite/g++.dg/ext/vector18.C b/gcc/testsuite/g++.dg/ext/vector18.C new file mode 100644 index 0000000..dfffad5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector18.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c++11" } */ + +typedef signed char __attribute__((vector_size(128) )) vec; + +template <class A, class B> +auto f (A *a, B b) -> decltype (*a + b); + +void f (...) {} + +void g (vec *v, long long l) +{ + f (v, l); +} diff --git a/gcc/testsuite/g++.dg/ext/vector5.C b/gcc/testsuite/g++.dg/ext/vector5.C index e5304bc..68f711f 100644 --- a/gcc/testsuite/g++.dg/ext/vector5.C +++ b/gcc/testsuite/g++.dg/ext/vector5.C @@ -4,5 +4,5 @@ void foo() { int __attribute__((vector_size(8))) v; - v = 1/v; // { dg-error "invalid operands of types" } + v = 1/v; } |