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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232518
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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;
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
}
/* 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);
&& (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
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)
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
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.