Hello,

this patch makes gimple checking of vector comparisons more strict by ensuring that it doesn't return a boolean. It also fixes a bug that this check detected in fold-const.c: for (void)(x<0), the C front-end was calling fold_unary_loc on the conversion to void, which was then converted to if(x<0)(void)0.

2012-11-02  Marc Glisse  <marc.gli...@inria.fr>

        * tree-cfg.c (verify_gimple_comparison): Verify that vector
        comparison returns a vector.
        * fold-const.c (fold_unary_loc): Disable conversion optimization
        for void type.

--
Marc Glisse
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 193060)
+++ gcc/fold-const.c    (working copy)
@@ -7742,21 +7742,22 @@ fold_unary_loc (location_t loc, enum tre
          /* If we have (type) (a CMP b) and type is an integral type, return
             new expression involving the new type.  Canonicalize
             (type) (a CMP b) to (a CMP b) ? (type) true : (type) false for
             non-integral type.
             Do not fold the result as that would not simplify further, also
             folding again results in recursions.  */
          if (TREE_CODE (type) == BOOLEAN_TYPE)
            return build2_loc (loc, TREE_CODE (op0), type,
                               TREE_OPERAND (op0, 0),
                               TREE_OPERAND (op0, 1));
-         else if (!INTEGRAL_TYPE_P (type) && TREE_CODE (type) != VECTOR_TYPE)
+         else if (!INTEGRAL_TYPE_P (type) && !VOID_TYPE_P (type)
+                  && TREE_CODE (type) != VECTOR_TYPE)
            return build3_loc (loc, COND_EXPR, type, op0,
                               constant_boolean_node (true, type),
                               constant_boolean_node (false, type));
        }
 
       /* Handle cases of two conversions in a row.  */
       if (CONVERT_EXPR_P (op0))
        {
          tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
          tree inter_type = TREE_TYPE (op0);
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 193060)
+++ gcc/tree-cfg.c      (working copy)
@@ -3263,21 +3263,30 @@ verify_gimple_comparison (tree type, tre
       error ("mismatching comparison operand types");
       debug_generic_expr (op0_type);
       debug_generic_expr (op1_type);
       return true;
     }
 
   /* The resulting type of a comparison may be an effective boolean type.  */
   if (INTEGRAL_TYPE_P (type)
       && (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;
+        }
+    }
   /* Or an integer vector type with the same size and element count
      as the comparison operand types.  */
   else if (TREE_CODE (type) == VECTOR_TYPE
           && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
     {
       if (TREE_CODE (op0_type) != VECTOR_TYPE
          || TREE_CODE (op1_type) != VECTOR_TYPE)
         {
           error ("non-vector operands in vector comparison");
           debug_generic_expr (op0_type);

Reply via email to