From 1d15f620aa4e68f6298491d52ca8cc8d496457a6 Mon Sep 17 00:00:00 2001 From: Kai Tietz Date: Thu, 12 May 2011 20:19:07 +0200 Subject: [PATCH] gimplify.c (gimple_boolify): Re-boolify expression arguments even if expression type is of kind BOOLEAN_TYPE. 2011-05-12 Kai Tietz * gimplify.c (gimple_boolify): Re-boolify expression arguments even if expression type is of kind BOOLEAN_TYPE. (gimplify_boolean_expr): Removed. (gimplify_expr): Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional take care that we keep expression's type. * tree-cfg.c (verify_gimple_assign_binary): Adjust check for type of TRUTH_AND|OR|XOR_EXPR. From-SVN: r173711 --- gcc/ChangeLog | 10 ++++++++ gcc/gimplify.c | 66 ++++++++++++++++++++++++++------------------------ gcc/tree-cfg.c | 8 +++--- 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bb144ef92c..4245ccc4263 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-05-12 Kai Tietz + + * gimplify.c (gimple_boolify): Re-boolify expression + arguments even if expression type is of kind BOOLEAN_TYPE. + (gimplify_boolean_expr): Removed. + (gimplify_expr): Boolify truth opcodes AND, ANDIF, OR, ORIF, + and XOR. Additional take care that we keep expression's type. + * tree-cfg.c (verify_gimple_assign_binary): Adjust check for type + of TRUTH_AND|OR|XOR_EXPR. + 2011-05-12 Jakub Jelinek PR tree-optimization/48975 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 700aa238e69..c54d3b5dcfc 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2824,9 +2824,6 @@ gimple_boolify (tree expr) } } - if (TREE_CODE (type) == BOOLEAN_TYPE) - return expr; - switch (TREE_CODE (expr)) { case TRUTH_AND_EXPR: @@ -2851,6 +2848,8 @@ gimple_boolify (tree expr) default: /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -4695,31 +4694,6 @@ gimplify_scalar_mode_aggregate_compare (tree *expr_p) return GS_OK; } -/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions. EXPR_P - points to the expression to gimplify. - - Expressions of the form 'a && b' are gimplified to: - - a && b ? true : false - - LOCUS is the source location to be put on the generated COND_EXPR. - gimplify_cond_expr will do the rest. */ - -static enum gimplify_status -gimplify_boolean_expr (tree *expr_p, location_t locus) -{ - /* Preserve the original type of the expression. */ - tree type = TREE_TYPE (*expr_p); - - *expr_p = build3 (COND_EXPR, type, *expr_p, - fold_convert_loc (locus, type, boolean_true_node), - fold_convert_loc (locus, type, boolean_false_node)); - - SET_EXPR_LOCATION (*expr_p, locus); - - return GS_OK; -} - /* Gimplify an expression sequence. This function gimplifies each expression and rewrites the original expression with the last expression of the sequence in GIMPLE form. @@ -6762,9 +6736,22 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: - /* Pass the source location of the outer expression. */ - ret = gimplify_boolean_expr (expr_p, saved_location); - break; + { + /* Preserve the original type of the expression and the + source location of the outer expression. */ + tree org_type = TREE_TYPE (*expr_p); + *expr_p = gimple_boolify (*expr_p); + *expr_p = build3_loc (saved_location, COND_EXPR, + org_type, *expr_p, + fold_convert_loc + (saved_location, + org_type, boolean_true_node), + fold_convert_loc + (saved_location, + org_type, boolean_false_node)); + ret = GS_OK; + break; + } case TRUTH_NOT_EXPR: if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE) @@ -7203,6 +7190,23 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: + { + tree org_type = TREE_TYPE (*expr_p); + + *expr_p = gimple_boolify (*expr_p); + + /* This shouldn't happen, but due fold-const (and here especially + fold_truth_not_expr) happily uses operand type and doesn't + automatically uses boolean_type as result, we need to keep + orignal type. */ + if (TREE_CODE (org_type) != BOOLEAN_TYPE) + { + *expr_p = fold_convert (org_type, *expr_p); + ret = GS_OK; + break; + } + } + /* Classified as tcc_expression. */ goto expr_2; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index e1f8707e809..aa73f5ea3a5 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: { - /* We allow any kind of integral typed argument and result. */ - if (!INTEGRAL_TYPE_P (rhs1_type) - || !INTEGRAL_TYPE_P (rhs2_type) - || !INTEGRAL_TYPE_P (lhs_type)) + /* We allow only boolean typed or compatible argument and result. */ + if (!useless_type_conversion_p (boolean_type_node, rhs1_type) + || !useless_type_conversion_p (boolean_type_node, rhs2_type) + || !useless_type_conversion_p (boolean_type_node, lhs_type)) { error ("type mismatch in binary truth expression"); debug_generic_expr (lhs_type); -- 2.30.2