X+Y < X iff Y<0 moved to match.pd
authorMarc Glisse <marc.glisse@inria.fr>
Wed, 11 Oct 2017 13:18:06 +0000 (15:18 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Wed, 11 Oct 2017 13:18:06 +0000 (13:18 +0000)
2017-10-11  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* fold-const.c (fold_binary_loc) [X +- Y CMP X]: Move ...
* match.pd: ... here.
((T) X == (T) Y): Relax condition.

gcc/testsuite/
* gcc.dg/Wstrict-overflow-7.c: Xfail.
* gcc.dg/pragma-diag-3.c: Likewise.

From-SVN: r253642

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wstrict-overflow-7.c
gcc/testsuite/gcc.dg/pragma-diag-3.c

index 0028fc9a38af23c69cc84ef211de315c03d17c81..d30aa3adf2d7a1b4be3ef070570a91ffc1a16a5e 100644 (file)
@@ -1,3 +1,9 @@
+2017-10-11  Marc Glisse  <marc.glisse@inria.fr>
+
+       * fold-const.c (fold_binary_loc) [X +- Y CMP X]: Move ...
+       * match.pd: ... here.
+       ((T) X == (T) Y): Relax condition.
+
 2017-10-11  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/82472
index f2e1cea2038b2301bb4f076459fe213021cc2fd8..e22b02f13120713ba98b81ac60c34e56d3482a99 100644 (file)
@@ -10502,40 +10502,6 @@ fold_binary_loc (location_t loc,
          && code == NE_EXPR)
         return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
 
-      /* Transform comparisons of the form X +- Y CMP X to Y CMP 0.  */
-      if ((TREE_CODE (arg0) == PLUS_EXPR
-          || TREE_CODE (arg0) == POINTER_PLUS_EXPR
-          || TREE_CODE (arg0) == MINUS_EXPR)
-         && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg0,
-                                                                       0)),
-                             arg1, 0)
-         && (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
-             || POINTER_TYPE_P (TREE_TYPE (arg0))))
-       {
-         tree val = TREE_OPERAND (arg0, 1);
-         val = fold_build2_loc (loc, code, type, val,
-                                build_int_cst (TREE_TYPE (val), 0));
-         return omit_two_operands_loc (loc, type, val,
-                                       TREE_OPERAND (arg0, 0), arg1);
-       }
-
-      /* Transform comparisons of the form X CMP X +- Y to Y CMP 0.  */
-      if ((TREE_CODE (arg1) == PLUS_EXPR
-          || TREE_CODE (arg1) == POINTER_PLUS_EXPR
-          || TREE_CODE (arg1) == MINUS_EXPR)
-         && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1,
-                                                                       0)),
-                             arg0, 0)
-         && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-             || POINTER_TYPE_P (TREE_TYPE (arg1))))
-       {
-         tree val = TREE_OPERAND (arg1, 1);
-         val = fold_build2_loc (loc, code, type, val,
-                                build_int_cst (TREE_TYPE (val), 0));
-         return omit_two_operands_loc (loc, type, val,
-                                       TREE_OPERAND (arg1, 0), arg0);
-       }
-
       /* If this is an EQ or NE comparison with zero and ARG0 is
         (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
         two operations, but the latter can be done in one less insn
@@ -10918,130 +10884,38 @@ fold_binary_loc (location_t loc,
       /* Transform comparisons of the form X +- C CMP X.  */
       if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
-         && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
-              && !HONOR_SNANS (arg0))
-             || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))))
+         && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
+         && !HONOR_SNANS (arg0))
        {
          tree arg01 = TREE_OPERAND (arg0, 1);
          enum tree_code code0 = TREE_CODE (arg0);
-         int is_positive;
-
-         if (TREE_CODE (arg01) == REAL_CST)
-           is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1;
-         else
-           is_positive = tree_int_cst_sgn (arg01);
+         int is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1;
 
          /* (X - c) > X becomes false.  */
          if (code == GT_EXPR
              && ((code0 == MINUS_EXPR && is_positive >= 0)
                  || (code0 == PLUS_EXPR && is_positive <= 0)))
-           {
-             if (TREE_CODE (arg01) == INTEGER_CST
-                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-               fold_overflow_warning (("assuming signed overflow does not "
-                                       "occur when assuming that (X - c) > X "
-                                       "is always false"),
-                                      WARN_STRICT_OVERFLOW_ALL);
-             return constant_boolean_node (0, type);
-           }
+           return constant_boolean_node (0, type);
 
          /* Likewise (X + c) < X becomes false.  */
          if (code == LT_EXPR
              && ((code0 == PLUS_EXPR && is_positive >= 0)
                  || (code0 == MINUS_EXPR && is_positive <= 0)))
-           {
-             if (TREE_CODE (arg01) == INTEGER_CST
-                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-               fold_overflow_warning (("assuming signed overflow does not "
-                                       "occur when assuming that "
-                                       "(X + c) < X is always false"),
-                                      WARN_STRICT_OVERFLOW_ALL);
-             return constant_boolean_node (0, type);
-           }
+           return constant_boolean_node (0, type);
 
          /* Convert (X - c) <= X to true.  */
          if (!HONOR_NANS (arg1)
              && code == LE_EXPR
              && ((code0 == MINUS_EXPR && is_positive >= 0)
                  || (code0 == PLUS_EXPR && is_positive <= 0)))
-           {
-             if (TREE_CODE (arg01) == INTEGER_CST
-                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-               fold_overflow_warning (("assuming signed overflow does not "
-                                       "occur when assuming that "
-                                       "(X - c) <= X is always true"),
-                                      WARN_STRICT_OVERFLOW_ALL);
-             return constant_boolean_node (1, type);
-           }
+           return constant_boolean_node (1, type);
 
          /* Convert (X + c) >= X to true.  */
          if (!HONOR_NANS (arg1)
              && code == GE_EXPR
              && ((code0 == PLUS_EXPR && is_positive >= 0)
                  || (code0 == MINUS_EXPR && is_positive <= 0)))
-           {
-             if (TREE_CODE (arg01) == INTEGER_CST
-                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-               fold_overflow_warning (("assuming signed overflow does not "
-                                       "occur when assuming that "
-                                       "(X + c) >= X is always true"),
-                                      WARN_STRICT_OVERFLOW_ALL);
-             return constant_boolean_node (1, type);
-           }
-
-         if (TREE_CODE (arg01) == INTEGER_CST)
-           {
-             /* Convert X + c > X and X - c < X to true for integers.  */
-             if (code == GT_EXPR
-                 && ((code0 == PLUS_EXPR && is_positive > 0)
-                     || (code0 == MINUS_EXPR && is_positive < 0)))
-               {
-                 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-                   fold_overflow_warning (("assuming signed overflow does "
-                                           "not occur when assuming that "
-                                           "(X + c) > X is always true"),
-                                          WARN_STRICT_OVERFLOW_ALL);
-                 return constant_boolean_node (1, type);
-               }
-
-             if (code == LT_EXPR
-                 && ((code0 == MINUS_EXPR && is_positive > 0)
-                     || (code0 == PLUS_EXPR && is_positive < 0)))
-               {
-                 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-                   fold_overflow_warning (("assuming signed overflow does "
-                                           "not occur when assuming that "
-                                           "(X - c) < X is always true"),
-                                          WARN_STRICT_OVERFLOW_ALL);
-                 return constant_boolean_node (1, type);
-               }
-
-             /* Convert X + c <= X and X - c >= X to false for integers.  */
-             if (code == LE_EXPR
-                 && ((code0 == PLUS_EXPR && is_positive > 0)
-                     || (code0 == MINUS_EXPR && is_positive < 0)))
-               {
-                 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-                   fold_overflow_warning (("assuming signed overflow does "
-                                           "not occur when assuming that "
-                                           "(X + c) <= X is always false"),
-                                          WARN_STRICT_OVERFLOW_ALL);
-                 return constant_boolean_node (0, type);
-               }
-
-             if (code == GE_EXPR
-                 && ((code0 == MINUS_EXPR && is_positive > 0)
-                     || (code0 == PLUS_EXPR && is_positive < 0)))
-               {
-                 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
-                   fold_overflow_warning (("assuming signed overflow does "
-                                           "not occur when assuming that "
-                                           "(X - c) >= X is always false"),
-                                          WARN_STRICT_OVERFLOW_ALL);
-                 return constant_boolean_node (0, type);
-               }
-           }
+           return constant_boolean_node (1, type);
        }
 
       /* If we are comparing an ABS_EXPR with a constant, we can
index 2f8a7411d76b8333adf51cd876a016275bc7f377..f2c43737b800d650e36f899551b87435f74dba81 100644 (file)
@@ -1280,6 +1280,44 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
           || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))))
    (op @1 @0))))
 
+/* X + Y < Y is the same as X < 0 when there is no overflow.  */
+(for op (lt le gt ge)
+ (simplify
+  (op:c (plus:c@2 @0 @1) @1)
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+       && (CONSTANT_CLASS_P (@0) || single_use (@2)))
+   (op @0 { build_zero_cst (TREE_TYPE (@0)); }))))
+/* For equality, this is also true with wrapping overflow.  */
+(for op (eq ne)
+ (simplify
+  (op:c (nop_convert@3 (plus:c@2 @0 (convert1? @1))) (convert2? @1))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+          || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+       && (CONSTANT_CLASS_P (@0) || (single_use (@2) && single_use (@3)))
+       && tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@2))
+       && tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@1)))
+   (op @0 { build_zero_cst (TREE_TYPE (@0)); })))
+ (simplify
+  (op:c (nop_convert@3 (pointer_plus@2 (convert1? @0) @1)) (convert2? @0))
+  (if (tree_nop_conversion_p (TREE_TYPE (@2), TREE_TYPE (@0))
+       && tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0))
+       && (CONSTANT_CLASS_P (@1) || (single_use (@2) && single_use (@3))))
+   (op @1 { build_zero_cst (TREE_TYPE (@1)); }))))
+
+/* X - Y < X is the same as Y > 0 when there is no overflow.
+   For equality, this is also true with wrapping overflow.  */
+(for op (simple_comparison)
+ (simplify
+  (op:c @0 (minus@2 @0 @1))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+          || ((op == EQ_EXPR || op == NE_EXPR)
+              && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))))
+       && (CONSTANT_CLASS_P (@1) || single_use (@2)))
+   (op @1 { build_zero_cst (TREE_TYPE (@1)); }))))
+
 /* Transform:
  * (X / Y) == 0 -> X < Y if X, Y are unsigned.
  * (X / Y) != 0 -> X >= Y, if X, Y are unsigned.
@@ -3125,7 +3163,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (op (abs @0) zerop@1)
   (op @0 @1)))
 
-/* From fold_sign_changed_comparison and fold_widened_comparison.  */
+/* From fold_sign_changed_comparison and fold_widened_comparison.
+   FIXME: the lack of symmetry is disturbing.  */
 (for cmp (simple_comparison)
  (simplify
   (cmp (convert@0 @00) (convert?@1 @10))
@@ -3138,11 +3177,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && single_use (@0))
    (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))))
+           || @1 != @10)
        && (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))))
+       && !POINTER_TYPE_P (TREE_TYPE (@00)))
     /* ???  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.  */
index 23fccba5a677604848f48e973c0725d01c8c1739..20f7b0f132c5ddbbddba8a53ec6c9520965e9080 100644 (file)
@@ -1,3 +1,8 @@
+2017-10-11  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/Wstrict-overflow-7.c: Xfail.
+       * gcc.dg/pragma-diag-3.c: Likewise.
+
 2017-10-11  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/82472
index 5bf7b6005ca00daf5419180e21c20cb4c7691af3..401cbc3c98717d959210e9418111c1be3266fcdf 100644 (file)
@@ -6,5 +6,5 @@
 int
 foo (int i)
 {
-  return i + 10 > i; /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
+  return i + 10 > i; /* { dg-warning "assuming signed overflow does not occur" "correct warning" { xfail *-*-* } } */
 }
index 2ee439d7e338eac1ef2eae7aa8489cf74680f60c..b6ee60f16770924a1e882f10b0c9376ff040c568 100644 (file)
@@ -15,7 +15,7 @@ void testing2() {
 
 void testing3() {
   int k = 4;
-  k + 4 < k; /* { dg-error "overflow" } */
+  k + 4 < k; /* { dg-error "overflow" "" { xfail *-*-* } } */
 }
 
 int bar()