diff options
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index cd8dbdf0f3e..bece8d74b46 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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 |