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.  */

Reply via email to