On Thu, May 26, 2011 at 1:20 PM, Kai Tietz <ktiet...@googlemail.com> wrote: > 2011/5/26 Richard Guenther <richard.guent...@gmail.com>: >> On Thu, May 26, 2011 at 1:11 PM, Kai Tietz <ktiet...@googlemail.com> wrote: >>> 2011/5/26 Richard Guenther <richard.guent...@gmail.com>: >>>> On Thu, May 26, 2011 at 12:46 PM, Richard Guenther >>>> <richard.guent...@gmail.com> wrote: >>>>> On Thu, May 26, 2011 at 12:20 PM, Kai Tietz <kti...@redhat.com> wrote: >>>>>> Hello, >>>>>> >>>>>> this patch ensures that after gimplification also comparison expressions >>>>>> using FE's boolean_type_node. As we need to deal here with C/C++'s >>>>>> (obj-c/c++ and java's), Ada's, and Fortran's specific boolean types, >>>>>> this patch alters some checks in tree-cfg for Ada's sake, and we need to >>>>>> deal in fold-const about type-conversion of comparisons special. >>>>>> Additionally it takes care that in forwprop pass we don't do type >>>>>> hoising for boolean types. >>>>>> >>>>>> ChangeLog >>>>>> >>>>>> 2011-05-26 Kai Tietz >>>>>> >>>>>> * gimplify.c (gimple_boolify): Boolify all comparison >>>>>> expressions. >>>>>> (gimplify_expr): Use 'useless_type_conversion_p' for comparing >>>>>> org_type with boolean_type_node for TRUTH-expressions and >>>>>> comparisons. >>>>>> * fold-const.c (fold_unary_loc): Handle comparison conversions >>>>>> with >>>>>> boolean-type special. >>>>>> * tree-cfg.c (verify_gimple_comparison): Adjust check for >>>>>> boolean >>>>>> or compatible types. >>>>>> (verify_gimple_assign_unary): Likewise. >>>>>> * tree-ssa-forwprop.c (forward_propagate_comparison): Handle >>>>>> boolean case special. >>>>>> >>>>>> Tested on x86_64-pc-linux-gnu (multilib) with regression test for all >>>>>> standard languages (C, C++, Obj-C, Fortran, Java) plus Obj-C++ and Ada. >>>>>> Ok for apply? >>>>> >>>>> It obviously isn't ok to apply before a patch has gone in that will >>>>> resolve >>>>> all of the FAILs you specify. Comments on the patch: >>>>> >>>>> @@ -7281,9 +7284,28 @@ gimplify_expr (tree *expr_p, gimple_seq >>>>> plain wrong if bitfields are involved. */ >>>>> { >>>>> tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1)); >>>>> + tree org_type = TREE_TYPE (*expr_p); >>>>> + >>>>> + if (!useless_type_conversion_p (org_type, >>>>> boolean_type_node)) >>>>> + { >>>>> + TREE_TYPE (*expr_p) = boolean_type_node; >>>>> + *expr_p = fold_convert_loc (saved_location, >>>>> org_type, *expr_p); >>>>> + ret = GS_OK; >>>>> + goto dont_recalculate; >>>>> + } >>>>> >>>>> The above should be only done for !AGGREGATE_TYPE_P. Probably then >>>>> the strange dont_recalcuate goto can go away as well. >>>>> >>>>> if (!AGGREGATE_TYPE_P (type)) >>>>> - goto expr_2; >>>>> + { >>>>> + enum gimplify_status r0, r1; >>>>> + >>>>> + r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), >>>>> pre_p, >>>>> + post_p, is_gimple_val, >>>>> fb_rvalue); >>>>> + r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), >>>>> pre_p, >>>>> + post_p, is_gimple_val, >>>>> fb_rvalue); >>>>> + >>>>> + ret = MIN (r0, r1); >>>>> + } >>>>> + >>>>> >>>>> why change this? >>>>> >>>>> @@ -7641,6 +7641,12 @@ fold_unary_loc (location_t loc, enum tre >>>>> } >>>>> else if (COMPARISON_CLASS_P (arg0)) >>>>> { >>>>> + /* Don't optimize type change, if op0 is of kind >>>>> boolean_type_node. >>>>> + Otherwise this will lead to race-condition on gimplification >>>>> + trying to boolify comparison expression. */ >>>>> + if (TREE_TYPE (op0) == boolean_type_node) >>>>> + return NULL_TREE; >>>>> + >>>>> if (TREE_CODE (type) == BOOLEAN_TYPE) >>>>> { >>>>> arg0 = copy_node (arg0); >>>>> >>>>> The code leading here looks quite strange to me ... >>>>> >>>>> tree >>>>> fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) >>>>> { >>>>> ... >>>>> if (TREE_CODE_CLASS (code) == tcc_unary) >>>>> { >>>>> ... >>>>> else if (COMPARISON_CLASS_P (arg0)) >>>>> { >>>>> if (TREE_CODE (type) == BOOLEAN_TYPE) >>>>> { >>>>> arg0 = copy_node (arg0); >>>>> TREE_TYPE (arg0) = type; >>>>> return arg0; >>>>> } >>>>> else if (TREE_CODE (type) != INTEGER_TYPE) >>>>> return fold_build3_loc (loc, COND_EXPR, type, arg0, >>>>> fold_build1_loc (loc, code, type, >>>>> integer_one_node), >>>>> fold_build1_loc (loc, code, type, >>>>> integer_zero_node)); >>>>> } >>>>> >>>>> so, for any tcc_unary, like NEGATE_EXPR, with BOOLEAN_TYPE, >>>>> return arg0 ... sure. Same for the 2nd case. ~ (a == b) isn't >>>>> the same as a == b ? ~1 : ~0. I _suppose_ those cases were >>>>> ment for CONVERT_EXPR_CODE_P (code) instead of all of tcc_unary, >>>>> in which case they should be dropped or moved below where we >>>>> handle conversions explicitly. >>>>> >>>>> That said - does anyone remember anything about that above code? >>>>> Trying to do some svn blame history tracking now ... >>>> >>>> Oh, the patch continues... >>>> >>>> @@ -3208,7 +3208,10 @@ verify_gimple_comparison (tree type, tre >>>> && (!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 >>>> + || (TREE_TYPE (type) && TREE_CODE (type) == INTEGER_TYPE >>>> + && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE) >>>> + || (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1))) >>>> { >>>> >>>> why that strange TREE_TYPE (TREE_TYPE ())) thing again? Drop >>>> that. >>>> >>>> @@ -3352,6 +3355,8 @@ verify_gimple_assign_unary (gimple stmt) >>>> case TRUTH_NOT_EXPR: >>>> /* We require two-valued operand types. */ >>>> if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE >>>> + || (TREE_TYPE (rhs1_type) && TREE_CODE (rhs1_type) == >>>> INTEGER_TYPE >>>> + && TREE_CODE (TREE_TYPE (rhs1_type)) == BOOLEAN_TYPE) >>>> || (INTEGRAL_TYPE_P (rhs1_type) >>>> && TYPE_PRECISION (rhs1_type) == 1))) >>>> { >>>> >>>> likewise. >>> >>> Well, those checks are necessary for Ada and its crippled >>> boolean_type_node and computed boolean-based integer construct. Ada >>> derives here the boolean-type to an integer with range 0..1 and the >>> only way to find out that it is in fact such a beast is by looking >>> into TREE_TYPE of type. See here Ada's code for getting base-type >>> information. >>> As such things are treated as compatible they can appear for TRUTH_NOT >>> expressions and comparisons. >> >> No they can't as we boolify them. >> >> Richard. > > Well, they do. Test can prove this by running fortran's dg tests. > > The logic we do in gimplification is: > > 1) save original type of expression. > 2) set expression's type to boolean_type_node. > 3) if conversion from boolean_type_node to saved type isn't useless > (and here we have the issue about Fortran's different booleans with > different modes, which make those kinds not useless) then cast > expression's result to original type and retry gimplification. > 4) Otherwise gimplify operands and continue.
You don't make sense. Btw, >>>> + if (!useless_type_conversion_p (org_type, >>>> boolean_type_node)) >>>> + { >>>> + TREE_TYPE (*expr_p) = boolean_type_node; >>>> + *expr_p = fold_convert_loc (saved_location, org_type, is bogus it should be TREE_TYPE (*expr_p) = boolean_type_node; if (!useless_type_conversion_p (org_type, boolean_type_node)) { *expr_p = fold_convert_loc (saved_location, org_type, ... > Regards, > Kai > > Kai >