mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 10:30:56 +08:00
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:
parent
969028053f
commit
305708cedd
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user