diff mbox

[gimplifier] : Boolify more strict conditional expressions and transform simple form to binary

Message ID BANLkTin8jXb8p4Lf_=8LkVzudFTbG7f-6Q@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz May 12, 2011, 1:29 p.m. UTC
While testing some other issues with C++'s __java_boolean type
occurred. So I adjusted check in test-cfg.c as you suggested.
Additionally due the fact that we are now boolifying conditions for
even BOOLEAN_TYPE'ed cases (for making sure inner arms are boolified,
too), we possibly would alter here truth-type provided by FE. To
restore original type (for types != boolean-type), we do type
conversion always back to FE's used type for truth-AND/OR/XOR/etc as
result.

Patch bootstrapped with all languages on x86_64-pc-linux-gnu
(multilib). Ok for apply?

Regards,
Kai
Index: gcc/gcc/gimplify.c
===================================================================
--- gcc.orig/gcc/gimplify.c	2011-05-12 09:02:58.946243000 +0200
+++ gcc/gcc/gimplify.c	2011-05-12 15:13:59.534550700 +0200
@@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
 	}
     }
 
-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-    return expr;
-
   switch (TREE_CODE (expr))
     {
     case TRUTH_AND_EXPR:
@@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
     default:
       /* Other expressions that get here must have boolean values, but
 	 might need to be converted to the appropriate mode.  */
+      if (TREE_CODE (type) == BOOLEAN_TYPE
+          && type == boolean_type_node)
+	return expr;
       return fold_convert_loc (loc, boolean_type_node, expr);
     }
 }
@@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
   return GS_OK;
 }
 
-/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
-   points to the expression to gimplify.
-
-   Expressions of the form 'a && b' are gimplified to:
-
-	a && b ? true : false
-
-   LOCUS is the source location to be put on the generated COND_EXPR.
-   gimplify_cond_expr will do the rest.  */
-
-static enum gimplify_status
-gimplify_boolean_expr (tree *expr_p, location_t locus)
-{
-  /* Preserve the original type of the expression.  */
-  tree type = TREE_TYPE (*expr_p);
-
-  *expr_p = build3 (COND_EXPR, type, *expr_p,
-		    fold_convert_loc (locus, type, boolean_true_node),
-		    fold_convert_loc (locus, type, boolean_false_node));
-
-  SET_EXPR_LOCATION (*expr_p, locus);
-
-  return GS_OK;
-}
-
 /* Gimplify an expression sequence.  This function gimplifies each
    expression and rewrites the original expression with the last
    expression of the sequence in GIMPLE form.
@@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
 
 	case TRUTH_ANDIF_EXPR:
 	case TRUTH_ORIF_EXPR:
-	  /* Pass the source location of the outer expression.  */
-	  ret = gimplify_boolean_expr (expr_p, saved_location);
-	  break;
+	  {
+	    /* Preserve the original type of the expression and the
+	       source location of the outer expression.  */
+	    tree org_type = TREE_TYPE (*expr_p);
+	    *expr_p = gimple_boolify (*expr_p);
+	    *expr_p = build3_loc (saved_location, COND_EXPR,
+				  org_type, *expr_p,
+				  fold_convert_loc
+				    (saved_location,
+				     org_type, boolean_true_node),
+				  fold_convert_loc
+				    (saved_location,
+				     org_type, boolean_false_node));
+	    ret = GS_OK;
+	    break;
+	  }
 
 	case TRUTH_NOT_EXPR:
-	  if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+	  if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
+	      || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
 	    {
 	      tree type = TREE_TYPE (*expr_p);
 	      *expr_p = fold_convert (type, gimple_boolify (*expr_p));
@@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
 	case TRUTH_AND_EXPR:
 	case TRUTH_OR_EXPR:
 	case TRUTH_XOR_EXPR:
+	  {
+	    tree org_type = TREE_TYPE (*expr_p);
+	    
+	    *expr_p = gimple_boolify (*expr_p);
+
+	    /* This shouldn't happen, but due fold-const (and here especially
+	       fold_truth_not_expr) happily uses operand type and doesn't
+	       automatically uses boolean_type as result, we need to keep
+	       orignal type.  */
+	    if (TREE_CODE (org_type) != BOOLEAN_TYPE
+	        || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
+	      {
+		*expr_p = fold_convert (org_type, *expr_p);
+		ret = GS_OK;
+		break;
+	      }
+	  }
+	  
 	  /* Classified as tcc_expression.  */
 	  goto expr_2;
 
Index: gcc/gcc/tree-cfg.c
===================================================================
--- gcc.orig/gcc/tree-cfg.c	2011-05-12 09:02:58.989243000 +0200
+++ gcc/gcc/tree-cfg.c	2011-05-12 14:50:19.656249100 +0200
@@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
       {
-	/* We allow any kind of integral typed argument and result.  */
-	if (!INTEGRAL_TYPE_P (rhs1_type)
-	    || !INTEGRAL_TYPE_P (rhs2_type)
-	    || !INTEGRAL_TYPE_P (lhs_type))
+	/* 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);

Comments

Richard Biener May 12, 2011, 2:18 p.m. UTC | #1
On Thu, May 12, 2011 at 3:29 PM, Kai Tietz <ktietz70@googlemail.com> wrote:
> While testing some other issues with C++'s __java_boolean type
> occurred. So I adjusted check in test-cfg.c as you suggested.
> Additionally due the fact that we are now boolifying conditions for
> even BOOLEAN_TYPE'ed cases (for making sure inner arms are boolified,
> too), we possibly would alter here truth-type provided by FE. To
> restore original type (for types != boolean-type), we do type
> conversion always back to FE's used type for truth-AND/OR/XOR/etc as
> result.

boolean_type_node is the only BOOLEAN_TYPE node we have,
so please remove the !=/== boolean_type_node checks again, or,
if you want more visual consistency with the adjustment gimple_boolify
makes replace them with !=/== boolean_type_node comparisons
completely.

Ok with either change.

Thanks,
Richard.

> Patch bootstrapped with all languages on x86_64-pc-linux-gnu
> (multilib). Ok for apply?
>
> Regards,
> Kai
>
> Index: gcc/gcc/gimplify.c
> ===================================================================
> --- gcc.orig/gcc/gimplify.c     2011-05-12 09:02:58.946243000 +0200
> +++ gcc/gcc/gimplify.c  2011-05-12 15:13:59.534550700 +0200
> @@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
>        }
>     }
>
> -  if (TREE_CODE (type) == BOOLEAN_TYPE)
> -    return expr;
> -
>   switch (TREE_CODE (expr))
>     {
>     case TRUTH_AND_EXPR:
> @@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
>     default:
>       /* Other expressions that get here must have boolean values, but
>         might need to be converted to the appropriate mode.  */
> +      if (TREE_CODE (type) == BOOLEAN_TYPE
> +          && type == boolean_type_node)
> +       return expr;
>       return fold_convert_loc (loc, boolean_type_node, expr);
>     }
>  }
> @@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
>   return GS_OK;
>  }
>
> -/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
> -   points to the expression to gimplify.
> -
> -   Expressions of the form 'a && b' are gimplified to:
> -
> -       a && b ? true : false
> -
> -   LOCUS is the source location to be put on the generated COND_EXPR.
> -   gimplify_cond_expr will do the rest.  */
> -
> -static enum gimplify_status
> -gimplify_boolean_expr (tree *expr_p, location_t locus)
> -{
> -  /* Preserve the original type of the expression.  */
> -  tree type = TREE_TYPE (*expr_p);
> -
> -  *expr_p = build3 (COND_EXPR, type, *expr_p,
> -                   fold_convert_loc (locus, type, boolean_true_node),
> -                   fold_convert_loc (locus, type, boolean_false_node));
> -
> -  SET_EXPR_LOCATION (*expr_p, locus);
> -
> -  return GS_OK;
> -}
> -
>  /* Gimplify an expression sequence.  This function gimplifies each
>    expression and rewrites the original expression with the last
>    expression of the sequence in GIMPLE form.
> @@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
>
>        case TRUTH_ANDIF_EXPR:
>        case TRUTH_ORIF_EXPR:
> -         /* Pass the source location of the outer expression.  */
> -         ret = gimplify_boolean_expr (expr_p, saved_location);
> -         break;
> +         {
> +           /* Preserve the original type of the expression and the
> +              source location of the outer expression.  */
> +           tree org_type = TREE_TYPE (*expr_p);
> +           *expr_p = gimple_boolify (*expr_p);
> +           *expr_p = build3_loc (saved_location, COND_EXPR,
> +                                 org_type, *expr_p,
> +                                 fold_convert_loc
> +                                   (saved_location,
> +                                    org_type, boolean_true_node),
> +                                 fold_convert_loc
> +                                   (saved_location,
> +                                    org_type, boolean_false_node));
> +           ret = GS_OK;
> +           break;
> +         }
>
>        case TRUTH_NOT_EXPR:
> -         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
> +         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
> +             || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
>            {
>              tree type = TREE_TYPE (*expr_p);
>              *expr_p = fold_convert (type, gimple_boolify (*expr_p));
> @@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
>        case TRUTH_AND_EXPR:
>        case TRUTH_OR_EXPR:
>        case TRUTH_XOR_EXPR:
> +         {
> +           tree org_type = TREE_TYPE (*expr_p);
> +
> +           *expr_p = gimple_boolify (*expr_p);
> +
> +           /* This shouldn't happen, but due fold-const (and here especially
> +              fold_truth_not_expr) happily uses operand type and doesn't
> +              automatically uses boolean_type as result, we need to keep
> +              orignal type.  */
> +           if (TREE_CODE (org_type) != BOOLEAN_TYPE
> +               || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
> +             {
> +               *expr_p = fold_convert (org_type, *expr_p);
> +               ret = GS_OK;
> +               break;
> +             }
> +         }
> +
>          /* Classified as tcc_expression.  */
>          goto expr_2;
>
> Index: gcc/gcc/tree-cfg.c
> ===================================================================
> --- gcc.orig/gcc/tree-cfg.c     2011-05-12 09:02:58.989243000 +0200
> +++ gcc/gcc/tree-cfg.c  2011-05-12 14:50:19.656249100 +0200
> @@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
>     case TRUTH_OR_EXPR:
>     case TRUTH_XOR_EXPR:
>       {
> -       /* We allow any kind of integral typed argument and result.  */
> -       if (!INTEGRAL_TYPE_P (rhs1_type)
> -           || !INTEGRAL_TYPE_P (rhs2_type)
> -           || !INTEGRAL_TYPE_P (lhs_type))
> +       /* 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);
>
Kai Tietz May 12, 2011, 6:19 p.m. UTC | #2
2011/5/12 Richard Guenther <richard.guenther@gmail.com>:
> On Thu, May 12, 2011 at 3:29 PM, Kai Tietz <ktietz70@googlemail.com> wrote:
>> While testing some other issues with C++'s __java_boolean type
>> occurred. So I adjusted check in test-cfg.c as you suggested.
>> Additionally due the fact that we are now boolifying conditions for
>> even BOOLEAN_TYPE'ed cases (for making sure inner arms are boolified,
>> too), we possibly would alter here truth-type provided by FE. To
>> restore original type (for types != boolean-type), we do type
>> conversion always back to FE's used type for truth-AND/OR/XOR/etc as
>> result.
>
> boolean_type_node is the only BOOLEAN_TYPE node we have,
> so please remove the !=/== boolean_type_node checks again, or,
> if you want more visual consistency with the adjustment gimple_boolify
> makes replace them with !=/== boolean_type_node comparisons
> completely.
>
> Ok with either change.
>
> Thanks,
> Richard.
>
>> Patch bootstrapped with all languages on x86_64-pc-linux-gnu
>> (multilib). Ok for apply?
>>
>> Regards,
>> Kai
>>
>> Index: gcc/gcc/gimplify.c
>> ===================================================================
>> --- gcc.orig/gcc/gimplify.c     2011-05-12 09:02:58.946243000 +0200
>> +++ gcc/gcc/gimplify.c  2011-05-12 15:13:59.534550700 +0200
>> @@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
>>        }
>>     }
>>
>> -  if (TREE_CODE (type) == BOOLEAN_TYPE)
>> -    return expr;
>> -
>>   switch (TREE_CODE (expr))
>>     {
>>     case TRUTH_AND_EXPR:
>> @@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
>>     default:
>>       /* Other expressions that get here must have boolean values, but
>>         might need to be converted to the appropriate mode.  */
>> +      if (TREE_CODE (type) == BOOLEAN_TYPE
>> +          && type == boolean_type_node)
>> +       return expr;
>>       return fold_convert_loc (loc, boolean_type_node, expr);
>>     }
>>  }
>> @@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
>>   return GS_OK;
>>  }
>>
>> -/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
>> -   points to the expression to gimplify.
>> -
>> -   Expressions of the form 'a && b' are gimplified to:
>> -
>> -       a && b ? true : false
>> -
>> -   LOCUS is the source location to be put on the generated COND_EXPR.
>> -   gimplify_cond_expr will do the rest.  */
>> -
>> -static enum gimplify_status
>> -gimplify_boolean_expr (tree *expr_p, location_t locus)
>> -{
>> -  /* Preserve the original type of the expression.  */
>> -  tree type = TREE_TYPE (*expr_p);
>> -
>> -  *expr_p = build3 (COND_EXPR, type, *expr_p,
>> -                   fold_convert_loc (locus, type, boolean_true_node),
>> -                   fold_convert_loc (locus, type, boolean_false_node));
>> -
>> -  SET_EXPR_LOCATION (*expr_p, locus);
>> -
>> -  return GS_OK;
>> -}
>> -
>>  /* Gimplify an expression sequence.  This function gimplifies each
>>    expression and rewrites the original expression with the last
>>    expression of the sequence in GIMPLE form.
>> @@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
>>
>>        case TRUTH_ANDIF_EXPR:
>>        case TRUTH_ORIF_EXPR:
>> -         /* Pass the source location of the outer expression.  */
>> -         ret = gimplify_boolean_expr (expr_p, saved_location);
>> -         break;
>> +         {
>> +           /* Preserve the original type of the expression and the
>> +              source location of the outer expression.  */
>> +           tree org_type = TREE_TYPE (*expr_p);
>> +           *expr_p = gimple_boolify (*expr_p);
>> +           *expr_p = build3_loc (saved_location, COND_EXPR,
>> +                                 org_type, *expr_p,
>> +                                 fold_convert_loc
>> +                                   (saved_location,
>> +                                    org_type, boolean_true_node),
>> +                                 fold_convert_loc
>> +                                   (saved_location,
>> +                                    org_type, boolean_false_node));
>> +           ret = GS_OK;
>> +           break;
>> +         }
>>
>>        case TRUTH_NOT_EXPR:
>> -         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
>> +         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
>> +             || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
>>            {
>>              tree type = TREE_TYPE (*expr_p);
>>              *expr_p = fold_convert (type, gimple_boolify (*expr_p));
>> @@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
>>        case TRUTH_AND_EXPR:
>>        case TRUTH_OR_EXPR:
>>        case TRUTH_XOR_EXPR:
>> +         {
>> +           tree org_type = TREE_TYPE (*expr_p);
>> +
>> +           *expr_p = gimple_boolify (*expr_p);
>> +
>> +           /* This shouldn't happen, but due fold-const (and here especially
>> +              fold_truth_not_expr) happily uses operand type and doesn't
>> +              automatically uses boolean_type as result, we need to keep
>> +              orignal type.  */
>> +           if (TREE_CODE (org_type) != BOOLEAN_TYPE
>> +               || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
>> +             {
>> +               *expr_p = fold_convert (org_type, *expr_p);
>> +               ret = GS_OK;
>> +               break;
>> +             }
>> +         }
>> +
>>          /* Classified as tcc_expression.  */
>>          goto expr_2;
>>
>> Index: gcc/gcc/tree-cfg.c
>> ===================================================================
>> --- gcc.orig/gcc/tree-cfg.c     2011-05-12 09:02:58.989243000 +0200
>> +++ gcc/gcc/tree-cfg.c  2011-05-12 14:50:19.656249100 +0200
>> @@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
>>     case TRUTH_OR_EXPR:
>>     case TRUTH_XOR_EXPR:
>>       {
>> -       /* We allow any kind of integral typed argument and result.  */
>> -       if (!INTEGRAL_TYPE_P (rhs1_type)
>> -           || !INTEGRAL_TYPE_P (rhs2_type)
>> -           || !INTEGRAL_TYPE_P (lhs_type))
>> +       /* 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);
>>
>

Committed at revision 173711 with removing check for !=/== boolean_type_node.

Thanks,
Kai
H.J. Lu May 12, 2011, 7:59 p.m. UTC | #3
On Thu, May 12, 2011 at 11:19 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
> 2011/5/12 Richard Guenther <richard.guenther@gmail.com>:
>> On Thu, May 12, 2011 at 3:29 PM, Kai Tietz <ktietz70@googlemail.com> wrote:
>>> While testing some other issues with C++'s __java_boolean type
>>> occurred. So I adjusted check in test-cfg.c as you suggested.
>>> Additionally due the fact that we are now boolifying conditions for
>>> even BOOLEAN_TYPE'ed cases (for making sure inner arms are boolified,
>>> too), we possibly would alter here truth-type provided by FE. To
>>> restore original type (for types != boolean-type), we do type
>>> conversion always back to FE's used type for truth-AND/OR/XOR/etc as
>>> result.
>>
>> boolean_type_node is the only BOOLEAN_TYPE node we have,
>> so please remove the !=/== boolean_type_node checks again, or,
>> if you want more visual consistency with the adjustment gimple_boolify
>> makes replace them with !=/== boolean_type_node comparisons
>> completely.
>>
>> Ok with either change.
>>
>> Thanks,
>> Richard.
>>
>>> Patch bootstrapped with all languages on x86_64-pc-linux-gnu
>>> (multilib). Ok for apply?
>>>
>>> Regards,
>>> Kai
>>>
>>> Index: gcc/gcc/gimplify.c
>>> ===================================================================
>>> --- gcc.orig/gcc/gimplify.c     2011-05-12 09:02:58.946243000 +0200
>>> +++ gcc/gcc/gimplify.c  2011-05-12 15:13:59.534550700 +0200
>>> @@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
>>>        }
>>>     }
>>>
>>> -  if (TREE_CODE (type) == BOOLEAN_TYPE)
>>> -    return expr;
>>> -
>>>   switch (TREE_CODE (expr))
>>>     {
>>>     case TRUTH_AND_EXPR:
>>> @@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
>>>     default:
>>>       /* Other expressions that get here must have boolean values, but
>>>         might need to be converted to the appropriate mode.  */
>>> +      if (TREE_CODE (type) == BOOLEAN_TYPE
>>> +          && type == boolean_type_node)
>>> +       return expr;
>>>       return fold_convert_loc (loc, boolean_type_node, expr);
>>>     }
>>>  }
>>> @@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
>>>   return GS_OK;
>>>  }
>>>
>>> -/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
>>> -   points to the expression to gimplify.
>>> -
>>> -   Expressions of the form 'a && b' are gimplified to:
>>> -
>>> -       a && b ? true : false
>>> -
>>> -   LOCUS is the source location to be put on the generated COND_EXPR.
>>> -   gimplify_cond_expr will do the rest.  */
>>> -
>>> -static enum gimplify_status
>>> -gimplify_boolean_expr (tree *expr_p, location_t locus)
>>> -{
>>> -  /* Preserve the original type of the expression.  */
>>> -  tree type = TREE_TYPE (*expr_p);
>>> -
>>> -  *expr_p = build3 (COND_EXPR, type, *expr_p,
>>> -                   fold_convert_loc (locus, type, boolean_true_node),
>>> -                   fold_convert_loc (locus, type, boolean_false_node));
>>> -
>>> -  SET_EXPR_LOCATION (*expr_p, locus);
>>> -
>>> -  return GS_OK;
>>> -}
>>> -
>>>  /* Gimplify an expression sequence.  This function gimplifies each
>>>    expression and rewrites the original expression with the last
>>>    expression of the sequence in GIMPLE form.
>>> @@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
>>>
>>>        case TRUTH_ANDIF_EXPR:
>>>        case TRUTH_ORIF_EXPR:
>>> -         /* Pass the source location of the outer expression.  */
>>> -         ret = gimplify_boolean_expr (expr_p, saved_location);
>>> -         break;
>>> +         {
>>> +           /* Preserve the original type of the expression and the
>>> +              source location of the outer expression.  */
>>> +           tree org_type = TREE_TYPE (*expr_p);
>>> +           *expr_p = gimple_boolify (*expr_p);
>>> +           *expr_p = build3_loc (saved_location, COND_EXPR,
>>> +                                 org_type, *expr_p,
>>> +                                 fold_convert_loc
>>> +                                   (saved_location,
>>> +                                    org_type, boolean_true_node),
>>> +                                 fold_convert_loc
>>> +                                   (saved_location,
>>> +                                    org_type, boolean_false_node));
>>> +           ret = GS_OK;
>>> +           break;
>>> +         }
>>>
>>>        case TRUTH_NOT_EXPR:
>>> -         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
>>> +         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
>>> +             || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
>>>            {
>>>              tree type = TREE_TYPE (*expr_p);
>>>              *expr_p = fold_convert (type, gimple_boolify (*expr_p));
>>> @@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
>>>        case TRUTH_AND_EXPR:
>>>        case TRUTH_OR_EXPR:
>>>        case TRUTH_XOR_EXPR:
>>> +         {
>>> +           tree org_type = TREE_TYPE (*expr_p);
>>> +
>>> +           *expr_p = gimple_boolify (*expr_p);
>>> +
>>> +           /* This shouldn't happen, but due fold-const (and here especially
>>> +              fold_truth_not_expr) happily uses operand type and doesn't
>>> +              automatically uses boolean_type as result, we need to keep
>>> +              orignal type.  */
>>> +           if (TREE_CODE (org_type) != BOOLEAN_TYPE
>>> +               || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
>>> +             {
>>> +               *expr_p = fold_convert (org_type, *expr_p);
>>> +               ret = GS_OK;
>>> +               break;
>>> +             }
>>> +         }
>>> +
>>>          /* Classified as tcc_expression.  */
>>>          goto expr_2;
>>>
>>> Index: gcc/gcc/tree-cfg.c
>>> ===================================================================
>>> --- gcc.orig/gcc/tree-cfg.c     2011-05-12 09:02:58.989243000 +0200
>>> +++ gcc/gcc/tree-cfg.c  2011-05-12 14:50:19.656249100 +0200
>>> @@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
>>>     case TRUTH_OR_EXPR:
>>>     case TRUTH_XOR_EXPR:
>>>       {
>>> -       /* We allow any kind of integral typed argument and result.  */
>>> -       if (!INTEGRAL_TYPE_P (rhs1_type)
>>> -           || !INTEGRAL_TYPE_P (rhs2_type)
>>> -           || !INTEGRAL_TYPE_P (lhs_type))
>>> +       /* 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);
>>>
>>
>
> Committed at revision 173711 with removing check for !=/== boolean_type_node.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48984
Richard Biener May 13, 2011, 9:05 a.m. UTC | #4
On Thu, May 12, 2011 at 9:59 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, May 12, 2011 at 11:19 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
>> 2011/5/12 Richard Guenther <richard.guenther@gmail.com>:
>>> On Thu, May 12, 2011 at 3:29 PM, Kai Tietz <ktietz70@googlemail.com> wrote:
>>>> While testing some other issues with C++'s __java_boolean type
>>>> occurred. So I adjusted check in test-cfg.c as you suggested.
>>>> Additionally due the fact that we are now boolifying conditions for
>>>> even BOOLEAN_TYPE'ed cases (for making sure inner arms are boolified,
>>>> too), we possibly would alter here truth-type provided by FE. To
>>>> restore original type (for types != boolean-type), we do type
>>>> conversion always back to FE's used type for truth-AND/OR/XOR/etc as
>>>> result.
>>>
>>> boolean_type_node is the only BOOLEAN_TYPE node we have,
>>> so please remove the !=/== boolean_type_node checks again, or,
>>> if you want more visual consistency with the adjustment gimple_boolify
>>> makes replace them with !=/== boolean_type_node comparisons
>>> completely.
>>>
>>> Ok with either change.
>>>
>>> Thanks,
>>> Richard.
>>>
>>>> Patch bootstrapped with all languages on x86_64-pc-linux-gnu
>>>> (multilib). Ok for apply?
>>>>
>>>> Regards,
>>>> Kai
>>>>
>>>> Index: gcc/gcc/gimplify.c
>>>> ===================================================================
>>>> --- gcc.orig/gcc/gimplify.c     2011-05-12 09:02:58.946243000 +0200
>>>> +++ gcc/gcc/gimplify.c  2011-05-12 15:13:59.534550700 +0200
>>>> @@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
>>>>        }
>>>>     }
>>>>
>>>> -  if (TREE_CODE (type) == BOOLEAN_TYPE)
>>>> -    return expr;
>>>> -
>>>>   switch (TREE_CODE (expr))
>>>>     {
>>>>     case TRUTH_AND_EXPR:
>>>> @@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
>>>>     default:
>>>>       /* Other expressions that get here must have boolean values, but
>>>>         might need to be converted to the appropriate mode.  */
>>>> +      if (TREE_CODE (type) == BOOLEAN_TYPE
>>>> +          && type == boolean_type_node)
>>>> +       return expr;
>>>>       return fold_convert_loc (loc, boolean_type_node, expr);
>>>>     }
>>>>  }
>>>> @@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
>>>>   return GS_OK;
>>>>  }
>>>>
>>>> -/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
>>>> -   points to the expression to gimplify.
>>>> -
>>>> -   Expressions of the form 'a && b' are gimplified to:
>>>> -
>>>> -       a && b ? true : false
>>>> -
>>>> -   LOCUS is the source location to be put on the generated COND_EXPR.
>>>> -   gimplify_cond_expr will do the rest.  */
>>>> -
>>>> -static enum gimplify_status
>>>> -gimplify_boolean_expr (tree *expr_p, location_t locus)
>>>> -{
>>>> -  /* Preserve the original type of the expression.  */
>>>> -  tree type = TREE_TYPE (*expr_p);
>>>> -
>>>> -  *expr_p = build3 (COND_EXPR, type, *expr_p,
>>>> -                   fold_convert_loc (locus, type, boolean_true_node),
>>>> -                   fold_convert_loc (locus, type, boolean_false_node));
>>>> -
>>>> -  SET_EXPR_LOCATION (*expr_p, locus);
>>>> -
>>>> -  return GS_OK;
>>>> -}
>>>> -
>>>>  /* Gimplify an expression sequence.  This function gimplifies each
>>>>    expression and rewrites the original expression with the last
>>>>    expression of the sequence in GIMPLE form.
>>>> @@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
>>>>
>>>>        case TRUTH_ANDIF_EXPR:
>>>>        case TRUTH_ORIF_EXPR:
>>>> -         /* Pass the source location of the outer expression.  */
>>>> -         ret = gimplify_boolean_expr (expr_p, saved_location);
>>>> -         break;
>>>> +         {
>>>> +           /* Preserve the original type of the expression and the
>>>> +              source location of the outer expression.  */
>>>> +           tree org_type = TREE_TYPE (*expr_p);
>>>> +           *expr_p = gimple_boolify (*expr_p);
>>>> +           *expr_p = build3_loc (saved_location, COND_EXPR,
>>>> +                                 org_type, *expr_p,
>>>> +                                 fold_convert_loc
>>>> +                                   (saved_location,
>>>> +                                    org_type, boolean_true_node),
>>>> +                                 fold_convert_loc
>>>> +                                   (saved_location,
>>>> +                                    org_type, boolean_false_node));
>>>> +           ret = GS_OK;
>>>> +           break;
>>>> +         }
>>>>
>>>>        case TRUTH_NOT_EXPR:
>>>> -         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
>>>> +         if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
>>>> +             || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
>>>>            {
>>>>              tree type = TREE_TYPE (*expr_p);
>>>>              *expr_p = fold_convert (type, gimple_boolify (*expr_p));
>>>> @@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
>>>>        case TRUTH_AND_EXPR:
>>>>        case TRUTH_OR_EXPR:
>>>>        case TRUTH_XOR_EXPR:
>>>> +         {
>>>> +           tree org_type = TREE_TYPE (*expr_p);
>>>> +
>>>> +           *expr_p = gimple_boolify (*expr_p);
>>>> +
>>>> +           /* This shouldn't happen, but due fold-const (and here especially
>>>> +              fold_truth_not_expr) happily uses operand type and doesn't
>>>> +              automatically uses boolean_type as result, we need to keep
>>>> +              orignal type.  */
>>>> +           if (TREE_CODE (org_type) != BOOLEAN_TYPE
>>>> +               || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
>>>> +             {
>>>> +               *expr_p = fold_convert (org_type, *expr_p);
>>>> +               ret = GS_OK;
>>>> +               break;
>>>> +             }
>>>> +         }
>>>> +
>>>>          /* Classified as tcc_expression.  */
>>>>          goto expr_2;
>>>>
>>>> Index: gcc/gcc/tree-cfg.c
>>>> ===================================================================
>>>> --- gcc.orig/gcc/tree-cfg.c     2011-05-12 09:02:58.989243000 +0200
>>>> +++ gcc/gcc/tree-cfg.c  2011-05-12 14:50:19.656249100 +0200
>>>> @@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
>>>>     case TRUTH_OR_EXPR:
>>>>     case TRUTH_XOR_EXPR:
>>>>       {
>>>> -       /* We allow any kind of integral typed argument and result.  */
>>>> -       if (!INTEGRAL_TYPE_P (rhs1_type)
>>>> -           || !INTEGRAL_TYPE_P (rhs2_type)
>>>> -           || !INTEGRAL_TYPE_P (lhs_type))
>>>> +       /* 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);
>>>>
>>>
>>
>> Committed at revision 173711 with removing check for !=/== boolean_type_node.
>>
>
> This caused:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48984

Appearantly a check for boolean_type_node would have been better
then.  It seems the Fortran FE has multiple BOOLEAN_TYPE
types.

Richard.

>
> --
> H.J.
>
diff mbox

Patch

Index: gcc/gcc/gimplify.c
===================================================================
--- gcc.orig/gcc/gimplify.c	2011-05-12 09:02:58.946243000 +0200
+++ gcc/gcc/gimplify.c	2011-05-12 15:13:59.534550700 +0200
@@ -2824,9 +2824,6 @@  gimple_boolify (tree expr)
 	}
     }

-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-    return expr;
-
   switch (TREE_CODE (expr))
     {
     case TRUTH_AND_EXPR:
@@ -2851,6 +2848,9 @@  gimple_boolify (tree expr)
     default:
       /* Other expressions that get here must have boolean values, but
 	 might need to be converted to the appropriate mode.  */
+      if (TREE_CODE (type) == BOOLEAN_TYPE
+          && type == boolean_type_node)
+	return expr;
       return fold_convert_loc (loc, boolean_type_node, expr);
     }
 }
@@ -4695,31 +4695,6 @@  gimplify_scalar_mode_aggregate_compare (
   return GS_OK;
 }

-/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
-   points to the expression to gimplify.
-
-   Expressions of the form 'a && b' are gimplified to:
-
-	a && b ? true : false
-
-   LOCUS is the source location to be put on the generated COND_EXPR.
-   gimplify_cond_expr will do the rest.  */
-
-static enum gimplify_status
-gimplify_boolean_expr (tree *expr_p, location_t locus)
-{
-  /* Preserve the original type of the expression.  */
-  tree type = TREE_TYPE (*expr_p);
-
-  *expr_p = build3 (COND_EXPR, type, *expr_p,
-		    fold_convert_loc (locus, type, boolean_true_node),
-		    fold_convert_loc (locus, type, boolean_false_node));
-
-  SET_EXPR_LOCATION (*expr_p, locus);
-
-  return GS_OK;
-}
-
 /* Gimplify an expression sequence.  This function gimplifies each
    expression and rewrites the original expression with the last
    expression of the sequence in GIMPLE form.
@@ -6762,12 +6737,26 @@  gimplify_expr (tree *expr_p, gimple_seq

 	case TRUTH_ANDIF_EXPR:
 	case TRUTH_ORIF_EXPR:
-	  /* Pass the source location of the outer expression.  */
-	  ret = gimplify_boolean_expr (expr_p, saved_location);
-	  break;
+	  {
+	    /* Preserve the original type of the expression and the
+	       source location of the outer expression.  */
+	    tree org_type = TREE_TYPE (*expr_p);
+	    *expr_p = gimple_boolify (*expr_p);
+	    *expr_p = build3_loc (saved_location, COND_EXPR,
+				  org_type, *expr_p,
+				  fold_convert_loc
+				    (saved_location,
+				     org_type, boolean_true_node),
+				  fold_convert_loc
+				    (saved_location,
+				     org_type, boolean_false_node));
+	    ret = GS_OK;
+	    break;
+	  }

 	case TRUTH_NOT_EXPR:
-	  if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+	  if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
+	      || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
 	    {
 	      tree type = TREE_TYPE (*expr_p);
 	      *expr_p = fold_convert (type, gimple_boolify (*expr_p));
@@ -7203,6 +7192,24 @@  gimplify_expr (tree *expr_p, gimple_seq
 	case TRUTH_AND_EXPR:
 	case TRUTH_OR_EXPR:
 	case TRUTH_XOR_EXPR:
+	  {
+	    tree org_type = TREE_TYPE (*expr_p);
+	
+	    *expr_p = gimple_boolify (*expr_p);
+
+	    /* This shouldn't happen, but due fold-const (and here especially
+	       fold_truth_not_expr) happily uses operand type and doesn't
+	       automatically uses boolean_type as result, we need to keep
+	       orignal type.  */
+	    if (TREE_CODE (org_type) != BOOLEAN_TYPE
+	        || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
+	      {
+		*expr_p = fold_convert (org_type, *expr_p);
+		ret = GS_OK;
+		break;
+	      }
+	  }
+	
 	  /* Classified as tcc_expression.  */
 	  goto expr_2;

Index: gcc/gcc/tree-cfg.c
===================================================================
--- gcc.orig/gcc/tree-cfg.c	2011-05-12 09:02:58.989243000 +0200
+++ gcc/gcc/tree-cfg.c	2011-05-12 14:50:19.656249100 +0200
@@ -3541,10 +3541,10 @@  do_pointer_plus_expr_check:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
       {
-	/* We allow any kind of integral typed argument and result.  */
-	if (!INTEGRAL_TYPE_P (rhs1_type)
-	    || !INTEGRAL_TYPE_P (rhs2_type)
-	    || !INTEGRAL_TYPE_P (lhs_type))
+	/* 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);