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
This commit is contained in:
Yuri Rumyantsev 2016-01-18 14:14:35 +00:00 committed by Ilya Enkovich
parent 969028053f
commit 305708cedd
4 changed files with 55 additions and 14 deletions

View File

@ -1,3 +1,17 @@
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>
* config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): Require

View File

@ -6446,13 +6446,17 @@ fold_binary_op_with_conditional_arg (location_t loc,
if (VOID_TYPE_P (TREE_TYPE (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);
test = cond;
true_value = constant_boolean_node (true, 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)
cond_code = VEC_COND_EXPR;
@ -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 (!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);
tree *elts = XALLOCAVEC (tree, count);
gcc_assert (VECTOR_CST_NELTS (op1) == count

View File

@ -3437,10 +3437,10 @@ verify_gimple_call (gcall *stmt)
}
/* 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
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 op1_type = TREE_TYPE (op1);
@ -3474,13 +3474,17 @@ verify_gimple_comparison (tree type, tree op0, tree op1)
&& (TREE_CODE (type) == BOOLEAN_TYPE
|| TYPE_PRECISION (type) == 1))
{
if (TREE_CODE (op0_type) == VECTOR_TYPE
|| TREE_CODE (op1_type) == VECTOR_TYPE)
{
error ("vector comparison returning a boolean");
debug_generic_expr (op0_type);
debug_generic_expr (op1_type);
return true;
if ((TREE_CODE (op0_type) == VECTOR_TYPE
|| TREE_CODE (op1_type) == VECTOR_TYPE)
&& code != EQ_EXPR && code != NE_EXPR
&& !VECTOR_BOOLEAN_TYPE_P (op0_type)
&& !VECTOR_INTEGER_TYPE_P (op0_type))
{
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
@ -3861,7 +3865,7 @@ verify_gimple_assign_binary (gassign *stmt)
case LTGT_EXPR:
/* Comparisons are also binary, but the result type is not
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:
if (TREE_CODE (lhs_type) != INTEGER_TYPE)
@ -4570,7 +4574,8 @@ verify_gimple_cond (gcond *stmt)
return verify_gimple_comparison (boolean_type_node,
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

View File

@ -5067,8 +5067,9 @@ extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code,
if (invert)
comp_code = invert_tree_comparison (comp_code, 0);
/* VRP does not handle float types. */
if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (val)))
/* VRP only handles integral and pointer types. */
if (! INTEGRAL_TYPE_P (TREE_TYPE (val))
&& ! POINTER_TYPE_P (TREE_TYPE (val)))
return false;
/* Do not register always-false predicates.