On Wed, May 11, 2011 at 5:46 PM, Kai Tietz <ktiet...@googlemail.com> wrote: > 2011/5/11 Richard Guenther <richard.guent...@gmail.com>: >> The most important thing is to get predicate types sane - that affects >> tcc_comparison codes and the TRUTH_* codes. After that, the TRUTH_* >> codes are redundant with the BIT_* ones which already are always >> validly typed. As fold already converts some TRUTH_* to BIT_* variants >> we usually have a mix of both which is not handled very well by tree >> optimizers. > > Well, to boolify comparisions isn't that hard at all, but I don't see > here much improvement, as it will lead necessarily for uses without > boolean-type always in gimple as '(type) comparison_tcc-ssa', which > seems to me like trying to put the cart before the horse.
Well, it's of course a matter of consistency. > So updated patch inlined (and attached). The type-casting for > TRUTH_ANDIF/ORIF is still necessary (without it I get bootstrap > failures due perfectly working gimple_cond_expr function, which is > producing here happily "iftmp" variables assigning later on wrong > type. Hm, I see ... > Regards, > Kai > > Index: gcc/gcc/gimplify.c > =================================================================== > --- gcc.orig/gcc/gimplify.c 2011-05-11 17:03:24.853377700 +0200 > +++ gcc/gcc/gimplify.c 2011-05-11 17:11:02.018281300 +0200 > @@ -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); > } > } > @@ -6762,6 +6761,21 @@ gimplify_expr (tree *expr_p, gimple_seq > > case TRUTH_ANDIF_EXPR: > case TRUTH_ORIF_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, this happens. */ > + if (TREE_CODE (org_type) != BOOLEAN_TYPE) > + { > + *expr_p = fold_convert (org_type, *expr_p); > + ret = GS_OK; > + break; > + } I suppose it makes sense to be consistent with the other TRUTH_* exprs. But when looking at the further context - we call into gimplify_boolean_expr - the conversion back to the original type is not necessary. So I would prefer to inline gimplify_boolean_expr at this single caller location and simply gimple_boolify (*expr_p) without doing the conversion back. Thus, @@ -6762,9 +6761,22 @@ gimplify_expr (tree *expr_p, gimple_seq 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) and remove the then unused function. Ok with that change if it passes bootstrap and regtest for all languages. Thanks, Richard. > + } > /* Pass the source location of the outer expression. */ > ret = gimplify_boolean_expr (expr_p, saved_location); > break; > @@ -7203,6 +7217,22 @@ gimplify_expr (tree *expr_p, gimple_seq > 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, this happens. */ > + 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; > > Index: gcc/gcc/tree-cfg.c > =================================================================== > --- gcc.orig/gcc/tree-cfg.c 2011-05-11 17:03:24.863377700 +0200 > +++ gcc/gcc/tree-cfg.c 2011-05-11 17:04:32.293292500 +0200 > @@ -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 argument and result. */ > + if (TREE_CODE (rhs1_type) != BOOLEAN_TYPE > + || TREE_CODE (rhs2_type) != BOOLEAN_TYPE > + || TREE_CODE (lhs_type) != BOOLEAN_TYPE) > { > error ("type mismatch in binary truth expression"); > debug_generic_expr (lhs_type); >