diff options
author | Artjoms Sinkarovs <artyom.shinkaroff@gmail.com> | 2011-08-29 11:55:45 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-08-29 11:55:45 +0000 |
commit | 544d960a12742dbe8c8e9a968764d4502b239a26 (patch) | |
tree | a6235b0de2204188ae68275b478b1d3c90038b41 /gcc | |
parent | 776bebcdb0de9557b40aa5496c016588da845398 (diff) | |
download | gcc-544d960a12742dbe8c8e9a968764d4502b239a26.zip gcc-544d960a12742dbe8c8e9a968764d4502b239a26.tar.gz gcc-544d960a12742dbe8c8e9a968764d4502b239a26.tar.bz2 |
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.
From-SVN: r178209
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/fold-const.c | 23 | ||||
-rw-r--r-- | gcc/gimplify.c | 5 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 54 | ||||
-rw-r--r-- | gcc/tree.def | 5 | ||||
-rw-r--r-- | gcc/tree.h | 2 |
6 files changed, 81 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a35deb..c1b6de3 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 01c5570..5807a55 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 85033a9..a22b5d3 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 b266d1b..bcb8ba9 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 d4b3cb9..ea255d5 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) @@ -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); |