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
This commit is contained in:
Marc Glisse 2012-10-09 08:18:29 +02:00 committed by Marc Glisse
parent f5220359f4
commit a212e43fca
19 changed files with 252 additions and 107 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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))

View File

@ -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));
}
}

View File

@ -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

View File

@ -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" } */

View File

@ -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;
}

View File

@ -1,3 +1,4 @@
/* { dg-do run } */
#define vector __attribute__((vector_size(8*sizeof(short))))
int main (int argc, char *argv[]) {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -4,5 +4,5 @@
void foo()
{
int __attribute__((vector_size(8))) v;
v = 1/v; // { dg-error "invalid operands of types" }
v = 1/v;
}