2011/5/16 Richard Guenther <[email protected]>:
> On Mon, May 16, 2011 at 3:45 PM, Michael Matz <[email protected]> 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);