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

2011-05-13 Thread Richard Guenther
On Thu, May 12, 2011 at 9:59 PM, H.J. Lu hjl.to...@gmail.com wrote:
 On Thu, May 12, 2011 at 11:19 AM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/12 Richard Guenther richard.guent...@gmail.com:
 On Thu, May 12, 2011 at 3:29 PM, Kai Tietz ktiet...@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 

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

2011-05-12 Thread Richard Guenther
On Wed, May 11, 2011 at 5:46 PM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/11 Richard Guenther richard.guent...@gmail.com:
 The most important thing is to get predicate types sane - that affects
 tcc_comparison codes and the TRUTH_* codes.  After that, the TRUTH_*
 codes are redundant with the BIT_* ones which already are always
 validly typed.  As fold already converts some TRUTH_* to BIT_* variants
 we usually have a mix of both which is not handled very well by tree
 optimizers.

 Well, to boolify comparisions isn't that hard at all, but I don't see
 here much improvement, as it will lead necessarily for uses without
 boolean-type always in gimple as '(type) comparison_tcc-ssa', which
 seems to me like trying to put the cart before the horse.

Well, it's of course a matter of consistency.

 So updated patch inlined (and attached).  The type-casting for
 TRUTH_ANDIF/ORIF is still necessary (without it I get bootstrap
 failures due perfectly working gimple_cond_expr function, which is
 producing here happily iftmp variables assigning later on wrong
 type.

Hm, I see ...

 Regards,
 Kai

 Index: gcc/gcc/gimplify.c
 ===
 --- gcc.orig/gcc/gimplify.c     2011-05-11 17:03:24.853377700 +0200
 +++ gcc/gcc/gimplify.c  2011-05-11 17:11:02.018281300 +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,8 @@ 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)
 +       return expr;
       return fold_convert_loc (loc, boolean_type_node, expr);
     }
  }
 @@ -6762,6 +6761,21 @@ gimplify_expr (tree *expr_p, gimple_seq

        case TRUTH_ANDIF_EXPR:
        case TRUTH_ORIF_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, this happens.  */
 +           if (TREE_CODE (org_type) != BOOLEAN_TYPE)
 +             {
 +               *expr_p = fold_convert (org_type, *expr_p);
 +               ret = GS_OK;
 +               break;
 +             }

I suppose it makes sense to be consistent with the other TRUTH_*
exprs.  But when looking at the further context - we call into
gimplify_boolean_expr - the conversion back to the original type
is not necessary.  So I would prefer to inline gimplify_boolean_expr
at this single caller location and simply gimple_boolify (*expr_p)
without doing the conversion back.  Thus,

@@ -6762,9 +6761,22 @@ 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)

and remove the then unused function.

Ok with that change if it passes bootstrap and regtest for all languages.

Thanks,
Richard.

 +         }
          /* Pass the source location of the outer expression.  */
          ret = gimplify_boolean_expr (expr_p, saved_location);
          break;
 @@ -7203,6 +7217,22 @@ 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, this happens.  */
 +           if (TREE_CODE (org_type) != BOOLEAN_TYPE)
 +             {
 +               *expr_p = fold_convert (org_type, *expr_p);
 +               ret = 

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

2011-05-12 Thread Kai Tietz
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:
   {
-   

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

2011-05-12 Thread Richard Guenther
On Thu, May 12, 2011 at 3:29 PM, Kai Tietz ktiet...@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;
 +        

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

2011-05-12 Thread Kai Tietz
2011/5/12 Richard Guenther richard.guent...@gmail.com:
 On Thu, May 12, 2011 at 3:29 PM, Kai Tietz ktiet...@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 = 

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

2011-05-12 Thread H.J. Lu
On Thu, May 12, 2011 at 11:19 AM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/12 Richard Guenther richard.guent...@gmail.com:
 On Thu, May 12, 2011 at 3:29 PM, Kai Tietz ktiet...@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 

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

2011-05-11 Thread Richard Guenther
On Tue, May 10, 2011 at 9:26 PM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/10 Kai Tietz ktiet...@googlemail.com:
 2011/5/10 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote:
 On 05/10/2011 05:23 PM, Richard Guenther wrote:

 I suppose you have testcases for all the cases you looked at, please
 add some that cover these corner cases.

 Also, there is quite some tree-vrp.c dead code with these changes. Removing
 the TRUTH_*_CODE handling in VRP will help finding more places where the
 middle-end is building boolean operations.  There should be testcases
 covering these parts of VRP.

 Btw, you can split the patch into two pieces - first, make TRUTH_*
 expressions correctly typed (take boolean typed operands and procude
 a boolean typed result) and verify that in verify_gimple_assign_binary.
 A second patch than can do the s/TRUTH_/BIT_/ substitution during
 gimplification.  That way the first (and more difficult) part doesn't get
 too big with unrelated changes.

 Richard.

 Paolo



 Well, I think I found one big issue here about booified expression of
 condition. The gimple_boolify needs to handle COND_EXPR in more
 detail. As if a conditional expression has to be boolified, it means
 its condition and its other operands need to be boolified, too. And
 this is for sure one cause, why I see for ANDIF/ORIF and the truth
 AND|OR|XOR none boolean types.

 I will continue on that.

 To split this seems to make sense, as I have to touch much more areas
 for the TRUTH to BIT conversion.

 Regards,
 Kai


 So I use this thread for first part of the series of patches. This one
 improves boolean type-logic
 during gimplification.
 To gimple_boolify the handling for COND_EXPR are added, and in general
 it is tried to do
 boolean operation just on boolean type.  As sadly fold-const (and here
 in special fold_truth_not_expr (), which doesn't provide by default
 boolean type and uses instead operand-type, which is IMHO a major flaw
 here.  But well, there are some comments indicating that this behavior
 is required due some other quirks. But this is for sure something to
 be cleaned up) produces truth operations with wrong type, which are in
 calculations not necessarily identifyable as truth ops anymore, this
 patch makes sure that for truth AND|OR|XOR original type remains.

 2011-05-10  Kai Tietz

        * gimplify.c (gimple_boolify): Handle COND_EXPR
        and make sure that even if type is BOOLEAN for
        TRUTH-opcodes the operands getting boolified.
        (gimplify_expr): Boolify operand condition for
        COND_EXPR.
        Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional
        take care that we keep expression's type.

 Ok for apply?

Posting patches inline makes it easier to put in review comments, so
please consider doing that.


Index: gcc/gcc/gimplify.c
===
--- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200
+++ gcc/gcc/gimplify.c  2011-05-10 21:14:49.106340400 +0200
@@ -2824,11 +2824,20 @@ gimple_boolify (tree expr)
}
 }

-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-return expr;
-
   switch (TREE_CODE (expr))
 {
+case COND_EXPR:
+  /* If we have a conditional expression, which shall be
+ boolean, take care we boolify also their left and right arm.  */
+  if (TREE_OPERAND (expr, 2) != NULL_TREE  !VOID_TYPE_P
(TREE_TYPE (TREE_OPERAND (expr, 2
+TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2));
+  if (TREE_OPERAND (expr, 1) != NULL_TREE  !VOID_TYPE_P
(TREE_TYPE (TREE_OPERAND (expr, 1
+TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
+  TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+   return expr;
+  return fold_convert_loc (loc, boolean_type_node, expr);
+

That looks like premature optimization.  Why isn't it enough to
fold-convert the COND_EXPR itself?  Thus, I don't see why the
existing gimple_boolify isn't enough.

 case TRUTH_AND_EXPR:
 case TRUTH_OR_EXPR:
 case TRUTH_XOR_EXPR:
@@ -2851,6 +2860,8 @@ 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)
+   return expr;
   return fold_convert_loc (loc, boolean_type_node, expr);
 }
 }
@@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p, gimple_seq
  break;

case COND_EXPR:
+ TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 
0));
  ret = gimplify_cond_expr (expr_p, pre_p, fallback);

This boolification should be done by gimplify_cond_expr as I said
in the previous review.  It does already handle this perfectly fine.

  /* C99 code may assign to an array in a 

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

2011-05-11 Thread Kai Tietz
Hi,

By investigating the conditional expression handling I found some
causes, why TRUTH operations AND, ANDIF, OR, XOR, and ORIF are
appearing withing conditional folding during gimplification.
The reason for this can be that the truth expression is simply used as
result of an assignment or return statement, which then leads to the
issue that expression has lhs type.  By this reason it is still
necessary to have in TRUTH operations type-cast after boolifying it
for later operation, if type isn't of kind boolean.  Therefore it is
necessary for conditional to check if their arms might be TRUTH
results and therefore doing boolification of the arms, too.

2011-05-11  Kai Tietz

* gimplify.c (gimple_boolify): Handle COND_EXPR
and make sure that even if type is BOOLEAN for
TRUTH-opcodes the operands getting boolified.
(gimple_has_cond_boolean_arms): Helper function to
detect if condition is a TRUTH operation in arms.
(gimple_is_truth_op): Checks if operand is of BOOLEAN
kind.
(gimplify_expr): Boolify operand condition for
COND_EXPR and try to see if condition might be an TRUTH operation.
Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional
take care that we keep expression's type.

Tested on x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply?

Regards,
Kai
Index: gcc/gcc/gimplify.c
===
--- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200
+++ gcc/gcc/gimplify.c  2011-05-11 10:20:30.413964700 +0200
@@ -102,6 +102,7 @@ typedef struct gimple_temp_hash_elt
 
 /* Forward declaration.  */
 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, 
bool);
+static bool gimple_has_cond_boolean_arms (tree);
 
 /* Mark X addressable.  Unlike the langhook we expect X to be in gimple
form and we don't do any syntax checking.  */
@@ -2824,11 +2825,26 @@ gimple_boolify (tree expr)
}
 }
 
-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-return expr;
-
   switch (TREE_CODE (expr))
 {
+case COND_EXPR:
+  /* If we have a conditional expression, which shall be
+ boolean, take care we boolify also their left and right arm.  */
+  if (TREE_OPERAND (expr, 2) != NULL_TREE  !VOID_TYPE_P (TREE_TYPE 
(TREE_OPERAND (expr, 2
+TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2));
+  if (TREE_OPERAND (expr, 1) != NULL_TREE  !VOID_TYPE_P (TREE_TYPE 
(TREE_OPERAND (expr, 1
+TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
+  TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+   return expr;
+  if (!VOID_TYPE_P (TREE_TYPE (expr)))
+{
+ /* These expressions always produce boolean results.  */
+ TREE_TYPE (expr) = boolean_type_node;
+   }
+  else
+return fold_convert_loc (loc, boolean_type_node, expr);
+
 case TRUTH_AND_EXPR:
 case TRUTH_OR_EXPR:
 case TRUTH_XOR_EXPR:
@@ -2851,6 +2867,8 @@ 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)
+   return expr;
   return fold_convert_loc (loc, boolean_type_node, expr);
 }
 }
@@ -2909,6 +2927,66 @@ generic_expr_could_trap_p (tree expr)
   return false;
 }
 
+/* This function checks if OP is of TRUTH kind expression. It special-case
+   COND_EXPR, as here we need to look on results, too. See function
+   gimple_has_cond_boolean_arms () for more details.
+   If OP is of possible kind TRUTH expression, TRUE is returned,
+   otherwise FALSE is returned.
+   This functions assumes that all TRUTH operations, COND_EXPR with
+   boolean arms, INTEGER_CST with value of one or zero, and any
+   comparision has boolean result. */
+
+static bool
+gimple_is_truth_op (tree op)
+{
+  if (VOID_TYPE_P (TREE_TYPE (op)))
+return false;
+  if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE)
+return true;
+  switch (TREE_CODE (op))
+{
+case TRUTH_AND_EXPR:
+case TRUTH_OR_EXPR:
+case TRUTH_XOR_EXPR:
+case TRUTH_ANDIF_EXPR:
+case TRUTH_ORIF_EXPR:
+case TRUTH_NOT_EXPR:
+  return true;
+case COND_EXPR:
+   return gimple_has_cond_boolean_arms (op);
+case INTEGER_CST:
+   if (integer_zerop (op) || integer_onep (op))
+ return true;
+   return false;
+default:
+   if (TREE_CODE_CLASS (TREE_CODE (op)) == tcc_comparison)
+ return true;
+   break;
+}
+  return false;
+}
+
+/* This function checks if all arms of the condition expression EXPR
+   are of kind TRUTH. If so, it returns TRUE, otherwise FALSE. */
+
+static bool
+gimple_has_cond_boolean_arms (tree expr)
+{
+  tree type = TREE_TYPE (expr);
+  tree arm1 = TREE_OPERAND (expr, 0);
+  tree arm2 = 

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

2011-05-11 Thread Richard Guenther
On Wed, May 11, 2011 at 11:00 AM, Kai Tietz ktiet...@googlemail.com wrote:
 Hi,

 By investigating the conditional expression handling I found some
 causes, why TRUTH operations AND, ANDIF, OR, XOR, and ORIF are
 appearing withing conditional folding during gimplification.
 The reason for this can be that the truth expression is simply used as
 result of an assignment or return statement, which then leads to the
 issue that expression has lhs type.  By this reason it is still
 necessary to have in TRUTH operations type-cast after boolifying it
 for later operation, if type isn't of kind boolean.  Therefore it is
 necessary for conditional to check if their arms might be TRUTH
 results and therefore doing boolification of the arms, too.

You are not making much sense - gimple_boolify already boolifies
both arms.  It assumes that if the expr is bool already the arms are
as well - I'm not sure that always holds, so defering that check as
your patch did probably makes sense.

Richard.

 2011-05-11  Kai Tietz

        * gimplify.c (gimple_boolify): Handle COND_EXPR
        and make sure that even if type is BOOLEAN for
        TRUTH-opcodes the operands getting boolified.
        (gimple_has_cond_boolean_arms): Helper function to
        detect if condition is a TRUTH operation in arms.
        (gimple_is_truth_op): Checks if operand is of BOOLEAN
        kind.
        (gimplify_expr): Boolify operand condition for
        COND_EXPR and try to see if condition might be an TRUTH operation.
        Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional
        take care that we keep expression's type.

 Tested on x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply?

 Regards,
 Kai



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

2011-05-11 Thread Kai Tietz
2011/5/11 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 9:26 PM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/10 Kai Tietz ktiet...@googlemail.com:
 2011/5/10 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote:
 On 05/10/2011 05:23 PM, Richard Guenther wrote:

 I suppose you have testcases for all the cases you looked at, please
 add some that cover these corner cases.

 Also, there is quite some tree-vrp.c dead code with these changes. 
 Removing
 the TRUTH_*_CODE handling in VRP will help finding more places where the
 middle-end is building boolean operations.  There should be testcases
 covering these parts of VRP.

 Btw, you can split the patch into two pieces - first, make TRUTH_*
 expressions correctly typed (take boolean typed operands and procude
 a boolean typed result) and verify that in verify_gimple_assign_binary.
 A second patch than can do the s/TRUTH_/BIT_/ substitution during
 gimplification.  That way the first (and more difficult) part doesn't get
 too big with unrelated changes.

 Richard.

 Paolo



 Well, I think I found one big issue here about booified expression of
 condition. The gimple_boolify needs to handle COND_EXPR in more
 detail. As if a conditional expression has to be boolified, it means
 its condition and its other operands need to be boolified, too. And
 this is for sure one cause, why I see for ANDIF/ORIF and the truth
 AND|OR|XOR none boolean types.

 I will continue on that.

 To split this seems to make sense, as I have to touch much more areas
 for the TRUTH to BIT conversion.

 Regards,
 Kai


 So I use this thread for first part of the series of patches. This one
 improves boolean type-logic
 during gimplification.
 To gimple_boolify the handling for COND_EXPR are added, and in general
 it is tried to do
 boolean operation just on boolean type.  As sadly fold-const (and here
 in special fold_truth_not_expr (), which doesn't provide by default
 boolean type and uses instead operand-type, which is IMHO a major flaw
 here.  But well, there are some comments indicating that this behavior
 is required due some other quirks. But this is for sure something to
 be cleaned up) produces truth operations with wrong type, which are in
 calculations not necessarily identifyable as truth ops anymore, this
 patch makes sure that for truth AND|OR|XOR original type remains.

 2011-05-10  Kai Tietz

        * gimplify.c (gimple_boolify): Handle COND_EXPR
        and make sure that even if type is BOOLEAN for
        TRUTH-opcodes the operands getting boolified.
        (gimplify_expr): Boolify operand condition for
        COND_EXPR.
        Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional
        take care that we keep expression's type.

 Ok for apply?

 Posting patches inline makes it easier to put in review comments, so
 please consider doing that.

Ok, I think about this. Not sure how well, google-mail handles this.
I'll try next time.

 Index: gcc/gcc/gimplify.c
 ===
 --- gcc.orig/gcc/gimplify.c     2011-05-10 18:31:40.0 +0200
 +++ gcc/gcc/gimplify.c  2011-05-10 21:14:49.106340400 +0200
 @@ -2824,11 +2824,20 @@ gimple_boolify (tree expr)
        }
     }

 -  if (TREE_CODE (type) == BOOLEAN_TYPE)
 -    return expr;
 -
   switch (TREE_CODE (expr))
     {
 +    case COND_EXPR:
 +      /* If we have a conditional expression, which shall be
 +         boolean, take care we boolify also their left and right arm.  */
 +      if (TREE_OPERAND (expr, 2) != NULL_TREE  !VOID_TYPE_P
 (TREE_TYPE (TREE_OPERAND (expr, 2
 +        TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2));
 +      if (TREE_OPERAND (expr, 1) != NULL_TREE  !VOID_TYPE_P
 (TREE_TYPE (TREE_OPERAND (expr, 1
 +        TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
 +      TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
 +      if (TREE_CODE (type) == BOOLEAN_TYPE)
 +       return expr;
 +      return fold_convert_loc (loc, boolean_type_node, expr);
 +

 That looks like premature optimization.  Why isn't it enough to
 fold-convert the COND_EXPR itself?  Thus, I don't see why the
 existing gimple_boolify isn't enough.

See description of recent update patch.  It isn't enough.

     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
 @@ -2851,6 +2860,8 @@ 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)
 +       return expr;
       return fold_convert_loc (loc, boolean_type_node, expr);
     }
  }
 @@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p, gimple_seq
          break;

        case COND_EXPR:
 +         TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 
 0));
          ret 

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

2011-05-11 Thread Kai Tietz
2011/5/11 Richard Guenther richard.guent...@gmail.com:
 On Wed, May 11, 2011 at 11:00 AM, Kai Tietz ktiet...@googlemail.com wrote:
 Hi,

 By investigating the conditional expression handling I found some
 causes, why TRUTH operations AND, ANDIF, OR, XOR, and ORIF are
 appearing withing conditional folding during gimplification.
 The reason for this can be that the truth expression is simply used as
 result of an assignment or return statement, which then leads to the
 issue that expression has lhs type.  By this reason it is still
 necessary to have in TRUTH operations type-cast after boolifying it
 for later operation, if type isn't of kind boolean.  Therefore it is
 necessary for conditional to check if their arms might be TRUTH
 results and therefore doing boolification of the arms, too.

 You are not making much sense - gimple_boolify already boolifies
 both arms.  It assumes that if the expr is bool already the arms are
 as well - I'm not sure that always holds, so defering that check as
 your patch did probably makes sense.

It makes absolutely sense. Simply try the following example:

int
foo (int a, int b, int c)
{
  int e = (a  b);
  return e ? (c  !a) : (c  a  b);
}

You will see that by this you have TRUTH AND operations with none
boolean type, due the fact that for a conditional only the cond part
was converted. This patch checks that inner arms getting boolified, if
result of condition on both arms is a TRUTH result.

Regards,
Kai


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

2011-05-11 Thread Kai Tietz
For more detail what happens and why this conditional handling is necessary:

The sample code is:

int
foo (int a, int b)
{
  return (a ? b != 3 : 0);
}

leads for variant without condition boolifying of arms to:

;; Function foo (foo)

foo (int a, int b)
{
  int D.1991;
  int D.1990;
  int D.1989;

bb 2:
  D.1990_2 = a_1(D) != 0;
  D.1991_4 = b_3(D) != 3;
  D.1989_5 = D.1991_4  D.1990_2;
  return D.1989_5;

}

with this code we see


;; Function foo (foo)

foo (int a, int b)
{
  _Bool D.1992;
  _Bool D.1991;
  _Bool D.1990;
  int D.1989;

bb 2:
  D.1990_2 = a_1(D) != 0;
  D.1991_4 = b_3(D) != 3;
  D.1992_5 = D.1991_4  D.1990_2;
  D.1989_6 = (int) D.1992_5;
  return D.1989_6;

}

So you see that by this, the SSA variable having _Bool type, as to be
wished, and not being handled as int.

Regards,
Kai


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

2011-05-11 Thread Eric Botcazou
 this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
 expressions on gimplification to their binary form.

What is it for?  This will redirect the compilation stream from proven paths to 
others so there must be a good reason to do it.  What's the effect on the code?

-- 
Eric Botcazou


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

2011-05-11 Thread Kai Tietz
2011/5/11 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 9:26 PM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/10 Kai Tietz ktiet...@googlemail.com:
 2011/5/10 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote:
 On 05/10/2011 05:23 PM, Richard Guenther wrote:

 I suppose you have testcases for all the cases you looked at, please
 add some that cover these corner cases.

 Also, there is quite some tree-vrp.c dead code with these changes. 
 Removing
 the TRUTH_*_CODE handling in VRP will help finding more places where the
 middle-end is building boolean operations.  There should be testcases
 covering these parts of VRP.

 Btw, you can split the patch into two pieces - first, make TRUTH_*
 expressions correctly typed (take boolean typed operands and procude
 a boolean typed result) and verify that in verify_gimple_assign_binary.
 A second patch than can do the s/TRUTH_/BIT_/ substitution during
 gimplification.  That way the first (and more difficult) part doesn't get
 too big with unrelated changes.

 Richard.

 Paolo



 Well, I think I found one big issue here about booified expression of
 condition. The gimple_boolify needs to handle COND_EXPR in more
 detail. As if a conditional expression has to be boolified, it means
 its condition and its other operands need to be boolified, too. And
 this is for sure one cause, why I see for ANDIF/ORIF and the truth
 AND|OR|XOR none boolean types.

 I will continue on that.

 To split this seems to make sense, as I have to touch much more areas
 for the TRUTH to BIT conversion.

 Regards,
 Kai


 So I use this thread for first part of the series of patches. This one
 improves boolean type-logic
 during gimplification.
 To gimple_boolify the handling for COND_EXPR are added, and in general
 it is tried to do
 boolean operation just on boolean type.  As sadly fold-const (and here
 in special fold_truth_not_expr (), which doesn't provide by default
 boolean type and uses instead operand-type, which is IMHO a major flaw
 here.  But well, there are some comments indicating that this behavior
 is required due some other quirks. But this is for sure something to
 be cleaned up) produces truth operations with wrong type, which are in
 calculations not necessarily identifyable as truth ops anymore, this
 patch makes sure that for truth AND|OR|XOR original type remains.

 2011-05-10  Kai Tietz

        * gimplify.c (gimple_boolify): Handle COND_EXPR
        and make sure that even if type is BOOLEAN for
        TRUTH-opcodes the operands getting boolified.
        (gimplify_expr): Boolify operand condition for
        COND_EXPR.
        Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional
        take care that we keep expression's type.

 Ok for apply?

 Posting patches inline makes it easier to put in review comments, so
 please consider doing that.


 Index: gcc/gcc/gimplify.c
 ===
 --- gcc.orig/gcc/gimplify.c     2011-05-10 18:31:40.0 +0200
 +++ gcc/gcc/gimplify.c  2011-05-10 21:14:49.106340400 +0200
 @@ -2824,11 +2824,20 @@ gimple_boolify (tree expr)
        }
     }

 -  if (TREE_CODE (type) == BOOLEAN_TYPE)
 -    return expr;
 -
   switch (TREE_CODE (expr))
     {
 +    case COND_EXPR:
 +      /* If we have a conditional expression, which shall be
 +         boolean, take care we boolify also their left and right arm.  */
 +      if (TREE_OPERAND (expr, 2) != NULL_TREE  !VOID_TYPE_P
 (TREE_TYPE (TREE_OPERAND (expr, 2
 +        TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2));
 +      if (TREE_OPERAND (expr, 1) != NULL_TREE  !VOID_TYPE_P
 (TREE_TYPE (TREE_OPERAND (expr, 1
 +        TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
 +      TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
 +      if (TREE_CODE (type) == BOOLEAN_TYPE)
 +       return expr;
 +      return fold_convert_loc (loc, boolean_type_node, expr);
 +

 That looks like premature optimization.  Why isn't it enough to
 fold-convert the COND_EXPR itself?  Thus, I don't see why the
 existing gimple_boolify isn't enough.

Old code simple casted condition expression to boolean type, but
didn't converted inner arms.  By this the arms are remaining by their
old type, which later then gets converted. This is for a condition of
kind COND_EXPR pretty bad, as exactly this leads us to useless type
conversion in inner arms.

     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
 @@ -2851,6 +2860,8 @@ 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)
 +       return expr;
       return fold_convert_loc (loc, boolean_type_node, expr);
     }
  }
 @@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p, 

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

2011-05-11 Thread Kai Tietz
2011/5/11 Eric Botcazou ebotca...@adacore.com:
 this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
 expressions on gimplification to their binary form.

 What is it for?  This will redirect the compilation stream from proven paths 
 to
 others so there must be a good reason to do it.  What's the effect on the 
 code?

 --
 Eric Botcazou

Well, it would have some effects.  First we don't need to handle TRUTH
and BINARY variants of AND, OR, XOR any longer special.  Second cause
is that on BINARY trees the reassociation pass can operate, which
leads to better optimized boolean logic.

Regards,
Kai


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

2011-05-11 Thread Richard Guenther
On Wed, May 11, 2011 at 11:35 AM, Kai Tietz ktiet...@googlemail.com wrote:
 For more detail what happens and why this conditional handling is necessary:

 The sample code is:

 int
 foo (int a, int b)
 {
  return (a ? b != 3 : 0);
 }

 leads for variant without condition boolifying of arms to:

 ;; Function foo (foo)

 foo (int a, int b)
 {
  int D.1991;
  int D.1990;
  int D.1989;

 bb 2:
  D.1990_2 = a_1(D) != 0;
  D.1991_4 = b_3(D) != 3;
  D.1989_5 = D.1991_4  D.1990_2;
  return D.1989_5;

 }

There is no TRUTH_* expr.  The patch should fix TRUTH_* expr types,
not everything else (I know tcc_comparison exprs have the same issue).

If you want to fix tcc_comparison results as well do so in gimplify_expr
(and adjust the type verifier similar to the TRUTH_ case).

Richard.


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

2011-05-11 Thread Richard Guenther
On Wed, May 11, 2011 at 12:03 PM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/11 Eric Botcazou ebotca...@adacore.com:
 this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
 expressions on gimplification to their binary form.

 What is it for?  This will redirect the compilation stream from proven paths 
 to
 others so there must be a good reason to do it.  What's the effect on the 
 code?

 --
 Eric Botcazou

 Well, it would have some effects.  First we don't need to handle TRUTH
 and BINARY variants of AND, OR, XOR any longer special.  Second cause
 is that on BINARY trees the reassociation pass can operate, which
 leads to better optimized boolean logic.

The most important thing is to get predicate types sane - that affects
tcc_comparison codes and the TRUTH_* codes.  After that, the TRUTH_*
codes are redundant with the BIT_* ones which already are always
validly typed.  As fold already converts some TRUTH_* to BIT_* variants
we usually have a mix of both which is not handled very well by tree
optimizers.

Richard.

 Regards,
 Kai



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

2011-05-11 Thread Kai Tietz
2011/5/11 Richard Guenther richard.guent...@gmail.com:
 The most important thing is to get predicate types sane - that affects
 tcc_comparison codes and the TRUTH_* codes.  After that, the TRUTH_*
 codes are redundant with the BIT_* ones which already are always
 validly typed.  As fold already converts some TRUTH_* to BIT_* variants
 we usually have a mix of both which is not handled very well by tree
 optimizers.

Well, to boolify comparisions isn't that hard at all, but I don't see
here much improvement, as it will lead necessarily for uses without
boolean-type always in gimple as '(type) comparison_tcc-ssa', which
seems to me like trying to put the cart before the horse.

So updated patch inlined (and attached).  The type-casting for
TRUTH_ANDIF/ORIF is still necessary (without it I get bootstrap
failures due perfectly working gimple_cond_expr function, which is
producing here happily iftmp variables assigning later on wrong
type.

Regards,
Kai

Index: gcc/gcc/gimplify.c
===
--- gcc.orig/gcc/gimplify.c 2011-05-11 17:03:24.853377700 +0200
+++ gcc/gcc/gimplify.c  2011-05-11 17:11:02.018281300 +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,8 @@ 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)
+   return expr;
   return fold_convert_loc (loc, boolean_type_node, expr);
 }
 }
@@ -6762,6 +6761,21 @@ gimplify_expr (tree *expr_p, gimple_seq

case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_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, this happens.  */
+   if (TREE_CODE (org_type) != BOOLEAN_TYPE)
+ {
+   *expr_p = fold_convert (org_type, *expr_p);
+   ret = GS_OK;
+   break;
+ }
+ }
  /* Pass the source location of the outer expression.  */
  ret = gimplify_boolean_expr (expr_p, saved_location);
  break;
@@ -7203,6 +7217,22 @@ 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, this happens.  */
+   if (TREE_CODE (org_type) != BOOLEAN_TYPE)
+ {
+   *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-11 17:03:24.863377700 +0200
+++ gcc/gcc/tree-cfg.c  2011-05-11 17:04:32.293292500 +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 argument and result.  */
+   if (TREE_CODE (rhs1_type) != BOOLEAN_TYPE
+   || TREE_CODE (rhs2_type) != BOOLEAN_TYPE
+   || TREE_CODE (lhs_type) != BOOLEAN_TYPE)
  {
error (type mismatch in binary truth expression);
debug_generic_expr (lhs_type);
Index: gcc/gcc/gimplify.c
===
--- gcc.orig/gcc/gimplify.c 2011-05-10 15:44:49.0 +0200
+++ gcc/gcc/gimplify.c  2011-05-10 15:46:58.365473600 +0200
@@ -4710,6 +4716,7 @@ gimplify_boolean_expr (tree *expr_p, loc
 {
   /* Preserve the original type of the expression.  */
   tree type = TREE_TYPE (*expr_p);
+  *expr_p = gimple_boolify (*expr_p);
 
   *expr_p = build3 (COND_EXPR, type, *expr_p,
fold_convert_loc (locus, type, boolean_true_node),
@@ -6762,6 +6769,13 @@ gimplify_expr (tree *expr_p, gimple_seq
 
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
+ if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+   {
+ tree type = TREE_TYPE (*expr_p);
+   

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

2011-05-10 Thread Richard Guenther
On Tue, May 10, 2011 at 3:56 PM, Kai Tietz ktiet...@googlemail.com wrote:
 Hello,

 this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
 expressions
 on gimplification to their binary form.  Additionally it takes care
 that conditions
 are getting boolified for operation.

 ChangeLog

 2011-05-10  Kai Tietz

        * gimplify.c (gimplify_exit_expr): Boolify conditional
        expression part.
        (shortcut_cond_r): Likewise.
        (shortcut_cond_expr): Likewise.
        (gimplify_cond_expr): Likewise.
        (gimplify_modify_expr_rhs): Likewise.
        (gimplify_boolean_expr): Likewise.
        (gimple_boolify): Boolify operands for BOOLEAN typed
        base expressions.
        (gimplify_expr): Boolify TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
        TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR. Additionally
        move TRUTH_AND|OR|XOR_EXPR to its binary form.

 Tested for x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply?

Comments inline (the attachment makes my comments harder to spot,
look close).

Index: gcc/gcc/gimplify.c
===
--- gcc.orig/gcc/gimplify.c 2011-05-10 15:44:49.0 +0200
+++ gcc/gcc/gimplify.c  2011-05-10 15:46:58.365473600 +0200
@@ -1664,10 +1664,12 @@ build_and_jump (tree *label_p)
 static enum gimplify_status
 gimplify_exit_expr (tree *expr_p)
 {
-  tree cond = TREE_OPERAND (*expr_p, 0);
-  tree expr;
+  tree cond, expr;

+  TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0));
+  cond = TREE_OPERAND (*expr_p, 0);

Why do you need to boolify things at all when we build a COND_EXPR
that gets re-gimplified anyway?  I'm confused by this (similar to other
places you do that).  I would expect that you at most would do this
when gimplifying COND_EXPRs, not when you build them.

   expr = build_and_jump (gimplify_ctxp-exit_label);
+
   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
   *expr_p = expr;

@@ -2586,6 +2588,7 @@ shortcut_cond_r (tree pred, tree *true_l
   /* Keep the original source location on the first 'if'.  Set the source
 location of the ? on the second 'if'.  */
   new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
+  TREE_OPERAND (pred, 0) = gimple_boolify (TREE_OPERAND (pred, 0));
   expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
  false_label_p, locus),
@@ -2594,7 +2597,7 @@ shortcut_cond_r (tree pred, tree *true_l
 }
   else
 {
-  expr = build3 (COND_EXPR, void_type_node, pred,
+  expr = build3 (COND_EXPR, void_type_node, gimple_boolify (pred),
 build_and_jump (true_label_p),
 build_and_jump (false_label_p));
   SET_EXPR_LOCATION (expr, locus);
@@ -2625,7 +2628,8 @@ shortcut_cond_expr (tree expr)
   bool emit_end, emit_false, jump_over_else;
   bool then_se = then_  TREE_SIDE_EFFECTS (then_);
   bool else_se = else_  TREE_SIDE_EFFECTS (else_);
-
+
+  pred = TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   /* First do simple transformations.  */
   if (!else_se)
 {
@@ -2665,7 +2669,7 @@ shortcut_cond_expr (tree expr)
SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
  else_ = shortcut_cond_expr (expr);
  else_se = else_  TREE_SIDE_EFFECTS (else_);
- pred = TREE_OPERAND (pred, 0);
+ pred = gimple_boolify (TREE_OPERAND (pred, 0));
  expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
  SET_EXPR_LOCATION (expr, locus);
}
@@ -2824,9 +2828,6 @@ gimple_boolify (tree expr)
}
 }

-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-return expr;
-
   switch (TREE_CODE (expr))
 {
 case TRUTH_AND_EXPR:
@@ -2851,6 +2852,8 @@ 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)
+   return expr;

Why do you need to move this?

   return fold_convert_loc (loc, boolean_type_node, expr);
 }
 }
@@ -2865,7 +2868,7 @@ gimplify_pure_cond_expr (tree *expr_p, g
   enum gimplify_status ret, tret;
   enum tree_code code;

-  cond = gimple_boolify (COND_EXPR_COND (expr));
+  cond = COND_EXPR_COND (expr) = gimple_boolify (COND_EXPR_COND (expr));

why change COND_EXPR_COND?

   /* We need to handle  and || specially, as their gimplification
  creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
@@ -2937,6 +2940,7 @@ gimplify_cond_expr (tree *expr_p, gimple
   enum tree_code pred_code;
   gimple_seq seq = NULL;

+  TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0));

So you are doing it here - why do it everywhere else?  I'd like to see
this change at exactly _one_ place.

   /* If this 

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

2011-05-10 Thread Richard Guenther
On Tue, May 10, 2011 at 5:08 PM, Kai Tietz ktiet...@googlemail.com wrote:
 2011/5/10 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 3:56 PM, Kai Tietz ktiet...@googlemail.com wrote:
 Hello,

 this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
 expressions
 on gimplification to their binary form.  Additionally it takes care
 that conditions
 are getting boolified for operation.

 ChangeLog

 2011-05-10  Kai Tietz

        * gimplify.c (gimplify_exit_expr): Boolify conditional
        expression part.
        (shortcut_cond_r): Likewise.
        (shortcut_cond_expr): Likewise.
        (gimplify_cond_expr): Likewise.
        (gimplify_modify_expr_rhs): Likewise.
        (gimplify_boolean_expr): Likewise.
        (gimple_boolify): Boolify operands for BOOLEAN typed
        base expressions.
        (gimplify_expr): Boolify TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
        TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR. Additionally
        move TRUTH_AND|OR|XOR_EXPR to its binary form.

 Tested for x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply?

 Comments inline (the attachment makes my comments harder to spot,
 look close).

 Index: gcc/gcc/gimplify.c
 ===
 --- gcc.orig/gcc/gimplify.c     2011-05-10 15:44:49.0 +0200
 +++ gcc/gcc/gimplify.c  2011-05-10 15:46:58.365473600 +0200
 @@ -1664,10 +1664,12 @@ build_and_jump (tree *label_p)
  static enum gimplify_status
  gimplify_exit_expr (tree *expr_p)
  {
 -  tree cond = TREE_OPERAND (*expr_p, 0);
 -  tree expr;
 +  tree cond, expr;

 +  TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0));
 +  cond = TREE_OPERAND (*expr_p, 0);

 Why do you need to boolify things at all when we build a COND_EXPR
 that gets re-gimplified anyway?  I'm confused by this (similar to other
 places you do that).  I would expect that you at most would do this
 when gimplifying COND_EXPRs, not when you build them.

   expr = build_and_jump (gimplify_ctxp-exit_label);
 +
   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
   *expr_p = expr;

 @@ -2586,6 +2588,7 @@ shortcut_cond_r (tree pred, tree *true_l
       /* Keep the original source location on the first 'if'.  Set the source
         location of the ? on the second 'if'.  */
       new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
 +      TREE_OPERAND (pred, 0) = gimple_boolify (TREE_OPERAND (pred, 0));
       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
                     shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
                                      false_label_p, locus),
 @@ -2594,7 +2597,7 @@ shortcut_cond_r (tree pred, tree *true_l
     }
   else
     {
 -      expr = build3 (COND_EXPR, void_type_node, pred,
 +      expr = build3 (COND_EXPR, void_type_node, gimple_boolify (pred),
                     build_and_jump (true_label_p),
                     build_and_jump (false_label_p));
       SET_EXPR_LOCATION (expr, locus);
 @@ -2625,7 +2628,8 @@ shortcut_cond_expr (tree expr)
   bool emit_end, emit_false, jump_over_else;
   bool then_se = then_  TREE_SIDE_EFFECTS (then_);
   bool else_se = else_  TREE_SIDE_EFFECTS (else_);
 -
 +
 +  pred = TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   /* First do simple transformations.  */
   if (!else_se)
     {
 @@ -2665,7 +2669,7 @@ shortcut_cond_expr (tree expr)
            SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
          else_ = shortcut_cond_expr (expr);
          else_se = else_  TREE_SIDE_EFFECTS (else_);
 -         pred = TREE_OPERAND (pred, 0);
 +         pred = gimple_boolify (TREE_OPERAND (pred, 0));
          expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
          SET_EXPR_LOCATION (expr, locus);
        }
 @@ -2824,9 +2828,6 @@ gimple_boolify (tree expr)
        }
     }

 -  if (TREE_CODE (type) == BOOLEAN_TYPE)
 -    return expr;
 -
   switch (TREE_CODE (expr))
     {
     case TRUTH_AND_EXPR:
 @@ -2851,6 +2852,8 @@ 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)
 +       return expr;

 Why do you need to move this?

       return fold_convert_loc (loc, boolean_type_node, expr);
     }
  }
 @@ -2865,7 +2868,7 @@ gimplify_pure_cond_expr (tree *expr_p, g
   enum gimplify_status ret, tret;
   enum tree_code code;

 -  cond = gimple_boolify (COND_EXPR_COND (expr));
 +  cond = COND_EXPR_COND (expr) = gimple_boolify (COND_EXPR_COND (expr));

 why change COND_EXPR_COND?

   /* We need to handle  and || specially, as their gimplification
      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
 @@ -2937,6 +2940,7 @@ gimplify_cond_expr (tree *expr_p, gimple
   enum tree_code pred_code;
   gimple_seq seq = NULL;

 +  TREE_OPERAND 

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

2011-05-10 Thread Paolo Bonzini

On 05/10/2011 05:23 PM, Richard Guenther wrote:

I suppose you have testcases for all the cases you looked at, please
add some that cover these corner cases.


Also, there is quite some tree-vrp.c dead code with these changes. 
Removing the TRUTH_*_CODE handling in VRP will help finding more places 
where the middle-end is building boolean operations.  There should be 
testcases covering these parts of VRP.


Paolo


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

2011-05-10 Thread Richard Guenther
On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote:
 On 05/10/2011 05:23 PM, Richard Guenther wrote:

 I suppose you have testcases for all the cases you looked at, please
 add some that cover these corner cases.

 Also, there is quite some tree-vrp.c dead code with these changes. Removing
 the TRUTH_*_CODE handling in VRP will help finding more places where the
 middle-end is building boolean operations.  There should be testcases
 covering these parts of VRP.

Btw, you can split the patch into two pieces - first, make TRUTH_*
expressions correctly typed (take boolean typed operands and procude
a boolean typed result) and verify that in verify_gimple_assign_binary.
A second patch than can do the s/TRUTH_/BIT_/ substitution during
gimplification.  That way the first (and more difficult) part doesn't get
too big with unrelated changes.

Richard.

 Paolo



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

2011-05-10 Thread Kai Tietz
2011/5/10 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote:
 On 05/10/2011 05:23 PM, Richard Guenther wrote:

 I suppose you have testcases for all the cases you looked at, please
 add some that cover these corner cases.

 Also, there is quite some tree-vrp.c dead code with these changes. Removing
 the TRUTH_*_CODE handling in VRP will help finding more places where the
 middle-end is building boolean operations.  There should be testcases
 covering these parts of VRP.

 Btw, you can split the patch into two pieces - first, make TRUTH_*
 expressions correctly typed (take boolean typed operands and procude
 a boolean typed result) and verify that in verify_gimple_assign_binary.
 A second patch than can do the s/TRUTH_/BIT_/ substitution during
 gimplification.  That way the first (and more difficult) part doesn't get
 too big with unrelated changes.

 Richard.

 Paolo



Well, I think I found one big issue here about booified expression of
condition. The gimple_boolify needs to handle COND_EXPR in more
detail. As if a conditional expression has to be boolified, it means
its condition and its other operands need to be boolified, too. And
this is for sure one cause, why I see for ANDIF/ORIF and the truth
AND|OR|XOR none boolean types.

I will continue on that.

To split this seems to make sense, as I have to touch much more areas
for the TRUTH to BIT conversion.

Regards,
Kai


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

2011-05-10 Thread Kai Tietz
2011/5/10 Kai Tietz ktiet...@googlemail.com:
 2011/5/10 Richard Guenther richard.guent...@gmail.com:
 On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote:
 On 05/10/2011 05:23 PM, Richard Guenther wrote:

 I suppose you have testcases for all the cases you looked at, please
 add some that cover these corner cases.

 Also, there is quite some tree-vrp.c dead code with these changes. Removing
 the TRUTH_*_CODE handling in VRP will help finding more places where the
 middle-end is building boolean operations.  There should be testcases
 covering these parts of VRP.

 Btw, you can split the patch into two pieces - first, make TRUTH_*
 expressions correctly typed (take boolean typed operands and procude
 a boolean typed result) and verify that in verify_gimple_assign_binary.
 A second patch than can do the s/TRUTH_/BIT_/ substitution during
 gimplification.  That way the first (and more difficult) part doesn't get
 too big with unrelated changes.

 Richard.

 Paolo



 Well, I think I found one big issue here about booified expression of
 condition. The gimple_boolify needs to handle COND_EXPR in more
 detail. As if a conditional expression has to be boolified, it means
 its condition and its other operands need to be boolified, too. And
 this is for sure one cause, why I see for ANDIF/ORIF and the truth
 AND|OR|XOR none boolean types.

 I will continue on that.

 To split this seems to make sense, as I have to touch much more areas
 for the TRUTH to BIT conversion.

 Regards,
 Kai


So I use this thread for first part of the series of patches. This one
improves boolean type-logic
during gimplification.
To gimple_boolify the handling for COND_EXPR are added, and in general
it is tried to do
boolean operation just on boolean type.  As sadly fold-const (and here
in special fold_truth_not_expr (), which doesn't provide by default
boolean type and uses instead operand-type, which is IMHO a major flaw
here.  But well, there are some comments indicating that this behavior
is required due some other quirks. But this is for sure something to
be cleaned up) produces truth operations with wrong type, which are in
calculations not necessarily identifyable as truth ops anymore, this
patch makes sure that for truth AND|OR|XOR original type remains.

2011-05-10  Kai Tietz

* gimplify.c (gimple_boolify): Handle COND_EXPR
and make sure that even if type is BOOLEAN for
TRUTH-opcodes the operands getting boolified.
(gimplify_expr): Boolify operand condition for
COND_EXPR.
Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional
take care that we keep expression's type.

Ok for apply?

Regards,
Kai
Index: gcc/gcc/gimplify.c
===
--- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200
+++ gcc/gcc/gimplify.c  2011-05-10 21:14:49.106340400 +0200
@@ -2824,11 +2824,20 @@ gimple_boolify (tree expr)
}
 }
 
-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-return expr;
-
   switch (TREE_CODE (expr))
 {
+case COND_EXPR:
+  /* If we have a conditional expression, which shall be
+ boolean, take care we boolify also their left and right arm.  */
+  if (TREE_OPERAND (expr, 2) != NULL_TREE  !VOID_TYPE_P (TREE_TYPE 
(TREE_OPERAND (expr, 2
+TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2));
+  if (TREE_OPERAND (expr, 1) != NULL_TREE  !VOID_TYPE_P (TREE_TYPE 
(TREE_OPERAND (expr, 1
+TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
+  TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+   return expr;
+  return fold_convert_loc (loc, boolean_type_node, expr);
+
 case TRUTH_AND_EXPR:
 case TRUTH_OR_EXPR:
 case TRUTH_XOR_EXPR:
@@ -2851,6 +2860,8 @@ 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)
+   return expr;
   return fold_convert_loc (loc, boolean_type_node, expr);
 }
 }
@@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p, gimple_seq
  break;
 
case COND_EXPR:
+ TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 
0));
  ret = gimplify_cond_expr (expr_p, pre_p, fallback);
 
  /* C99 code may assign to an array in a structure value of a
@@ -6762,6 +6774,17 @@ gimplify_expr (tree *expr_p, gimple_seq
 
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
+ /* 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, this happens.  */
+ if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+   {
+ tree type =