re PR c++/54427 (Expose more vector extensions)
2012-10-25 Marc Glisse <marc.glisse@inria.fr> PR c++/54427 gcc/ * tree.c (signed_or_unsigned_type_for): Handle vectors. gcc/cp/ * typeck.c (build_x_conditional_expr): Handle VEC_COND_EXPR. * call.c (build_conditional_expr_1): Likewise. gcc/c-family/ * c-common.c (scalar_to_vector): Handle VEC_COND_EXPR. gcc/testsuite/ * g++.dg/ext/vector19.C: New testcase. From-SVN: r192808
This commit is contained in:
parent
6ced940d17
commit
93100c6b5b
@ -1,3 +1,8 @@
|
||||
2012-10-25 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
* tree.c (signed_or_unsigned_type_for): Handle vectors.
|
||||
|
||||
2012-10-25 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* ipa-inline.c (recursive_inlining): Redirect to master
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-10-25 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
* c-common.c (scalar_to_vector): Handle VEC_COND_EXPR.
|
||||
|
||||
2012-10-23 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* c-common.h (pch_cpp_save_state): Declare.
|
||||
|
@ -11474,6 +11474,8 @@ scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1,
|
||||
integer_only_op = true;
|
||||
/* ... fall through ... */
|
||||
|
||||
case VEC_COND_EXPR:
|
||||
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
|
@ -1,3 +1,9 @@
|
||||
2012-10-25 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
* typeck.c (build_x_conditional_expr): Handle VEC_COND_EXPR.
|
||||
* call.c (build_conditional_expr_1): Likewise.
|
||||
|
||||
2012-10-25 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/34892
|
||||
|
@ -4373,18 +4373,90 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
|
||||
arg2 = arg1 = save_expr (arg1);
|
||||
}
|
||||
|
||||
/* If something has already gone wrong, just pass that fact up the
|
||||
tree. */
|
||||
if (error_operand_p (arg1)
|
||||
|| error_operand_p (arg2)
|
||||
|| error_operand_p (arg3))
|
||||
return error_mark_node;
|
||||
|
||||
orig_arg2 = arg2;
|
||||
orig_arg3 = arg3;
|
||||
|
||||
if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1)))
|
||||
{
|
||||
arg1 = force_rvalue (arg1, complain);
|
||||
arg2 = force_rvalue (arg2, complain);
|
||||
arg3 = force_rvalue (arg3, complain);
|
||||
|
||||
tree arg1_type = TREE_TYPE (arg1);
|
||||
arg2_type = TREE_TYPE (arg2);
|
||||
arg3_type = TREE_TYPE (arg3);
|
||||
|
||||
if (TREE_CODE (arg2_type) != VECTOR_TYPE
|
||||
&& TREE_CODE (arg3_type) != VECTOR_TYPE)
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("at least one operand of a vector conditional operator "
|
||||
"must be a vector");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if ((TREE_CODE (arg2_type) == VECTOR_TYPE)
|
||||
!= (TREE_CODE (arg3_type) == VECTOR_TYPE))
|
||||
{
|
||||
enum stv_conv convert_flag =
|
||||
scalar_to_vector (input_location, VEC_COND_EXPR, arg2, arg3,
|
||||
complain & tf_error);
|
||||
|
||||
switch (convert_flag)
|
||||
{
|
||||
case stv_error:
|
||||
return error_mark_node;
|
||||
case stv_firstarg:
|
||||
{
|
||||
arg2 = convert (TREE_TYPE (arg3_type), arg2);
|
||||
arg2 = build_vector_from_val (arg3_type, arg2);
|
||||
arg2_type = TREE_TYPE (arg2);
|
||||
break;
|
||||
}
|
||||
case stv_secondarg:
|
||||
{
|
||||
arg3 = convert (TREE_TYPE (arg2_type), arg3);
|
||||
arg3 = build_vector_from_val (arg2_type, arg3);
|
||||
arg3_type = TREE_TYPE (arg3);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!same_type_p (arg2_type, arg3_type)
|
||||
|| TYPE_VECTOR_SUBPARTS (arg1_type)
|
||||
!= TYPE_VECTOR_SUBPARTS (arg2_type)
|
||||
|| TYPE_SIZE (arg1_type) != TYPE_SIZE (arg2_type))
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("incompatible vector types in conditional expression: "
|
||||
"%qT, %qT and %qT", TREE_TYPE (arg1), TREE_TYPE (orig_arg2),
|
||||
TREE_TYPE (orig_arg3));
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (!COMPARISON_CLASS_P (arg1))
|
||||
arg1 = build2 (NE_EXPR, signed_type_for (arg1_type), arg1,
|
||||
build_zero_cst (arg1_type));
|
||||
return build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
/* [expr.cond]
|
||||
|
||||
The first expression is implicitly converted to bool (clause
|
||||
_conv_). */
|
||||
arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
|
||||
LOOKUP_NORMAL);
|
||||
|
||||
/* If something has already gone wrong, just pass that fact up the
|
||||
tree. */
|
||||
if (error_operand_p (arg1)
|
||||
|| error_operand_p (arg2)
|
||||
|| error_operand_p (arg3))
|
||||
if (error_operand_p (arg1))
|
||||
return error_mark_node;
|
||||
|
||||
/* [expr.cond]
|
||||
@ -4394,8 +4466,6 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
|
||||
array-to-pointer (_conv.array_), and function-to-pointer
|
||||
(_conv.func_) standard conversions are performed on the second
|
||||
and third operands. */
|
||||
orig_arg2 = arg2;
|
||||
orig_arg3 = arg3;
|
||||
arg2_type = unlowered_expr_type (arg2);
|
||||
arg3_type = unlowered_expr_type (arg3);
|
||||
if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
|
||||
|
@ -5810,7 +5810,8 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
|
||||
}
|
||||
|
||||
expr = build_conditional_expr (ifexp, op1, op2, complain);
|
||||
if (processing_template_decl && expr != error_mark_node)
|
||||
if (processing_template_decl && expr != error_mark_node
|
||||
&& TREE_CODE (expr) != VEC_COND_EXPR)
|
||||
{
|
||||
tree min = build_min_non_dep (COND_EXPR, expr,
|
||||
orig_ifexp, orig_op1, orig_op2);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-10-25 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
* g++.dg/ext/vector19.C: New testcase.
|
||||
|
||||
2012-10-25 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/54902
|
||||
|
56
gcc/testsuite/g++.dg/ext/vector19.C
Normal file
56
gcc/testsuite/g++.dg/ext/vector19.C
Normal file
@ -0,0 +1,56 @@
|
||||
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-options "-std=c++11 -mavx2" } */
|
||||
|
||||
// The target restrictions and the -mavx2 flag are meant to disappear
|
||||
// once vector lowering is in place.
|
||||
|
||||
typedef double vec __attribute__((vector_size(2*sizeof(double))));
|
||||
typedef signed char vec2 __attribute__((vector_size(16)));
|
||||
typedef unsigned char vec2u __attribute__((vector_size(16)));
|
||||
|
||||
void f (vec *x, vec *y, vec *z)
|
||||
{
|
||||
*x = (*y < *z) ? *x : *y;
|
||||
}
|
||||
|
||||
void g (vec *x, vec *y, vec *z)
|
||||
{
|
||||
*x = (*y < *z) ? *x : 42;
|
||||
}
|
||||
|
||||
void h (vec *x, vec *y, vec *z)
|
||||
{
|
||||
*x = (*y < *z) ? 3. : *y;
|
||||
}
|
||||
|
||||
void i1 (vec *x, vec *y, vec *z)
|
||||
{
|
||||
auto c = *y < *z;
|
||||
*x = c ? *x : *y;
|
||||
}
|
||||
|
||||
void i2 (vec2 *x, vec2 *y, vec2u *z)
|
||||
{
|
||||
*x = *y ? *x : *y;
|
||||
*y = *z ? *x : *y;
|
||||
}
|
||||
|
||||
void j (vec2 *x, vec2 *y, vec2 *z, vec *t)
|
||||
{
|
||||
*x = (*y < *z) ? *x : 4.2; /* { dg-error "" } */
|
||||
*y = (*x < *z) ? 2.5 : *y; /* { dg-error "" } */
|
||||
*t = *t ? *t : *t; /* { dg-error "" } */
|
||||
*z = (*x < *z) ? '1' : '0'; /* { dg-error "" } */
|
||||
// The last one may eventually be accepted.
|
||||
}
|
||||
|
||||
template <class A, class B>
|
||||
auto k (A *a, B b) -> decltype (*a ? *a : b);
|
||||
|
||||
void k (...) {}
|
||||
|
||||
void l (vec2 *v, double x)
|
||||
{
|
||||
k (v, x);
|
||||
}
|
||||
|
11
gcc/tree.c
11
gcc/tree.c
@ -10241,6 +10241,17 @@ signed_or_unsigned_type_for (int unsignedp, tree type)
|
||||
if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp)
|
||||
return type;
|
||||
|
||||
if (TREE_CODE (type) == VECTOR_TYPE)
|
||||
{
|
||||
tree inner = TREE_TYPE (type);
|
||||
tree inner2 = signed_or_unsigned_type_for (unsignedp, inner);
|
||||
if (!inner2)
|
||||
return NULL_TREE;
|
||||
if (inner == inner2)
|
||||
return type;
|
||||
return build_vector_type (inner2, TYPE_VECTOR_SUBPARTS (type));
|
||||
}
|
||||
|
||||
if (!INTEGRAL_TYPE_P (type)
|
||||
&& !POINTER_TYPE_P (type))
|
||||
return NULL_TREE;
|
||||
|
Loading…
Reference in New Issue
Block a user