mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2012-10-25 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* ipa-inline.c (recursive_inlining): Redirect to master
|
* 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>
|
2012-10-23 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* c-common.h (pch_cpp_save_state): Declare.
|
* 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;
|
integer_only_op = true;
|
||||||
/* ... fall through ... */
|
/* ... fall through ... */
|
||||||
|
|
||||||
|
case VEC_COND_EXPR:
|
||||||
|
|
||||||
case PLUS_EXPR:
|
case PLUS_EXPR:
|
||||||
case MINUS_EXPR:
|
case MINUS_EXPR:
|
||||||
case MULT_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>
|
2012-10-25 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR c++/34892
|
PR c++/34892
|
||||||
|
|
|
||||||
|
|
@ -4373,18 +4373,90 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
|
||||||
arg2 = arg1 = save_expr (arg1);
|
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]
|
/* [expr.cond]
|
||||||
|
|
||||||
The first expression is implicitly converted to bool (clause
|
The first expression is implicitly converted to bool (clause
|
||||||
_conv_). */
|
_conv_). */
|
||||||
arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
|
arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
|
||||||
LOOKUP_NORMAL);
|
LOOKUP_NORMAL);
|
||||||
|
if (error_operand_p (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;
|
return error_mark_node;
|
||||||
|
|
||||||
/* [expr.cond]
|
/* [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
|
array-to-pointer (_conv.array_), and function-to-pointer
|
||||||
(_conv.func_) standard conversions are performed on the second
|
(_conv.func_) standard conversions are performed on the second
|
||||||
and third operands. */
|
and third operands. */
|
||||||
orig_arg2 = arg2;
|
|
||||||
orig_arg3 = arg3;
|
|
||||||
arg2_type = unlowered_expr_type (arg2);
|
arg2_type = unlowered_expr_type (arg2);
|
||||||
arg3_type = unlowered_expr_type (arg3);
|
arg3_type = unlowered_expr_type (arg3);
|
||||||
if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
|
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);
|
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,
|
tree min = build_min_non_dep (COND_EXPR, expr,
|
||||||
orig_ifexp, orig_op1, orig_op2);
|
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>
|
2012-10-25 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/54902
|
PR tree-optimization/54902
|
||||||
|
|
|
||||||
|
|
@ -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)
|
if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp)
|
||||||
return type;
|
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)
|
if (!INTEGRAL_TYPE_P (type)
|
||||||
&& !POINTER_TYPE_P (type))
|
&& !POINTER_TYPE_P (type))
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue