Commit 08e0cda6 by Marc Glisse Committed by Marc Glisse

tree.h (VECTOR_TYPE_P): New macro.

2013-03-21  Marc Glisse  <marc.glisse@inria.fr>

gcc/
	* tree.h (VECTOR_TYPE_P): New macro.
	(VECTOR_INTEGER_TYPE_P, VECTOR_FLOAT_TYPE_P, FLOAT_TYPE_P,
	TYPE_MODE): Use it.
	* fold-const.c (fold_cond_expr_with_comparison): Use build_zero_cst.
	VEC_COND_EXPR cannot be lvalues.
	(fold_ternary_loc) <VEC_COND_EXPR>: Merge with the COND_EXPR case.

gcc/cp/
	* call.c (build_conditional_expr_1): Fold VEC_COND_EXPR.

gcc/testsuite/
	* g++.dg/ext/vector21.C: New testcase.

From-SVN: r196884
parent d08633b4
2013-03-21 Marc Glisse <marc.glisse@inria.fr> 2013-03-21 Marc Glisse <marc.glisse@inria.fr>
* tree.h (VECTOR_TYPE_P): New macro.
(VECTOR_INTEGER_TYPE_P, VECTOR_FLOAT_TYPE_P, FLOAT_TYPE_P,
TYPE_MODE): Use it.
* fold-const.c (fold_cond_expr_with_comparison): Use build_zero_cst.
VEC_COND_EXPR cannot be lvalues.
(fold_ternary_loc) <VEC_COND_EXPR>: Merge with the COND_EXPR case.
2013-03-21 Marc Glisse <marc.glisse@inria.fr>
* simplify-rtx.c (simplify_binary_operation_1) <VEC_CONCAT>: * simplify-rtx.c (simplify_binary_operation_1) <VEC_CONCAT>:
Restrict the transformation to equal modes. Restrict the transformation to equal modes.
......
2013-03-21 Marc Glisse <marc.glisse@inria.fr>
* call.c (build_conditional_expr_1): Fold VEC_COND_EXPR.
2013-03-21 Richard Biener <rguenther@suse.de> 2013-03-21 Richard Biener <rguenther@suse.de>
* error.c (cp_printer): Use DECL_HAS_DEBUG_EXPR_P instead of * error.c (cp_printer): Use DECL_HAS_DEBUG_EXPR_P instead of
......
...@@ -4437,9 +4437,9 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, ...@@ -4437,9 +4437,9 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
} }
if (!COMPARISON_CLASS_P (arg1)) if (!COMPARISON_CLASS_P (arg1))
arg1 = build2 (NE_EXPR, signed_type_for (arg1_type), arg1, arg1 = fold_build2 (NE_EXPR, signed_type_for (arg1_type), arg1,
build_zero_cst (arg1_type)); build_zero_cst (arg1_type));
return build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3); return fold_build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
} }
/* [expr.cond] /* [expr.cond]
......
...@@ -4633,7 +4633,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, ...@@ -4633,7 +4633,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
if (comp_code == NE_EXPR) if (comp_code == NE_EXPR)
return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1));
else if (comp_code == EQ_EXPR) else if (comp_code == EQ_EXPR)
return build_int_cst (type, 0); return build_zero_cst (type);
} }
/* Try some transformations of A op B ? A : B. /* Try some transformations of A op B ? A : B.
...@@ -4667,6 +4667,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, ...@@ -4667,6 +4667,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
/* Avoid these transformations if the COND_EXPR may be used /* Avoid these transformations if the COND_EXPR may be used
as an lvalue in the C++ front-end. PR c++/19199. */ as an lvalue in the C++ front-end. PR c++/19199. */
&& (in_gimple_form && (in_gimple_form
|| VECTOR_TYPE_P (type)
|| (strcmp (lang_hooks.name, "GNU C++") != 0 || (strcmp (lang_hooks.name, "GNU C++") != 0
&& strcmp (lang_hooks.name, "GNU Objective-C++") != 0) && strcmp (lang_hooks.name, "GNU Objective-C++") != 0)
|| ! maybe_lvalue_p (arg1) || ! maybe_lvalue_p (arg1)
...@@ -13899,6 +13900,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -13899,6 +13900,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
return NULL_TREE; return NULL_TREE;
case COND_EXPR: case COND_EXPR:
case VEC_COND_EXPR:
/* Pedantic ANSI C says that a conditional expression is never an lvalue, /* Pedantic ANSI C says that a conditional expression is never an lvalue,
so all simple results must be passed through pedantic_non_lvalue. */ so all simple results must be passed through pedantic_non_lvalue. */
if (TREE_CODE (arg0) == INTEGER_CST) if (TREE_CODE (arg0) == INTEGER_CST)
...@@ -13916,6 +13918,14 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -13916,6 +13918,14 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
return pedantic_non_lvalue_loc (loc, tem); return pedantic_non_lvalue_loc (loc, tem);
return NULL_TREE; return NULL_TREE;
} }
else if (TREE_CODE (arg0) == VECTOR_CST)
{
if (integer_all_onesp (arg0))
return pedantic_omit_one_operand_loc (loc, type, arg1, arg2);
if (integer_zerop (arg0))
return pedantic_omit_one_operand_loc (loc, type, arg2, arg1);
}
if (operand_equal_p (arg1, op2, 0)) if (operand_equal_p (arg1, op2, 0))
return pedantic_omit_one_operand_loc (loc, type, arg1, arg0); return pedantic_omit_one_operand_loc (loc, type, arg1, arg0);
...@@ -13951,6 +13961,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -13951,6 +13961,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
} }
} }
/* ??? Fixup the code below for VEC_COND_EXPR. */
if (code == VEC_COND_EXPR)
return NULL_TREE;
/* If the second operand is simpler than the third, swap them /* If the second operand is simpler than the third, swap them
since that produces better jump optimization results. */ since that produces better jump optimization results. */
if (truth_value_p (TREE_CODE (arg0)) if (truth_value_p (TREE_CODE (arg0))
...@@ -14138,16 +14152,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -14138,16 +14152,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
return NULL_TREE; return NULL_TREE;
case VEC_COND_EXPR:
if (TREE_CODE (arg0) == VECTOR_CST)
{
if (integer_all_onesp (arg0) && !TREE_SIDE_EFFECTS (op2))
return pedantic_non_lvalue_loc (loc, op1);
if (integer_zerop (arg0) && !TREE_SIDE_EFFECTS (op1))
return pedantic_non_lvalue_loc (loc, op2);
}
return NULL_TREE;
case CALL_EXPR: case CALL_EXPR:
/* CALL_EXPRs used to be ternary exprs. Catch any mistaken uses /* CALL_EXPRs used to be ternary exprs. Catch any mistaken uses
of fold_ternary on them. */ of fold_ternary on them. */
......
2013-03-21 Marc Glisse <marc.glisse@inria.fr>
* g++.dg/ext/vector21.C: New testcase.
2013-03-21 Christophe Lyon <christophe.lyon@linaro.org> 2013-03-21 Christophe Lyon <christophe.lyon@linaro.org>
* gcc.target/arm/neon-for-64bits-1.c: New tests. * gcc.target/arm/neon-for-64bits-1.c: New tests.
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-gimple" } */
typedef int vec __attribute__ ((vector_size (4 * sizeof (int))));
void f1 (vec *x)
{
*x = (*x >= 0) ? *x : -*x;
}
void f2 (vec *x)
{
*x = (0 < *x) ? *x : -*x;
}
void g1 (vec *x)
{
*x = (*x < 0) ? -*x : *x;
}
void g2 (vec *x)
{
*x = (0 > *x) ? -*x : *x;
}
void h (vec *x, vec *y)
{
*x = (*x < *y) ? *y : *x;
}
void i (vec *x, vec *y)
{
*x = (*x < *y) ? *x : *y;
}
void j (vec *x, vec *y)
{
*x = (*x < *y) ? *x : *x;
}
/* { dg-final { scan-tree-dump-times "ABS_EXPR" 4 "gimple" } } */
/* { dg-final { scan-tree-dump "MIN_EXPR" "gimple" } } */
/* { dg-final { scan-tree-dump "MAX_EXPR" "gimple" } } */
/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
...@@ -981,6 +981,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, ...@@ -981,6 +981,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define STRIP_USELESS_TYPE_CONVERSION(EXP) \ #define STRIP_USELESS_TYPE_CONVERSION(EXP) \
(EXP) = tree_ssa_strip_useless_type_conversions (EXP) (EXP) = tree_ssa_strip_useless_type_conversions (EXP)
/* Nonzero if TYPE represents a vector type. */
#define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE)
/* Nonzero if TYPE represents an integral type. Note that we do not /* Nonzero if TYPE represents an integral type. Note that we do not
include COMPLEX types here. Keep these checks in ascending code include COMPLEX types here. Keep these checks in ascending code
order. */ order. */
...@@ -1017,14 +1021,14 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, ...@@ -1017,14 +1021,14 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* Nonzero if TYPE represents a vector integer type. */ /* Nonzero if TYPE represents a vector integer type. */
#define VECTOR_INTEGER_TYPE_P(TYPE) \ #define VECTOR_INTEGER_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == VECTOR_TYPE \ (VECTOR_TYPE_P (TYPE) \
&& TREE_CODE (TREE_TYPE (TYPE)) == INTEGER_TYPE) && TREE_CODE (TREE_TYPE (TYPE)) == INTEGER_TYPE)
/* Nonzero if TYPE represents a vector floating-point type. */ /* Nonzero if TYPE represents a vector floating-point type. */
#define VECTOR_FLOAT_TYPE_P(TYPE) \ #define VECTOR_FLOAT_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == VECTOR_TYPE \ (VECTOR_TYPE_P (TYPE) \
&& TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE) && TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE)
/* Nonzero if TYPE represents a floating-point type, including complex /* Nonzero if TYPE represents a floating-point type, including complex
...@@ -1034,7 +1038,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, ...@@ -1034,7 +1038,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define FLOAT_TYPE_P(TYPE) \ #define FLOAT_TYPE_P(TYPE) \
(SCALAR_FLOAT_TYPE_P (TYPE) \ (SCALAR_FLOAT_TYPE_P (TYPE) \
|| ((TREE_CODE (TYPE) == COMPLEX_TYPE \ || ((TREE_CODE (TYPE) == COMPLEX_TYPE \
|| TREE_CODE (TYPE) == VECTOR_TYPE) \ || VECTOR_TYPE_P (TYPE)) \
&& SCALAR_FLOAT_TYPE_P (TREE_TYPE (TYPE)))) && SCALAR_FLOAT_TYPE_P (TREE_TYPE (TYPE))))
/* Nonzero if TYPE represents a decimal floating-point type. */ /* Nonzero if TYPE represents a decimal floating-point type. */
...@@ -2116,7 +2120,7 @@ struct GTY(()) tree_block { ...@@ -2116,7 +2120,7 @@ struct GTY(()) tree_block {
/* Vector types need to check target flags to determine type. */ /* Vector types need to check target flags to determine type. */
extern enum machine_mode vector_type_mode (const_tree); extern enum machine_mode vector_type_mode (const_tree);
#define TYPE_MODE(NODE) \ #define TYPE_MODE(NODE) \
(TREE_CODE (TYPE_CHECK (NODE)) == VECTOR_TYPE \ (VECTOR_TYPE_P (TYPE_CHECK (NODE)) \
? vector_type_mode (NODE) : (NODE)->type_common.mode) ? vector_type_mode (NODE) : (NODE)->type_common.mode)
#define SET_TYPE_MODE(NODE, MODE) \ #define SET_TYPE_MODE(NODE, MODE) \
(TYPE_CHECK (NODE)->type_common.mode = (MODE)) (TYPE_CHECK (NODE)->type_common.mode = (MODE))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment