]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
20011-08-29 Artjoms Sinkarovs <artyom.shinkaroff@gmail.com>
authorArtjoms Sinkarovs <artyom.shinkaroff@gmail.com>
Mon, 29 Aug 2011 11:55:45 +0000 (11:55 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 29 Aug 2011 11:55:45 +0000 (11:55 +0000)
Richard Guenther  <rguenther@suse.de>

* tree.h (constant_boolean_node): Adjust prototype.
* fold-const.c (fold_convert_loc): Move aggregate conversion
leeway down.
(constant_boolean_node): Make value parameter boolean, add
vector type handling.
(fold_unary_loc): Use constant_boolean_node.
(fold_binary_loc): Preserve types properly when folding
COMPLEX_EXPR <__real x, __imag x>.
* gimplify.c (gimplify_expr): Handle vector comparison.
* tree.def (EQ_EXPR, ...): Document behavior on vector typed
comparison.
* tree-cfg.c (verify_gimple_comparison): Verify vector typed
comparisons.

From-SVN: r178209

gcc/ChangeLog
gcc/fold-const.c
gcc/gimplify.c
gcc/tree-cfg.c
gcc/tree.def
gcc/tree.h

index 7a35deb088f6df8a9b1798e98497a8d3ae589702..c1b6de3fc95215b3946a9fc8ce0ae211883d0f36 100644 (file)
@@ -1,3 +1,20 @@
+20011-08-29  Artjoms Sinkarovs  <artyom.shinkaroff@gmail.com>
+       Richard Guenther  <rguenther@suse.de>
+
+       * tree.h (constant_boolean_node): Adjust prototype.
+       * fold-const.c (fold_convert_loc): Move aggregate conversion
+       leeway down.
+       (constant_boolean_node): Make value parameter boolean, add
+       vector type handling.
+       (fold_unary_loc): Use constant_boolean_node.
+       (fold_binary_loc): Preserve types properly when folding
+       COMPLEX_EXPR <__real x, __imag x>.
+       * gimplify.c (gimplify_expr): Handle vector comparison.
+       * tree.def (EQ_EXPR, ...): Document behavior on vector typed
+       comparison.
+       * tree-cfg.c (verify_gimple_comparison): Verify vector typed
+       comparisons.
+
 2011-08-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/48722
index 01c5570e28bf72bbbbdc7b8e9f907f151f9c99a5..5807a5533ba208ae88b5282544068d3b0ed419d6 100644 (file)
@@ -1867,9 +1867,6 @@ fold_convert_loc (location_t loc, tree type, tree arg)
       || TREE_CODE (orig) == ERROR_MARK)
     return error_mark_node;
 
-  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
-    return fold_build1_loc (loc, NOP_EXPR, type, arg);
-
   switch (TREE_CODE (type))
     {
     case POINTER_TYPE:
@@ -2017,6 +2014,8 @@ fold_convert_loc (location_t loc, tree type, tree arg)
       return fold_build1_loc (loc, NOP_EXPR, type, tem);
 
     default:
+      if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
+       return fold_build1_loc (loc, NOP_EXPR, type, arg);
       gcc_unreachable ();
     }
  fold_convert_exit:
@@ -5929,17 +5928,22 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
 }
 \f
 /* Return a node which has the indicated constant VALUE (either 0 or
-   1), and is of the indicated TYPE.  */
+   1 for scalars or {-1,-1,..} or {0,0,...} for vectors),
+   and is of the indicated TYPE.  */
 
 tree
-constant_boolean_node (int value, tree type)
+constant_boolean_node (bool value, tree type)
 {
   if (type == integer_type_node)
     return value ? integer_one_node : integer_zero_node;
   else if (type == boolean_type_node)
     return value ? boolean_true_node : boolean_false_node;
+  else if (TREE_CODE (type) == VECTOR_TYPE)
+    return build_vector_from_val (type,
+                                 build_int_cst (TREE_TYPE (type),
+                                                value ? -1 : 0));
   else
-    return build_int_cst (type, value);
+    return fold_convert (type, value ? integer_one_node : integer_zero_node);
 }
 
 
@@ -7668,8 +7672,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
                               TREE_OPERAND (op0, 1));
          else if (!INTEGRAL_TYPE_P (type))
            return build3_loc (loc, COND_EXPR, type, op0,
-                              fold_convert (type, boolean_true_node),
-                              fold_convert (type, boolean_false_node));
+                              constant_boolean_node (true, type),
+                              constant_boolean_node (false, type));
        }
 
       /* Handle cases of two conversions in a row.  */
@@ -13202,8 +13206,7 @@ fold_binary_loc (location_t loc,
        return build_complex (type, arg0, arg1);
       if (TREE_CODE (arg0) == REALPART_EXPR
          && TREE_CODE (arg1) == IMAGPART_EXPR
-         && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg0, 0)))
-             == TYPE_MAIN_VARIANT (type))
+         && TREE_TYPE (TREE_OPERAND (arg0, 0)) == type
          && operand_equal_p (TREE_OPERAND (arg0, 0),
                              TREE_OPERAND (arg1, 0), 0))
        return omit_one_operand_loc (loc, type, TREE_OPERAND (arg0, 0),
index 85033a998654c0db2b1b4644d5497da0f0bf9f91..a22b5d3121f6057a96fbaa2a0684105e1e540b1f 100644 (file)
@@ -7349,7 +7349,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                {
                  tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
 
-                 if (!AGGREGATE_TYPE_P (type))
+                 /* Vector comparisons need no boolification.  */
+                 if (TREE_CODE (type) == VECTOR_TYPE)
+                   goto expr_2;
+                 else if (!AGGREGATE_TYPE_P (type))
                    {
                      tree org_type = TREE_TYPE (*expr_p);
                      *expr_p = gimple_boolify (*expr_p);
index b266d1bc55430a2696b59c0ddcd068824e8642e7..bcb8ba9b742a3a31da4df33914f3335d0aebfe2d 100644 (file)
@@ -3193,25 +3193,55 @@ verify_gimple_comparison (tree type, tree op0, tree op1)
      effective type the comparison is carried out in.  Instead
      we require that either the first operand is trivially
      convertible into the second, or the other way around.
-     The resulting type of a comparison may be any integral type.
      Because we special-case pointers to void we allow
      comparisons of pointers with the same mode as well.  */
-  if ((!useless_type_conversion_p (op0_type, op1_type)
-       && !useless_type_conversion_p (op1_type, op0_type)
-       && (!POINTER_TYPE_P (op0_type)
-          || !POINTER_TYPE_P (op1_type)
-          || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
-      || !INTEGRAL_TYPE_P (type)
-      || (TREE_CODE (type) != BOOLEAN_TYPE
-         && TYPE_PRECISION (type) != 1))
-    {
-      error ("type mismatch in comparison expression");
-      debug_generic_expr (type);
+  if (!useless_type_conversion_p (op0_type, op1_type)
+      && !useless_type_conversion_p (op1_type, op0_type)
+      && (!POINTER_TYPE_P (op0_type)
+         || !POINTER_TYPE_P (op1_type)
+         || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
+    {
+      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))
+    ;
+  /* 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);
+          debug_generic_expr (op1_type);
+          return true;
+        }
+
+      if (TYPE_VECTOR_SUBPARTS (type) != TYPE_VECTOR_SUBPARTS (op0_type)
+         || (GET_MODE_SIZE (TYPE_MODE (type))
+             != GET_MODE_SIZE (TYPE_MODE (op0_type))))
+        {
+          error ("invalid vector comparison resulting type");
+          debug_generic_expr (type);
+          return true;
+        }
+    }
+  else
+    {
+      error ("bogus comparison result type");
+      debug_generic_expr (type);
+      return true;
+    }
+
   return false;
 }
 
index d4b3cb98d6e3279083dd0a54b84c6b1c5e5ea160..ea255d5805d0e97c292a7d7cdefb8645f95671c7 100644 (file)
@@ -704,7 +704,10 @@ DEFTREECODE (TRUTH_NOT_EXPR, "truth_not_expr", tcc_expression, 1)
    The others are allowed only for integer (or pointer or enumeral)
    or real types.
    In all cases the operands will have the same type,
-   and the value is always the type used by the language for booleans.  */
+   and the value is either the type used by the language for booleans
+   or an integer vector type of the same size and with the same number
+   of elements as the comparison operands.  True for a vector of
+   comparison results has all bits set while false is equal to zero.  */
 DEFTREECODE (LT_EXPR, "lt_expr", tcc_comparison, 2)
 DEFTREECODE (LE_EXPR, "le_expr", tcc_comparison, 2)
 DEFTREECODE (GT_EXPR, "gt_expr", tcc_comparison, 2)
index 1f56c499c4978a641d4f6689993e5623f35b6ea5..06f67f425d9adef3e6f0971960d36607f94be2df 100644 (file)
@@ -5274,7 +5274,7 @@ extern tree build_simple_mem_ref_loc (location_t, tree);
 extern double_int mem_ref_offset (const_tree);
 extern tree reference_alias_ptr_type (const_tree);
 extern tree build_invariant_address (tree, tree, HOST_WIDE_INT);
-extern tree constant_boolean_node (int, tree);
+extern tree constant_boolean_node (bool, tree);
 extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree);
 
 extern bool tree_swap_operands_p (const_tree, const_tree, bool);