diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78c31bca6f4..e6a2cdbe287 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2012-09-29 Marc Glisse + + * tree.c (truth_type_for): New function. + * tree.h (truth_type_for): Declare. + * gimple-fold.c (and_comparisons_1): Call it. + (or_comparisons_1): Likewise. + * tree-ssa-forwprop.c (forward_propagate_into_cond): Don't use + boolean_type_node for vectors. + 2012-09-28 Jan Hubicka * basic-block.h (RDIV): Define. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 4dba726f274..66d076664cc 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "target.h" #include "gimple-fold.h" -#include "langhooks.h" /* Return true when DECL can be referenced from current unit. FROM_DECL (if non-null) specify constructor of variable DECL was taken from. @@ -1693,15 +1692,7 @@ static tree and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree truth_type = boolean_type_node; - if (TREE_CODE (TREE_TYPE (op1a)) == VECTOR_TYPE) - { - tree vec_type = TREE_TYPE (op1a); - tree elem = lang_hooks.types.type_for_size - (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vec_type))), 0); - truth_type = build_opaque_vector_type (elem, - TYPE_VECTOR_SUBPARTS (vec_type)); - } + tree truth_type = truth_type_for (TREE_TYPE (op1a)); /* First check for ((x CODE1 y) AND (x CODE2 y)). */ if (operand_equal_p (op1a, op2a, 0) @@ -2165,15 +2156,7 @@ static tree or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree truth_type = boolean_type_node; - if (TREE_CODE (TREE_TYPE (op1a)) == VECTOR_TYPE) - { - tree vec_type = TREE_TYPE (op1a); - tree elem = lang_hooks.types.type_for_size - (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vec_type))), 0); - truth_type = build_opaque_vector_type (elem, - TYPE_VECTOR_SUBPARTS (vec_type)); - } + tree truth_type = truth_type_for (TREE_TYPE (op1a)); /* First check for ((x CODE1 y) OR (x CODE2 y)). */ if (operand_equal_p (op1a, op2a, 0) diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index cd8f092915b..b0e951a22f7 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -556,7 +556,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) /* We can do tree combining on SSA_NAME and comparison expressions. */ if (COMPARISON_CLASS_P (cond)) tmp = forward_propagate_into_comparison_1 (stmt, TREE_CODE (cond), - boolean_type_node, + TREE_TYPE (cond), TREE_OPERAND (cond, 0), TREE_OPERAND (cond, 1)); else if (TREE_CODE (cond) == SSA_NAME) diff --git a/gcc/tree.c b/gcc/tree.c index 9169424a01b..7f620e511be 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10250,6 +10250,22 @@ signed_type_for (tree type) return signed_or_unsigned_type_for (0, type); } +/* If TYPE is a vector type, return a signed integer vector type with the + same width and number of subparts. Otherwise return boolean_type_node. */ + +tree +truth_type_for (tree type) +{ + if (TREE_CODE (type) == VECTOR_TYPE) + { + tree elem = lang_hooks.types.type_for_size + (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type))), 0); + return build_opaque_vector_type (elem, TYPE_VECTOR_SUBPARTS (type)); + } + else + return boolean_type_node; +} + /* Returns the largest value obtainable by casting something in INNER type to OUTER type. */ diff --git a/gcc/tree.h b/gcc/tree.h index 2050efd71e1..0130ce464ee 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4769,6 +4769,7 @@ extern tree make_unsigned_type (int); extern tree signed_or_unsigned_type_for (int, tree); extern tree signed_type_for (tree); extern tree unsigned_type_for (tree); +extern tree truth_type_for (tree); extern void initialize_sizetypes (void); extern void fixup_unsigned_type (tree); extern tree build_pointer_type_for_mode (tree, enum machine_mode, bool);