aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorYuri Rumyantsev <ysrumyan@gmail.com>2016-01-18 14:14:35 +0000
committerIlya Enkovich <ienkovich@gcc.gnu.org>2016-01-18 14:14:35 +0000
commit305708cedd962831b648783936cb6991dfdeb87d (patch)
treefd70591afccdc84c6a6d41f54a41b785c0f898b8 /gcc/fold-const.c
parent969028053faeba62b856707b0ab5d49a15edc688 (diff)
downloadgcc-305708cedd962831b648783936cb6991dfdeb87d.zip
gcc-305708cedd962831b648783936cb6991dfdeb87d.tar.gz
gcc-305708cedd962831b648783936cb6991dfdeb87d.tar.bz2
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index cd8dbdf..bece8d7 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