summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-29 11:55:45 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-29 11:55:45 +0000
commit3a82f2b428391a072f1525255973d6460a7547a0 (patch)
treea6235b0de2204188ae68275b478b1d3c90038b41 /gcc
parent6d2a4bac916130b755c670c81d2c1892d69cadc5 (diff)
downloadgcc-3a82f2b428391a072f1525255973d6460a7547a0.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178209 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/fold-const.c23
-rw-r--r--gcc/gimplify.c5
-rw-r--r--gcc/tree-cfg.c54
-rw-r--r--gcc/tree.def5
-rw-r--r--gcc/tree.h2
6 files changed, 81 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7a35deb088f..c1b6de3fc95 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 01c5570e28b..5807a5533ba 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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,
}
/* 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),
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 85033a99865..a22b5d3121f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index b266d1bc554..bcb8ba9b742 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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;
}
diff --git a/gcc/tree.def b/gcc/tree.def
index d4b3cb98d6e..ea255d5805d 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -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)
diff --git a/gcc/tree.h b/gcc/tree.h
index 1f56c499c49..06f67f425d9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);