This fixes the TRUTH_*_EXPR verification issues by making sure we preserve conversions to BOOLEAN_TYPE where that carries useful semantics - when the type has a TYPE_PRECISION other than 1. The point of the TRUTH_*_EXPR operand sanitization was to make sure we have two-valued types for their operands.
Bootstrapped and tested on x86_64-unknown-linux-gnu. I also verified that SPEC2k6 builds the fortran parts again with LTO. Richard. 2011-05-18 Richard Guenther <rguent...@suse.de> PR middle-end/48989 * tree-cfg.c (verify_gimple_assign_unary): Adjust TRUTH op operand verification. (verify_gimple_assign_binary): Likewise. * tree-ssa.c (useless_type_conversion_p): Preserve conversions to non-1-precision BOOLEAN_TYPEs. Index: gcc/tree-cfg.c =================================================================== *** gcc/tree-cfg.c (revision 173831) --- gcc/tree-cfg.c (working copy) *************** verify_gimple_assign_unary (gimple stmt) *** 3350,3361 **** return false; case TRUTH_NOT_EXPR: ! if (!useless_type_conversion_p (boolean_type_node, rhs1_type)) { ! error ("invalid types in truth not"); ! debug_generic_expr (lhs_type); ! debug_generic_expr (rhs1_type); ! return true; } break; --- 3350,3364 ---- return false; case TRUTH_NOT_EXPR: ! /* We require two-valued operand types. */ ! if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE ! || (INTEGRAL_TYPE_P (rhs1_type) ! && TYPE_PRECISION (rhs1_type) == 1))) { ! error ("invalid types in truth not"); ! debug_generic_expr (lhs_type); ! debug_generic_expr (rhs1_type); ! return true; } break; *************** do_pointer_plus_expr_check: *** 3558,3567 **** 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)) { error ("type mismatch in binary truth expression"); debug_generic_expr (lhs_type); --- 3561,3573 ---- case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: { ! /* We require two-valued operand types. */ ! if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE ! || (INTEGRAL_TYPE_P (rhs1_type) ! && TYPE_PRECISION (rhs1_type) == 1)) ! || !(TREE_CODE (rhs2_type) == BOOLEAN_TYPE ! || (INTEGRAL_TYPE_P (rhs2_type) ! && TYPE_PRECISION (rhs2_type) == 1))) { error ("type mismatch in binary truth expression"); debug_generic_expr (lhs_type); *************** do_pointer_plus_expr_check: *** 3570,3576 **** return true; } ! return false; } case LT_EXPR: --- 3576,3582 ---- return true; } ! break; } case LT_EXPR: Index: gcc/tree-ssa.c =================================================================== *** gcc/tree-ssa.c (revision 173831) --- gcc/tree-ssa.c (working copy) *************** useless_type_conversion_p (tree outer_ty *** 1306,1311 **** --- 1306,1318 ---- || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) return false; + /* Preserve conversions to BOOLEAN_TYPE if it is not of precision + one. */ + if (TREE_CODE (inner_type) != BOOLEAN_TYPE + && TREE_CODE (outer_type) == BOOLEAN_TYPE + && TYPE_PRECISION (outer_type) != 1) + return false; + /* We don't need to preserve changes in the types minimum or maximum value in general as these do not generate code unless the types precisions are different. */