Commit 305708ce by Yuri Rumyantsev Committed by Ilya Enkovich

re PR middle-end/68542 (10% 481.wrf performance regression)

gcc/

2016-01-18  Yuri Rumyantsev  <ysrumyan@gmail.com>

	PR middle-end/68542
	* fold-const.c (fold_binary_op_with_conditional_arg): Bail out for case
	of mixind vector and scalar types.
	(fold_relational_const): Add handling of vector
	comparison with boolean result.
	* tree-cfg.c (verify_gimple_comparison): Add argument CODE, allow
	comparison of vector operands with boolean result for EQ/NE only.
	(verify_gimple_assign_binary): Adjust call for verify_gimple_comparison.
	(verify_gimple_cond): Likewise.
	* tree-vrp.c (extract_code_and_val_from_cond_with_ops): Modify check on
	valid type of VAL.

From-SVN: r232518
parent 96902805
2016-01-18 Yuri Rumyantsev <ysrumyan@gmail.com>
PR middle-end/68542
* fold-const.c (fold_binary_op_with_conditional_arg): Bail out for case
of mixind vector and scalar types.
(fold_relational_const): Add handling of vector
comparison with boolean result.
* tree-cfg.c (verify_gimple_comparison): Add argument CODE, allow
comparison of vector operands with boolean result for EQ/NE only.
(verify_gimple_assign_binary): Adjust call for verify_gimple_comparison.
(verify_gimple_cond): Likewise.
* tree-vrp.c (extract_code_and_val_from_cond_with_ops): Modify check on
valid type of VAL.
2016-01-18 Joseph Myers <joseph@codesourcery.com> 2016-01-18 Joseph Myers <joseph@codesourcery.com>
* config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): Require * config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): Require
......
...@@ -6446,13 +6446,17 @@ fold_binary_op_with_conditional_arg (location_t loc, ...@@ -6446,13 +6446,17 @@ fold_binary_op_with_conditional_arg (location_t loc,
if (VOID_TYPE_P (TREE_TYPE (false_value))) if (VOID_TYPE_P (TREE_TYPE (false_value)))
rhs = false_value; rhs = false_value;
} }
else else if (!(TREE_CODE (type) != VECTOR_TYPE
&& TREE_CODE (TREE_TYPE (cond)) == VECTOR_TYPE))
{ {
tree testtype = TREE_TYPE (cond); tree testtype = TREE_TYPE (cond);
test = cond; test = cond;
true_value = constant_boolean_node (true, testtype); true_value = constant_boolean_node (true, testtype);
false_value = constant_boolean_node (false, testtype); false_value = constant_boolean_node (false, testtype);
} }
else
/* Detect the case of mixing vector and scalar types - bail out. */
return NULL_TREE;
if (TREE_CODE (TREE_TYPE (test)) == VECTOR_TYPE) if (TREE_CODE (TREE_TYPE (test)) == VECTOR_TYPE)
cond_code = VEC_COND_EXPR; cond_code = VEC_COND_EXPR;
...@@ -13984,6 +13988,23 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) ...@@ -13984,6 +13988,23 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (op0) == VECTOR_CST && TREE_CODE (op1) == VECTOR_CST) if (TREE_CODE (op0) == VECTOR_CST && TREE_CODE (op1) == VECTOR_CST)
{ {
if (!VECTOR_TYPE_P (type))
{
/* Have vector comparison with scalar boolean result. */
bool result = true;
gcc_assert ((code == EQ_EXPR || code == NE_EXPR)
&& VECTOR_CST_NELTS (op0) == VECTOR_CST_NELTS (op1));
for (unsigned i = 0; i < VECTOR_CST_NELTS (op0); i++)
{
tree elem0 = VECTOR_CST_ELT (op0, i);
tree elem1 = VECTOR_CST_ELT (op1, i);
tree tmp = fold_relational_const (code, type, elem0, elem1);
result &= integer_onep (tmp);
}
if (code == NE_EXPR)
result = !result;
return constant_boolean_node (result, type);
}
unsigned count = VECTOR_CST_NELTS (op0); unsigned count = VECTOR_CST_NELTS (op0);
tree *elts = XALLOCAVEC (tree, count); tree *elts = XALLOCAVEC (tree, count);
gcc_assert (VECTOR_CST_NELTS (op1) == count gcc_assert (VECTOR_CST_NELTS (op1) == count
......
...@@ -3437,10 +3437,10 @@ verify_gimple_call (gcall *stmt) ...@@ -3437,10 +3437,10 @@ verify_gimple_call (gcall *stmt)
} }
/* Verifies the gimple comparison with the result type TYPE and /* Verifies the gimple comparison with the result type TYPE and
the operands OP0 and OP1. */ the operands OP0 and OP1, comparison code is CODE. */
static bool static bool
verify_gimple_comparison (tree type, tree op0, tree op1) verify_gimple_comparison (tree type, tree op0, tree op1, enum tree_code code)
{ {
tree op0_type = TREE_TYPE (op0); tree op0_type = TREE_TYPE (op0);
tree op1_type = TREE_TYPE (op1); tree op1_type = TREE_TYPE (op1);
...@@ -3474,13 +3474,17 @@ verify_gimple_comparison (tree type, tree op0, tree op1) ...@@ -3474,13 +3474,17 @@ verify_gimple_comparison (tree type, tree op0, tree op1)
&& (TREE_CODE (type) == BOOLEAN_TYPE && (TREE_CODE (type) == BOOLEAN_TYPE
|| TYPE_PRECISION (type) == 1)) || TYPE_PRECISION (type) == 1))
{ {
if (TREE_CODE (op0_type) == VECTOR_TYPE if ((TREE_CODE (op0_type) == VECTOR_TYPE
|| TREE_CODE (op1_type) == VECTOR_TYPE) || TREE_CODE (op1_type) == VECTOR_TYPE)
{ && code != EQ_EXPR && code != NE_EXPR
error ("vector comparison returning a boolean"); && !VECTOR_BOOLEAN_TYPE_P (op0_type)
debug_generic_expr (op0_type); && !VECTOR_INTEGER_TYPE_P (op0_type))
debug_generic_expr (op1_type); {
return true; error ("unsupported operation or type for vector comparison"
" returning a boolean");
debug_generic_expr (op0_type);
debug_generic_expr (op1_type);
return true;
} }
} }
/* Or a boolean vector type with the same element count /* Or a boolean vector type with the same element count
...@@ -3861,7 +3865,7 @@ verify_gimple_assign_binary (gassign *stmt) ...@@ -3861,7 +3865,7 @@ verify_gimple_assign_binary (gassign *stmt)
case LTGT_EXPR: case LTGT_EXPR:
/* Comparisons are also binary, but the result type is not /* Comparisons are also binary, but the result type is not
connected to the operand types. */ connected to the operand types. */
return verify_gimple_comparison (lhs_type, rhs1, rhs2); return verify_gimple_comparison (lhs_type, rhs1, rhs2, rhs_code);
case WIDEN_MULT_EXPR: case WIDEN_MULT_EXPR:
if (TREE_CODE (lhs_type) != INTEGER_TYPE) if (TREE_CODE (lhs_type) != INTEGER_TYPE)
...@@ -4570,7 +4574,8 @@ verify_gimple_cond (gcond *stmt) ...@@ -4570,7 +4574,8 @@ verify_gimple_cond (gcond *stmt)
return verify_gimple_comparison (boolean_type_node, return verify_gimple_comparison (boolean_type_node,
gimple_cond_lhs (stmt), gimple_cond_lhs (stmt),
gimple_cond_rhs (stmt)); gimple_cond_rhs (stmt),
gimple_cond_code (stmt));
} }
/* Verify the GIMPLE statement STMT. Returns true if there is an /* Verify the GIMPLE statement STMT. Returns true if there is an
......
...@@ -5067,8 +5067,9 @@ extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code, ...@@ -5067,8 +5067,9 @@ extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code,
if (invert) if (invert)
comp_code = invert_tree_comparison (comp_code, 0); comp_code = invert_tree_comparison (comp_code, 0);
/* VRP does not handle float types. */ /* VRP only handles integral and pointer types. */
if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (val))) if (! INTEGRAL_TYPE_P (TREE_TYPE (val))
&& ! POINTER_TYPE_P (TREE_TYPE (val)))
return false; return false;
/* Do not register always-false predicates. /* Do not register always-false predicates.
......
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