Hello,

this patch tries to sink conversions for comparisons patterns:
a) (type) X cmp (type) Y => x cmp y.
b) (type) X cmp CST => x cmp ((type-x) CST).
c) CST cmp (type) X => ((type-x) CST) cmp x.

This patch just allows type sinking for the case that type-precision of type is 
wider or equal to type-precision of type-x. Or if type and type-x have same 
signess and CST fits into type-x. For cmp operation is == or !=, we allow also 
that type and type-x have different signess, as long as CST fits into type-x 
without truncation. 

ChangeLog

2011-06-27  Kai Tietz  <kti...@redhat.com>

        * tree-ssa-forwprop.c (forward_propagate_into_comparision):
        Sink types within comparison operands, if suitable.

Bootstrapped and regression tested for x86_64-pc-linux-gnu. Ok for apply?

Regards,
Kai
Index: gcc-head/gcc/tree-ssa-forwprop.c
===================================================================
--- gcc-head.orig/gcc/tree-ssa-forwprop.c
+++ gcc-head/gcc/tree-ssa-forwprop.c
@@ -432,11 +432,73 @@ forward_propagate_into_comparison_1 (loc
   /* If that wasn't successful either, try both operands.  */
   if (rhs0 != NULL_TREE
       && rhs1 != NULL_TREE)
-    tmp = combine_cond_expr_cond (loc, code, type,
-                                 rhs0, rhs1,
-                                 !(single_use0_p && single_use1_p));
-
-  return tmp;
+    {
+      tmp = combine_cond_expr_cond (loc, code, type,
+                                   rhs0, rhs1,
+                                   !(single_use0_p && single_use1_p));
+      if (tmp)
+        return tmp;
+    }
+  /* Sink types of comparison, if (type) CMP (type) Y, if types
+     of X and Y are compatible.  */
+  if (rhs0 != NULL_TREE && rhs1 != NULL_TREE
+      && CONVERT_EXPR_CODE_P (TREE_CODE (rhs0))
+      && CONVERT_EXPR_CODE_P (TREE_CODE (rhs1))
+      && types_compatible_p (TREE_TYPE (TREE_OPERAND (rhs0, 0)),
+                            TREE_TYPE (TREE_OPERAND (rhs1, 0)))
+      /* Make sure that the conversion widens the operands, or has same
+        precision.  */
+      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs0, 0)))
+          <= TYPE_PRECISION (TREE_TYPE (rhs0)))
+      && (code == EQ_EXPR || code == NE_EXPR
+         || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (rhs0, 0)))
+            == TYPE_UNSIGNED (TREE_TYPE (rhs0))))
+     return fold_build2_loc (loc, code, type, TREE_OPERAND (rhs0, 0),
+                            TREE_OPERAND (rhs1, 0));
+  /* Check if (type) X cmp CST can be convered into
+     (type) (X cmp (type-x) CST).  */
+  if (rhs0 != NULL_TREE
+      && CONVERT_EXPR_CODE_P (TREE_CODE (rhs0))
+      && TREE_CODE (op1) == INTEGER_CST
+      && INTEGRAL_TYPE_P (TREE_OPERAND (rhs0, 0))
+      && INTEGRAL_TYPE_P (rhs0)
+      && (code == EQ_EXPR || code == NE_EXPR
+         || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (rhs0, 0)))
+            == TYPE_UNSIGNED (TREE_TYPE (rhs0))))
+    {
+      tree folded_int = fold_convert_loc (loc,
+                                         TREE_TYPE (TREE_OPERAND (rhs0, 0)),
+                                         op1);
+      /* Is the back casted folded integer identical to original
+        integer?  */
+      if (operand_equal_p (op1, fold_convert_loc (loc, TREE_TYPE (op0),
+                                                 folded_int), 0))
+        return fold_build2_loc (loc, code, type, TREE_OPERAND (rhs0, 0),
+                               folded_int);
+    }
+
+  /* Check if CST op (type) X can be converted into
+     (type) ((type-x) CST op X).  */
+  if (rhs1 != NULL_TREE
+      && CONVERT_EXPR_CODE_P (TREE_CODE (rhs1))
+      && TREE_CODE (op0) == INTEGER_CST
+      && INTEGRAL_TYPE_P (TREE_OPERAND (rhs1, 0))
+      && INTEGRAL_TYPE_P (rhs1)
+      && (code == EQ_EXPR || code == NE_EXPR
+         || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (rhs1, 0)))
+            == TYPE_UNSIGNED (TREE_TYPE (rhs1))))
+    {
+      tree folded_int = fold_convert_loc (loc,
+                                         TREE_TYPE (TREE_OPERAND (rhs1, 0)),
+                                         op0);
+      /* Is the back casted folded integer identical to original
+        integer?  */
+      if (operand_equal_p (op0, fold_convert_loc (loc, TREE_TYPE (op1),
+                                                 folded_int), 0))
+        return fold_build2_loc (loc, code, type, folded_int,
+                               TREE_OPERAND (rhs1, 0));
+    }
+  return NULL_TREE;
 }
 
 /* Propagate from the ssa name definition statements of the assignment

Reply via email to