diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c004870d5950c9f64fd3dc6f11a162f1a7667191..9ebf4aad20484902b00b725c9457d88e35068c5e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2011-05-18  Richard Guenther  <rguenther@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.
+
 2011-05-18  Tom de Vries  <tom@codesourcery.com>
 
 	PR target/45098
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 9e74f587f9e9888c8c439c451239a5581f1bcdf8..957f1f1238c32926c13f390bb30001071f3cf9a5 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3350,12 +3350,15 @@ verify_gimple_assign_unary (gimple stmt)
       return false;
 
     case TRUTH_NOT_EXPR:
-      if (!useless_type_conversion_p (boolean_type_node,  rhs1_type))
+      /* 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;
+	  error ("invalid types in truth not");
+	  debug_generic_expr (lhs_type);
+	  debug_generic_expr (rhs1_type);
+	  return true;
         }
       break;
 
@@ -3558,10 +3561,13 @@ 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 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);
@@ -3570,7 +3576,7 @@ do_pointer_plus_expr_check:
 	    return true;
 	  }
 
-	return false;
+	break;
       }
 
     case LT_EXPR:
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index ba5a20b6e476d27aa7ff36d274a5c05ad4e4e4eb..f0bbf3b9823fa6be4f2a03da856c97c31c866884 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1306,6 +1306,13 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
 	  || 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.  */