2011/5/16 Richard Guenther <richard.guent...@gmail.com>: > On Mon, May 16, 2011 at 3:45 PM, Michael Matz <m...@suse.de> wrote: >> Hi, >> >> On Mon, 16 May 2011, Richard Guenther wrote: >> >>> > I think conversion _to_ BOOLEAN_TYPE shouldn't be useless, on the >>> > grounds that it requires booleanization (at least conceptually), i.e. >>> > conversion to a set of two values (no matter the precision or size) >>> > based on the outcome of comparing the RHS value with >>> > false_pre_image(TREE_TYPE(RHS)). >>> > >>> > Conversion _from_ BOOLEAN_TYPE can be regarded as useless, as the >>> > conversions from false or true into false_pre_image or true_pre_image >>> > always is simply an embedding of 0 or 1/-1 (depending on target type >>> > signedness). And if the BOOLEAN_TYPE and the LHS have same signedness >>> > the bit representation of boolean_true_type is (or should be) the same >>> > as the one converted to LHS (namely either 1 or -1). >>> >>> Sure, that would probably be enough to prevent non-BOOLEAN_TYPEs be used >>> where BOOLEAN_TYPE nodes were used before. It still will cause an >>> artificial conversion from a single-bit bitfield read to a bool. >> >> Not if you're special casing single-bit conversions (on the grounds that a >> booleanization from two-valued set to a different two-valued set of >> the same signedness will not actually require a comparison). I think it's >> better to be very precise in our base predicates than to add various hacks >> over the place to care for imprecision. > > Or require a 1-bit integral type for TRUTH_* operands only (which ensures > the two-valueness which is what we really want). That can be done > by either fixing the frontends to make boolean_type_node have 1-bit > precision or to build a middle-end private type with that constraints > (though that's the more difficult route as we still do not have a strong > FE - middle-end hand-off point, and it certainly is not the gimplifier). > > Long term all the global trees should be FE private and the middle-end > should have its own set. > > Richard. > >> >> Ciao, >> Michael. >
Hello, initial idea was to check for logical operations that the conversion to boolean_type_node is useless. This assumption was flawed by the fact that boolean_type_node gets re-defined in free_lang_decl to a 1-bit precision BOOL_TYPE_SIZE-ed type, if FE's boolean_type_node is incompatible to this. By this FE's boolean_type_node gets via the back-door incompatible in tree-cfg checks. So for all languages - but ADA - logical types have precision set to one. Just for ADA case, which requires a different boolean_type_node kind, we need to inspect the inner type to be a boolean. As Fortran has also integer typed boolean compatible types, we can't simply check for BOOLEAN_TYPE here and need to check for precision first. ChangeLog 2011-05-18 Kai Tietz PR middle-end/48989 * tree-cfg.c (verify_gimple_assign_binary): Check lhs type for being compatible to boolean for logical operations. (verify_gimple_assign_unary): Likewise. (compatible_boolean_type_p): New helper. Bootstrapped on x86_64-pc-linux-gnu. And regression tested for ADA and Fortran. Ok for apply? Regards, Kai
Index: gcc/gcc/tree-cfg.c =================================================================== --- gcc.orig/gcc/tree-cfg.c 2011-05-16 14:26:12.369031500 +0200 +++ gcc/gcc/tree-cfg.c 2011-05-18 08:20:34.935819100 +0200 @@ -3220,6 +3220,31 @@ verify_gimple_comparison (tree type, tre return false; } +/* Checks TYPE for being compatible to boolean. Returns + FALSE, if type is not compatible, otherwise TRUE. + + A type is compatible if + a) TYPE_PRECISION is one. + b) The type - or the inner type - is of kind BOOLEAN_TYPE. */ + +static bool +compatible_boolean_type_p (tree type) +{ + if (!type) + return false; + if (TYPE_PRECISION (type) == 1) + return true; + + /* We try to look here into inner type, as ADA uses + boolean_type_node with type precision != 1. */ + while (TREE_TYPE (type) + && (TREE_CODE (type) == INTEGER_TYPE + || TREE_CODE (type) == REAL_TYPE)) + type = TREE_TYPE (type); + + return TYPE_PRECISION (type) == 1 || TREE_CODE (type) == BOOLEAN_TYPE; +} + /* Verify a gimple assignment statement STMT with an unary rhs. Returns true if anything is wrong. */ @@ -3350,15 +3375,16 @@ verify_gimple_assign_unary (gimple stmt) return false; case TRUTH_NOT_EXPR: - if (!useless_type_conversion_p (boolean_type_node, rhs1_type)) + + if (!useless_type_conversion_p (lhs_type, rhs1_type) + || !compatible_boolean_type_p (lhs_type)) { - error ("invalid types in truth not"); - debug_generic_expr (lhs_type); - debug_generic_expr (rhs1_type); - return true; + error ("invalid types in truth not"); + debug_generic_expr (lhs_type); + debug_generic_expr (rhs1_type); + return true; } break; - case NEGATE_EXPR: case ABS_EXPR: case BIT_NOT_EXPR: @@ -3558,10 +3584,11 @@ do_pointer_plus_expr_check: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: { - /* 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)) + /* We allow only boolean_typed or types with precision of one, + or compatible argument and result. */ + if (!useless_type_conversion_p (lhs_type, rhs1_type) + || !useless_type_conversion_p (lhs_type, rhs2_type) + || !compatible_boolean_type_p (lhs_type)) { error ("type mismatch in binary truth expression"); debug_generic_expr (lhs_type);