fold-const.c (fold_widened_comparison): Remove.
authorRichard Biener <rguenther@suse.de>
Thu, 16 Jul 2015 08:28:51 +0000 (08:28 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 16 Jul 2015 08:28:51 +0000 (08:28 +0000)
2015-07-16  Richard Biener  <rguenther@suse.de>

* fold-const.c (fold_widened_comparison): Remove.
(fold_sign_changed_comparison): Likewise.
(fold_comparison): Move widened and sign-changed comparison
simplification ...
* match.pd: ... to patterns here.
* generic-match-head.c: Include target.h.
* gimple-match-head.c: Likewise.

* gcc.dg/tree-ssa/pr21031.c: Adjust.

From-SVN: r225861

gcc/ChangeLog
gcc/fold-const.c
gcc/generic-match-head.c
gcc/gimple-match-head.c
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr21031.c

index 47c7c16f6b6738869c96c37d6bd9243a61814400..0287697ecb4f44cfcf1b6ec29016e6b943768c6c 100644 (file)
@@ -1,3 +1,13 @@
+2015-07-16  Richard Biener  <rguenther@suse.de>
+
+       * fold-const.c (fold_widened_comparison): Remove.
+       (fold_sign_changed_comparison): Likewise.
+       (fold_comparison): Move widened and sign-changed comparison
+       simplification ...
+       * match.pd: ... to patterns here.
+       * generic-match-head.c: Include target.h.
+       * gimple-match-head.c: Likewise.
+
 2015-07-16  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-dom.c (dom_valueize): New function.
index acccb3c6007119a62db61b63845364524be26827..93dd29d6729b2d445ea12ca87dd62980913d55a9 100644 (file)
@@ -6685,148 +6685,6 @@ tree_swap_operands_p (const_tree arg0, const_tree arg1, bool reorder)
   return 0;
 }
 
-/* Fold comparison ARG0 CODE ARG1 (with result in TYPE), where
-   ARG0 is extended to a wider type.  */
-
-static tree
-fold_widened_comparison (location_t loc, enum tree_code code,
-                        tree type, tree arg0, tree arg1)
-{
-  tree arg0_unw = get_unwidened (arg0, NULL_TREE);
-  tree arg1_unw;
-  tree shorter_type, outer_type;
-  tree min, max;
-  bool above, below;
-
-  if (arg0_unw == arg0)
-    return NULL_TREE;
-  shorter_type = TREE_TYPE (arg0_unw);
-
-  /* Disable this optimization if we're casting a function pointer
-     type on targets that require function pointer canonicalization.  */
-  if (targetm.have_canonicalize_funcptr_for_compare ()
-      && TREE_CODE (shorter_type) == POINTER_TYPE
-      && TREE_CODE (TREE_TYPE (shorter_type)) == FUNCTION_TYPE)
-    return NULL_TREE;
-
-  if (TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (shorter_type))
-    return NULL_TREE;
-
-  arg1_unw = get_unwidened (arg1, NULL_TREE);
-
-  /* If possible, express the comparison in the shorter mode.  */
-  if ((code == EQ_EXPR || code == NE_EXPR
-       || TYPE_UNSIGNED (TREE_TYPE (arg0)) == TYPE_UNSIGNED (shorter_type))
-      && (TREE_TYPE (arg1_unw) == shorter_type
-         || ((TYPE_PRECISION (shorter_type)
-              >= TYPE_PRECISION (TREE_TYPE (arg1_unw)))
-             && (TYPE_UNSIGNED (shorter_type)
-                 == TYPE_UNSIGNED (TREE_TYPE (arg1_unw))))
-         || (TREE_CODE (arg1_unw) == INTEGER_CST
-             && (TREE_CODE (shorter_type) == INTEGER_TYPE
-                 || TREE_CODE (shorter_type) == BOOLEAN_TYPE)
-             && int_fits_type_p (arg1_unw, shorter_type))))
-    return fold_build2_loc (loc, code, type, arg0_unw,
-                       fold_convert_loc (loc, shorter_type, arg1_unw));
-
-  if (TREE_CODE (arg1_unw) != INTEGER_CST
-      || TREE_CODE (shorter_type) != INTEGER_TYPE
-      || int_fits_type_p (arg1_unw, shorter_type))
-    return NULL_TREE;
-
-  /* If we are comparing with the integer that does not fit into the range
-     of the shorter type, the result is known.  */
-  outer_type = TREE_TYPE (arg1_unw);
-  min = lower_bound_in_type (outer_type, shorter_type);
-  max = upper_bound_in_type (outer_type, shorter_type);
-
-  above = integer_nonzerop (fold_relational_const (LT_EXPR, type,
-                                                  max, arg1_unw));
-  below = integer_nonzerop (fold_relational_const (LT_EXPR, type,
-                                                  arg1_unw, min));
-
-  switch (code)
-    {
-    case EQ_EXPR:
-      if (above || below)
-       return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
-      break;
-
-    case NE_EXPR:
-      if (above || below)
-       return omit_one_operand_loc (loc, type, integer_one_node, arg0);
-      break;
-
-    case LT_EXPR:
-    case LE_EXPR:
-      if (above)
-       return omit_one_operand_loc (loc, type, integer_one_node, arg0);
-      else if (below)
-       return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
-
-    case GT_EXPR:
-    case GE_EXPR:
-      if (above)
-       return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
-      else if (below)
-       return omit_one_operand_loc (loc, type, integer_one_node, arg0);
-
-    default:
-      break;
-    }
-
-  return NULL_TREE;
-}
-
-/* Fold comparison ARG0 CODE ARG1 (with result in TYPE), where for
-   ARG0 just the signedness is changed.  */
-
-static tree
-fold_sign_changed_comparison (location_t loc, enum tree_code code, tree type,
-                             tree arg0, tree arg1)
-{
-  tree arg0_inner;
-  tree inner_type, outer_type;
-
-  if (!CONVERT_EXPR_P (arg0))
-    return NULL_TREE;
-
-  outer_type = TREE_TYPE (arg0);
-  arg0_inner = TREE_OPERAND (arg0, 0);
-  inner_type = TREE_TYPE (arg0_inner);
-
-  /* Disable this optimization if we're casting a function pointer
-     type on targets that require function pointer canonicalization.  */
-  if (targetm.have_canonicalize_funcptr_for_compare ()
-      && TREE_CODE (inner_type) == POINTER_TYPE
-      && TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE)
-    return NULL_TREE;
-
-  if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
-    return NULL_TREE;
-
-  if (TREE_CODE (arg1) != INTEGER_CST
-      && !(CONVERT_EXPR_P (arg1)
-          && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
-    return NULL_TREE;
-
-  if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
-      && code != NE_EXPR
-      && code != EQ_EXPR)
-    return NULL_TREE;
-
-  if (POINTER_TYPE_P (inner_type) != POINTER_TYPE_P (outer_type))
-    return NULL_TREE;
-
-  if (TREE_CODE (arg1) == INTEGER_CST)
-    arg1 = force_fit_type (inner_type, wi::to_widest (arg1), 0,
-                          TREE_OVERFLOW (arg1));
-  else
-    arg1 = fold_convert_loc (loc, inner_type, arg1);
-
-  return fold_build2_loc (loc, code, type, arg0_inner, arg1);
-}
-
 
 /* Fold A < X && A + 1 > Y to A < X && A >= Y.  Normally A + 1 > Y
    means A >= Y && A != MAX, but in this case we know that
@@ -8813,22 +8671,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
   if (tem)
     return tem;
 
-  if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
-      && CONVERT_EXPR_P (arg0))
-    {
-      /* If we are widening one operand of an integer comparison,
-        see if the other operand is similarly being widened.  Perhaps we
-        can do the comparison in the narrower type.  */
-      tem = fold_widened_comparison (loc, code, type, arg0, arg1);
-      if (tem)
-       return tem;
-
-      /* Or if we are changing signedness.  */
-      tem = fold_sign_changed_comparison (loc, code, type, arg0, arg1);
-      if (tem)
-       return tem;
-    }
-
   /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
      constant, we can simplify it.  */
   if (TREE_CODE (arg1) == INTEGER_CST
index 66615a4fab43cff60f142af79ffd71724e177e89..da7abc669647df562e3a3cbf59942223aa36db2e 100644 (file)
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dfa.h"
 #include "builtins.h"
 #include "dumpfile.h"
+#include "target.h"
 #include "generic-match.h"
 
 /* Routine to determine if the types T1 and T2 are effectively
index 875b724657551eeebe303d162d7691d71c152325..2b1423806bca237910a1f75912182f372e5b346d 100644 (file)
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dfa.h"
 #include "builtins.h"
 #include "dumpfile.h"
+#include "target.h"
 #include "gimple-match.h"
 
 
index a3fba51969e80625ddaa79fc5e00a920a9acbc20..c335ada567ed82b164aa390cfdf0ddd2b075d0b2 100644 (file)
@@ -1664,6 +1664,62 @@ along with GCC; see the file COPYING3.  If not see
     (if (tem && !TREE_OVERFLOW (tem))
      (scmp @0 { tem; }))))))
 
+/* From fold_sign_changed_comparison and fold_widened_comparison.  */
+(for cmp (simple_comparison)
+ (simplify
+  (cmp (convert@0 @00) (convert?@1 @10))
+  (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE
+       /* Disable this optimization if we're casting a function pointer
+         type on targets that require function pointer canonicalization.  */
+       && !(targetm.have_canonicalize_funcptr_for_compare ()
+           && TREE_CODE (TREE_TYPE (@00)) == POINTER_TYPE
+           && TREE_CODE (TREE_TYPE (TREE_TYPE (@00))) == FUNCTION_TYPE))
+   (if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0))
+       && (TREE_CODE (@10) == INTEGER_CST
+           || (@1 != @10 && types_match (TREE_TYPE (@10), TREE_TYPE (@00))))
+       && (TYPE_UNSIGNED (TREE_TYPE (@00)) == TYPE_UNSIGNED (TREE_TYPE (@0))
+           || cmp == NE_EXPR
+           || cmp == EQ_EXPR)
+       && (POINTER_TYPE_P (TREE_TYPE (@00)) == POINTER_TYPE_P (TREE_TYPE (@0))))
+    /* ???  The special-casing of INTEGER_CST conversion was in the original
+       code and here to avoid a spurious overflow flag on the resulting
+       constant which fold_convert produces.  */
+    (if (TREE_CODE (@1) == INTEGER_CST)
+     (cmp @00 { force_fit_type (TREE_TYPE (@00), wi::to_widest (@1), 0,
+                               TREE_OVERFLOW (@1)); })
+     (cmp @00 (convert @1)))
+
+    (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@00)))
+     /* If possible, express the comparison in the shorter mode.  */
+     (if ((cmp == EQ_EXPR || cmp == NE_EXPR
+          || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@00)))
+         && (types_match (TREE_TYPE (@10), TREE_TYPE (@00))
+             || ((TYPE_PRECISION (TREE_TYPE (@00))
+                  >= TYPE_PRECISION (TREE_TYPE (@10)))
+                 && (TYPE_UNSIGNED (TREE_TYPE (@00))
+                     == TYPE_UNSIGNED (TREE_TYPE (@10))))
+             || (TREE_CODE (@10) == INTEGER_CST
+                 && (TREE_CODE (TREE_TYPE (@00)) == INTEGER_TYPE
+                     || TREE_CODE (TREE_TYPE (@00)) == BOOLEAN_TYPE)
+                 && int_fits_type_p (@10, TREE_TYPE (@00)))))
+      (cmp @00 (convert @10))
+      (if (TREE_CODE (@10) == INTEGER_CST
+          && TREE_CODE (TREE_TYPE (@00)) == INTEGER_TYPE
+          && !int_fits_type_p (@10, TREE_TYPE (@00)))
+       (with
+       {
+         tree min = lower_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00));
+         tree max = upper_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00));
+         bool above = integer_nonzerop (const_binop (LT_EXPR, type, max, @10));
+         bool below = integer_nonzerop (const_binop (LT_EXPR, type, @10, min));
+       }
+       (if (above || below)
+        (if (cmp == EQ_EXPR || cmp == NE_EXPR)
+         { constant_boolean_node (cmp == EQ_EXPR ? false : true, type); }
+         (if (cmp == LT_EXPR || cmp == LE_EXPR)
+          { constant_boolean_node (above ? true : false, type); }
+          (if (cmp == GT_EXPR || cmp == GE_EXPR)
+           { constant_boolean_node (above ? false : true, type); }))))))))))))
 
 /* Equality compare simplifications from fold_binary  */
 (for cmp (eq ne)
index a3ae9d5b39c427b6f218dadab333228d6e2cc110..8bc934129987b18a0076fdb0b8615b852484d33a 100644 (file)
@@ -1,3 +1,7 @@
+2015-07-16  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/pr21031.c: Adjust.
+
 2015-07-16  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/66866
index f39c1276c7ea4d480e8f48ad617b972f0ac0ea6e..a6f5b6e88481335cb48f6d11143434301dfaf311 100644 (file)
@@ -3,7 +3,7 @@
    Make sure that a != 0 is propagated into the "if" statement.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-forwprop1-details" } */
+/* { dg-options "-O1 -fdump-tree-forwprop1" } */
 
 int
 foo (int a)
@@ -16,4 +16,4 @@ foo (int a)
     return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "Replaced" 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump "if \\(a_\[0-9\]+\\(D\\) != 0\\)" "forwprop1" } } */