gcc/
authorienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Jan 2016 14:14:35 +0000 (14:14 +0000)
committerienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Jan 2016 14:14:35 +0000 (14:14 +0000)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/tree-cfg.c
gcc/tree-vrp.c

index 972ddec..f5bd86f 100644 (file)
@@ -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
index cd8dbdf..bece8d7 100644 (file)
@@ -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
index dbfa506..b54545d 100644 (file)
@@ -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
index 8f35eb7..159d487 100644 (file)
@@ -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.