From 305708cedd962831b648783936cb6991dfdeb87d Mon Sep 17 00:00:00 2001 From: Yuri Rumyantsev Date: Mon, 18 Jan 2016 14:14:35 +0000 Subject: [PATCH] re PR middle-end/68542 (10% 481.wrf performance regression) gcc/ 2016-01-18 Yuri Rumyantsev 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 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/fold-const.c | 23 ++++++++++++++++++++++- gcc/tree-cfg.c | 27 ++++++++++++++++----------- gcc/tree-vrp.c | 5 +++-- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 972ddec..f5bd86f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2016-01-18 Yuri Rumyantsev + + 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 * config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): Require 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 diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index dbfa506..b54545d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -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 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 8f35eb7..159d487 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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. -- 2.7.4