common.opt: Add fstrict-overflow.
authorIan Lance Taylor <iant@google.com>
Sun, 28 Jan 2007 05:15:06 +0000 (05:15 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sun, 28 Jan 2007 05:15:06 +0000 (05:15 +0000)
./: * common.opt: Add fstrict-overflow.
* opts.c (decode_options): Set flag_strict_overflow if -O2.
* flags.h (TYPE_OVERFLOW_WRAPS): Define.
(TYPE_OVERFLOW_UNDEFINED): Define.
(TYPE_OVERFLOW_TRAPS): Define.  This replaces TYPE_TRAP_SIGNED.
Replace all uses.
* tree.h (TYPE_TRAP_SIGNED): Don't define.
* fold-const.c (negate_expr_p): Use TYPE_OVERFLOW_UNDEFINED.
(fold_negate_expr): Likewise.
(make_range): Likewise.
(extract_muldiv_1): Likewise.
(maybe_canonicalize_comparison): Likewise.
(fold_comparison): Likewise.
(fold_binary): Likewise.
(tree_expr_nonnegative_p): Likewise.
(tree_expr_nonzero_p): Likewise.
* tree-vrp.c (compare_values): Likewise.
(extract_range_from_binary_expr): Likewise.
(extract_range_from_unary_expr): Likewise.
* tree-ssa-loop-niter.c (infer_loop_bounds_from_signedness):
Likewise.
(nowrap_type_p): Likewise.
* tree-scalar-evolution.c (simple_iv): Likewise.
* fold-const.c (negate_expr_p): Use TYPE_OVERFLOW_WRAPS.
(build_range_check): Likewise.
(extract_muldiv_1): Likewise.
(fold_comparison): Likewise.
* tree-vrp.c (vrp_int_const_binop): Likewise.
(extract_range_from_unary_expr): Likewise.
* convert.c (convert_to_integer): Likewise.
* fold-const.c (fold_negate_expr): Use TYPE_OVERFLOW_TRAPS.
(fold_comparison): Likewise.
(fold_binary): Likewise.
* optabs.c (optab_for_tree_code): Likewise.
* tree-vectorizer.c (vect_is_simple_reduction): Likewise.
* simplify-rtx.c (simplify_const_relational_operation): Check
flag_strict_overflow and flag_trapv.
(simplify_const_relational_operation): Likewise.
* doc/invoke.texi (Option Summary): Mention -fstrict-overflow.
(Optimize Options): Add -fstrict-overflow to -O2 list.  Document
-fstrict-overflow.
testsuite/:
* gcc.dg/strict-overflow-1.c: New test.
* gcc.dg/no-strict-overflow-1.c: New test.
* gcc.dg/strict-overflow-2.c: New test.
* gcc.dg/no-strict-overflow-2.c: New test.
* gcc.dg/strict-overflow-3.c: New test.
* gcc.dg/no-strict-overflow-3.c: New test.
* gcc.dg/strict-overflow-4.c: New test.
* gcc.dg/no-strict-overflow-4.c: New test.
* gcc.dg/fold-mod-1.c: Add -fstrict-overflow option.
* gcc.dg/pr15784-1.c: Likewise.
* gcc.dg/pr20922-1.c: Likewise.
* gcc.dg/pr20922-3.c: Likewise.
* gcc.dg/pr20922-4.c: Likewise.
* gcc.dg/pr20922-6.c: Likewise.
* gcc.dg/compare-4.c: Likewise.
* gcc.dg/torture/pr26898-1.c: Likewise.
* gcc.dg/tree-ssa/divide-1.c: Likewise.
* gcc.dg/tree-ssa/divide-2.c: Likewise.
* gcc.dg/tree-ssa/divide-3.c: Likewise.
* gcc.dg/tree-ssa/divide-4.c: Likewise.
* gcc.dg/tree-ssa/pr14490-1.c: Likewise.
* gcc.dg/tree-ssa/pr14490-3.c: Likewise.
* gcc.dg/tree-ssa/pr21082.c: Likewise.
* gcc.dg/tree-ssa/pr26899.c: Likewise.
* g++.dg/tree-ssa/pr21082.C: Likewise.

From-SVN: r121254

41 files changed:
gcc/ChangeLog
gcc/common.opt
gcc/convert.c
gcc/doc/invoke.texi
gcc/flags.h
gcc/fold-const.c
gcc/optabs.c
gcc/opts.c
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr21082.C
gcc/testsuite/gcc.dg/compare4.c
gcc/testsuite/gcc.dg/fold-mod-1.c
gcc/testsuite/gcc.dg/no-strict-overflow-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/no-strict-overflow-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/no-strict-overflow-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/no-strict-overflow-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr15784-1.c
gcc/testsuite/gcc.dg/pr20922-1.c
gcc/testsuite/gcc.dg/pr20922-3.c
gcc/testsuite/gcc.dg/pr20922-4.c
gcc/testsuite/gcc.dg/pr20922-6.c
gcc/testsuite/gcc.dg/strict-overflow-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strict-overflow-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strict-overflow-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strict-overflow-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr26898-1.c
gcc/testsuite/gcc.dg/tree-ssa/divide-1.c
gcc/testsuite/gcc.dg/tree-ssa/divide-2.c
gcc/testsuite/gcc.dg/tree-ssa/divide-3.c
gcc/testsuite/gcc.dg/tree-ssa/divide-4.c
gcc/testsuite/gcc.dg/tree-ssa/pr14490-1.c
gcc/testsuite/gcc.dg/tree-ssa/pr14490-3.c
gcc/testsuite/gcc.dg/tree-ssa/pr26899.c
gcc/tree-eh.c
gcc/tree-scalar-evolution.c
gcc/tree-ssa-loop-niter.c
gcc/tree-vect-generic.c
gcc/tree-vectorizer.c
gcc/tree-vrp.c
gcc/tree.h

index 6d3de89adaa2fe3b26e4f128f590249adb90f1b0..a2129d3e34b2a1056dca91917a2b97ae4c405d7b 100644 (file)
@@ -1,3 +1,47 @@
+2007-01-27  Ian Lance Taylor  <iant@google.com>
+
+       * common.opt: Add fstrict-overflow.
+       * opts.c (decode_options): Set flag_strict_overflow if -O2.
+       * flags.h (TYPE_OVERFLOW_WRAPS): Define.
+       (TYPE_OVERFLOW_UNDEFINED): Define.
+       (TYPE_OVERFLOW_TRAPS): Define.  This replaces TYPE_TRAP_SIGNED.
+       Replace all uses.
+       * tree.h (TYPE_TRAP_SIGNED): Don't define.
+       * fold-const.c (negate_expr_p): Use TYPE_OVERFLOW_UNDEFINED.
+       (fold_negate_expr): Likewise.
+       (make_range): Likewise.
+       (extract_muldiv_1): Likewise.
+       (maybe_canonicalize_comparison): Likewise.
+       (fold_comparison): Likewise.
+       (fold_binary): Likewise.
+       (tree_expr_nonnegative_p): Likewise.
+       (tree_expr_nonzero_p): Likewise.
+       * tree-vrp.c (compare_values): Likewise.
+       (extract_range_from_binary_expr): Likewise.
+       (extract_range_from_unary_expr): Likewise.
+       * tree-ssa-loop-niter.c (infer_loop_bounds_from_signedness):
+       Likewise.
+       (nowrap_type_p): Likewise.
+       * tree-scalar-evolution.c (simple_iv): Likewise.
+       * fold-const.c (negate_expr_p): Use TYPE_OVERFLOW_WRAPS.
+       (build_range_check): Likewise.
+       (extract_muldiv_1): Likewise.
+       (fold_comparison): Likewise.
+       * tree-vrp.c (vrp_int_const_binop): Likewise.
+       (extract_range_from_unary_expr): Likewise.
+       * convert.c (convert_to_integer): Likewise.
+       * fold-const.c (fold_negate_expr): Use TYPE_OVERFLOW_TRAPS.
+       (fold_comparison): Likewise.
+       (fold_binary): Likewise.
+       * optabs.c (optab_for_tree_code): Likewise.
+       * tree-vectorizer.c (vect_is_simple_reduction): Likewise.
+       * simplify-rtx.c (simplify_const_relational_operation): Check
+       flag_strict_overflow and flag_trapv.
+       (simplify_const_relational_operation): Likewise.
+       * doc/invoke.texi (Option Summary): Mention -fstrict-overflow.
+       (Optimize Options): Add -fstrict-overflow to -O2 list.  Document
+       -fstrict-overflow.
+
 2007-01-27  Roger Sayle  <roger@eyesopen.com>
 
        * tree.c (tree_fold_gcd): Delete.
index 0a0d287c78a8bbbcbdcd35ecc73b4e12e48c6d93..0f6f7ec16c50dfbda01bb0a5828e54752b69d723 100644 (file)
@@ -902,6 +902,10 @@ fstrict-aliasing
 Common Report Var(flag_strict_aliasing)
 Assume strict aliasing rules apply
 
+fstrict-overflow
+Common Report Var(flag_strict_overflow)
+Treat signed overflow as undefined
+
 fsyntax-only
 Common Report Var(flag_syntax_only)
 Check for syntax errors, then stop
index b7d26ee3c0a0a148fb8e8f752ee67aa36af9cbf5..af97d2a75901279dc3fe5b5625bbb0f4c4b4d420 100644 (file)
@@ -661,11 +661,10 @@ convert_to_integer (tree type, tree expr)
                           PLUS_EXPR or MINUS_EXPR in an unsigned
                           type.  Otherwise, we would introduce
                           signed-overflow undefinedness.  */
-                       || (!flag_wrapv
+                       || ((!TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))
+                            || !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
                            && (ex_form == PLUS_EXPR
-                               || ex_form == MINUS_EXPR)
-                           && (!TYPE_UNSIGNED (TREE_TYPE (arg0))
-                               || !TYPE_UNSIGNED (TREE_TYPE (arg1)))))
+                               || ex_form == MINUS_EXPR)))
                      typex = lang_hooks.types.unsigned_type (typex);
                    else
                      typex = lang_hooks.types.signed_type (typex);
index fee5871dc89617f03e2fc9d30483be194992f2ee..eb55c9b321a5ae7ac71f91269a178c0bdf74cdb0 100644 (file)
@@ -341,7 +341,7 @@ Objective-C and Objective-C++ Dialects}.
 -fsched2-use-traces -fsee -freschedule-modulo-scheduled-loops @gol
 -fsection-anchors  -fsignaling-nans  -fsingle-precision-constant @gol
 -fstack-protector  -fstack-protector-all @gol
--fstrict-aliasing  -ftracer  -fthread-jumps @gol
+-fstrict-aliasing  -fstrict-overflow  -ftracer  -fthread-jumps @gol
 -funroll-all-loops  -funroll-loops  -fpeel-loops @gol
 -fsplit-ivs-in-unroller -funswitch-loops @gol
 -fvariable-expansion-in-unroller @gol
@@ -4635,7 +4635,7 @@ also turns on the following optimization flags:
 -fschedule-insns  -fschedule-insns2 @gol
 -fsched-interblock  -fsched-spec @gol
 -fregmove @gol
--fstrict-aliasing @gol
+-fstrict-aliasing -fstrict-overflow @gol
 -fdelete-null-pointer-checks @gol
 -freorder-blocks  -freorder-functions @gol
 -falign-functions  -falign-jumps @gol
@@ -5465,6 +5465,32 @@ int f() @{
 
 Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
 
+@item -fstrict-overflow
+@opindex fstrict-overflow
+Allow the compiler to assume strict signed overflow rules, depending
+on the language being compiled.  For C (and C++) this means that
+overflow when doing arithmetic with signed numbers is undefined, which
+means that the compiler may assume that it will not happen.  This
+permits various optimizations.  For example, the compiler will assume
+that an expression like @code{i + 10 > i} will always be true for
+signed @code{i}.  This assumption is only valid if signed overflow is
+undefined, as the expression is false if @code{i + 10} overflows when
+using twos complement arithmetic.  When this option is in effect any
+attempt to determine whether an operation on signed numbers will
+overflow must be written carefully to not actually involve overflow.
+
+See also the @option{-fwrapv} option.  Using @option{-fwrapv} means
+that signed overflow is fully defined: it wraps.  When
+@option{-fwrapv} is used, there is no difference between
+@option{-fstrict-overflow} and @option{-fno-strict-overflow}.  With
+@option{-fwrapv} certain types of overflow are permitted.  For
+example, if the compiler gets an overflow when doing arithmetic on
+constants, the overflowed value can still be used with
+@option{-fwrapv}, but not otherwise.
+
+The @option{-fstrict-overflow} option is enabled at levels
+@option{-O2}, @option{-O3}, @option{-Os}.
+
 @item -falign-functions
 @itemx -falign-functions=@var{n}
 @opindex falign-functions
index ce9d6d7bb907cbfb3c808c747af29dc8f01b6f50..d2c1ca02cf083d3157c87275aded68545da0b847 100644 (file)
@@ -1,6 +1,6 @@
 /* Compilation switch flag definitions for GCC.
    Copyright (C) 1987, 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
-   2003, 2004, 2005
+   2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -288,4 +288,20 @@ extern const char *flag_random_seed;
 #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
   (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && flag_rounding_math)
 
+/* True if overflow wraps around for the given integral type.  That
+   is, TYPE_MAX + 1 == TYPE_MIN.  */
+#define TYPE_OVERFLOW_WRAPS(TYPE) \
+  (TYPE_UNSIGNED (TYPE) || flag_wrapv)
+
+/* True if overflow is undefined for the given integral type.  We may
+   optimize on the assumption that values in the type never
+   overflow.  */
+#define TYPE_OVERFLOW_UNDEFINED(TYPE) \
+  (!TYPE_UNSIGNED (TYPE) && !flag_wrapv && !flag_trapv && flag_strict_overflow)
+
+/* True if overflow for the given integral type should issue a
+   trap.  */
+#define TYPE_OVERFLOW_TRAPS(TYPE) \
+  (!TYPE_UNSIGNED (TYPE) && flag_trapv)
+
 #endif /* ! GCC_FLAGS_H */
index 34ff7111072eb910d37108848657e1cf9526c162..a7a12eb1d92a8f6ca545bf166573895436d81a9b 100644 (file)
@@ -994,16 +994,14 @@ negate_expr_p (tree t)
   switch (TREE_CODE (t))
     {
     case INTEGER_CST:
-      if (TYPE_UNSIGNED (type)
-         || (flag_wrapv && ! flag_trapv))
+      if (TYPE_OVERFLOW_WRAPS (type))
        return true;
 
       /* Check that -CST will not overflow type.  */
       return may_negate_without_overflow_p (t);
     case BIT_NOT_EXPR:
-       return INTEGRAL_TYPE_P (type)
-                     && (TYPE_UNSIGNED (type)
-                 || (flag_wrapv && !flag_trapv));
+      return (INTEGRAL_TYPE_P (type)
+             && TYPE_OVERFLOW_WRAPS (type));
 
     case REAL_CST:
     case NEGATE_EXPR:
@@ -1049,7 +1047,8 @@ negate_expr_p (tree t)
     case FLOOR_DIV_EXPR:
     case CEIL_DIV_EXPR:
     case EXACT_DIV_EXPR:
-      if (TYPE_UNSIGNED (TREE_TYPE (t)) || flag_wrapv)
+      if (INTEGRAL_TYPE_P (TREE_TYPE (t))
+         && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
         break;
       return negate_expr_p (TREE_OPERAND (t, 1))
              || negate_expr_p (TREE_OPERAND (t, 0));
@@ -1111,8 +1110,7 @@ fold_negate_expr (tree t)
     case INTEGER_CST:
       tem = fold_negate_const (t, type);
       if (!TREE_OVERFLOW (tem)
-         || TYPE_UNSIGNED (type)
-         || !flag_trapv)
+         || !TYPE_OVERFLOW_TRAPS (type))
        return tem;
       break;
 
@@ -1197,7 +1195,7 @@ fold_negate_expr (tree t)
     case FLOOR_DIV_EXPR:
     case CEIL_DIV_EXPR:
     case EXACT_DIV_EXPR:
-      if (!TYPE_UNSIGNED (type) && !flag_wrapv)
+      if (!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
         {
           tem = TREE_OPERAND (t, 1);
           if (negate_expr_p (tem))
@@ -3981,7 +3979,8 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
 
          /* If flag_wrapv and ARG0_TYPE is signed, then we cannot
             move a constant to the other side.  */
-         if (flag_wrapv && !TYPE_UNSIGNED (arg0_type))
+         if (!TYPE_UNSIGNED (arg0_type)
+             && !TYPE_OVERFLOW_UNDEFINED (arg0_type))
            break;
 
          /* If EXP is signed, any overflow in the computation is undefined,
@@ -4231,7 +4230,7 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
 
   /* If we don't have wrap-around arithmetics upfront, try to force it.  */
   if (TREE_CODE (etype) == INTEGER_TYPE
-      && !TYPE_UNSIGNED (etype) && !flag_wrapv)
+      && !TYPE_OVERFLOW_WRAPS (etype))
     {
       tree utype, minv, maxv;
 
@@ -5630,7 +5629,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
                             fold_convert (ctype, c), 0);
          /* We allow the constant to overflow with wrapping semantics.  */
          if (op1 == 0
-             || (TREE_OVERFLOW (op1) && ! flag_wrapv))
+             || (TREE_OVERFLOW (op1) && !TYPE_OVERFLOW_WRAPS (ctype)))
            break;
        }
       else
@@ -5704,9 +5703,8 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
         If we have an unsigned type that is not a sizetype, we cannot do
         this since it will change the result if the original computation
         overflowed.  */
-      if ((! TYPE_UNSIGNED (ctype)
+      if ((TYPE_OVERFLOW_UNDEFINED (ctype)
           || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
-         && ! flag_wrapv
          && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
              || (tcode == MULT_EXPR
                  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
@@ -7929,9 +7927,8 @@ maybe_canonicalize_comparison (enum tree_code code, tree type,
 
   /* In principle pointers also have undefined overflow behavior,
      but that causes problems elsewhere.  */
-  if ((flag_wrapv || flag_trapv)
-      || (TYPE_UNSIGNED (TREE_TYPE (arg0))
-         || POINTER_TYPE_P (TREE_TYPE (arg0))))
+  if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
+      || POINTER_TYPE_P (TREE_TYPE (arg0)))
     return NULL_TREE;
 
   /* Try canonicalization by simplifying arg0.  */
@@ -7976,8 +7973,7 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
   if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
       && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
          && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
-         && !TYPE_UNSIGNED (TREE_TYPE (arg1))
-         && !(flag_wrapv || flag_trapv))
+         && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
       && (TREE_CODE (arg1) == INTEGER_CST
          && !TREE_OVERFLOW (arg1)))
     {
@@ -8104,9 +8100,15 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
      same object, then we can fold this to a comparison of the two offsets in
      signed size type.  This is possible because pointer arithmetic is
      restricted to retain within an object and overflow on pointer differences
-     is undefined as of 6.5.6/8 and /9 with respect to the signed ptrdiff_t.  */
+     is undefined as of 6.5.6/8 and /9 with respect to the signed ptrdiff_t.
+
+     We check flag_wrapv directly because pointers types are unsigned,
+     and therefore TYPE_OVERFLOW_WRAPS returns true for them.  That is
+     normally what we want to avoid certain odd overflow cases, but
+     not here.  */
   if (POINTER_TYPE_P (TREE_TYPE (arg0))
-      && !flag_wrapv && !flag_trapv)
+      && !flag_wrapv
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (arg0)))
     {
       tree base0, offset0, base1, offset1;
 
@@ -8139,8 +8141,7 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
      X CMP Y +- C2 +- C1 for signed X, Y.  This is valid if
      the resulting offset is smaller in absolute value than the
      original one.  */
-  if (!(flag_wrapv || flag_trapv)
-      && !TYPE_UNSIGNED (TREE_TYPE (arg0))
+  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
       && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
       && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
          && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
@@ -8181,8 +8182,7 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
      signed arithmetic case.  That form is created by the compiler
      often enough for folding it to be of value.  One example is in
      computing loop trip counts after Operator Strength Reduction.  */
-  if (!(flag_wrapv || flag_trapv)
-      && !TYPE_UNSIGNED (TREE_TYPE (arg0))
+  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
       && TREE_CODE (arg0) == MULT_EXPR
       && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
           && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
@@ -8802,7 +8802,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          /* ~X + X is -1.  */
          if (TREE_CODE (arg0) == BIT_NOT_EXPR
              && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
-             && !TYPE_TRAP_SIGNED (type))
+             && !TYPE_OVERFLOW_TRAPS (type))
            {
              t1 = build_int_cst_type (type, -1);
              return omit_one_operand (type, t1, arg1);
@@ -8811,7 +8811,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          /* X + ~X is -1.  */
          if (TREE_CODE (arg1) == BIT_NOT_EXPR
              && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)
-             && !TYPE_TRAP_SIGNED (type))
+             && !TYPE_OVERFLOW_TRAPS (type))
            {
              t1 = build_int_cst_type (type, -1);
              return omit_one_operand (type, t1, arg0);
@@ -9158,7 +9158,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
       if (INTEGRAL_TYPE_P (type)
          && TREE_CODE (arg0) == NEGATE_EXPR
          && integer_onep (arg1)
-         && !TYPE_TRAP_SIGNED (type))
+         && !TYPE_OVERFLOW_TRAPS (type))
        return fold_build1 (BIT_NOT_EXPR, type,
                            fold_convert (type, TREE_OPERAND (arg0, 0)));
 
@@ -10277,12 +10277,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
 
       /* Convert -A / -B to A / B when the type is signed and overflow is
         undefined.  */
-      if (!TYPE_UNSIGNED (type) && !flag_wrapv
+      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
          && TREE_CODE (arg0) == NEGATE_EXPR
          && negate_expr_p (arg1))
        return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
                            negate_expr (arg1));
-      if (!TYPE_UNSIGNED (type) && !flag_wrapv
+      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
          && TREE_CODE (arg1) == NEGATE_EXPR
          && negate_expr_p (arg0))
        return fold_build2 (code, type, negate_expr (arg0),
@@ -10357,7 +10357,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          && TREE_CODE (arg1) == INTEGER_CST
          && !TREE_OVERFLOW (arg1)
          && TREE_INT_CST_HIGH (arg1) < 0
-         && !flag_trapv
+         && !TYPE_OVERFLOW_TRAPS (type)
          /* Avoid this transformation if C is INT_MIN, i.e. C == -C.  */
          && !sign_bit_p (arg1, arg1))
        return fold_build2 (code, type, fold_convert (type, arg0),
@@ -10367,7 +10367,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
       if (code == TRUNC_MOD_EXPR
          && !TYPE_UNSIGNED (type)
          && TREE_CODE (arg1) == NEGATE_EXPR
-         && !flag_trapv)
+         && !TYPE_OVERFLOW_TRAPS (type))
        return fold_build2 (code, type, fold_convert (type, arg0),
                            fold_convert (type, TREE_OPERAND (arg1, 0)));
 
@@ -11187,8 +11187,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
               && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))))
              || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-                 && !TYPE_UNSIGNED (TREE_TYPE (arg1))
-                 && !(flag_wrapv || flag_trapv))))
+                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))))
        {
          tree arg01 = TREE_OPERAND (arg0, 1);
          enum tree_code code0 = TREE_CODE (arg0);
@@ -12556,8 +12555,10 @@ tree_expr_nonnegative_p (tree t)
     case ABS_EXPR:
       /* We can't return 1 if flag_wrapv is set because
         ABS_EXPR<INT_MIN> = INT_MIN.  */
-      if (!(flag_wrapv && INTEGRAL_TYPE_P (TREE_TYPE (t))))
-        return true;
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+       return true;
+      if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
+       return true;
       break;
 
     case INTEGER_CST:
@@ -12863,7 +12864,7 @@ tree_expr_nonzero_p (tree t)
       return !integer_zerop (t);
 
     case PLUS_EXPR:
-      if (!TYPE_UNSIGNED (type) && !flag_wrapv)
+      if (TYPE_OVERFLOW_UNDEFINED (type))
        {
          /* With the presence of negative values it is hard
             to say something.  */
@@ -12877,7 +12878,7 @@ tree_expr_nonzero_p (tree t)
       break;
 
     case MULT_EXPR:
-      if (!TYPE_UNSIGNED (type) && !flag_wrapv)
+      if (TYPE_OVERFLOW_UNDEFINED (type))
        {
          return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
                  && tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
index 9a7731d221434b76dc62bc511b929368a92e8900..c7f16c29e5991d3c33da54e38ddd3403d2ca090d 100644 (file)
@@ -1,6 +1,7 @@
 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -341,7 +342,7 @@ optab_for_tree_code (enum tree_code code, tree type)
       break;
     }
 
-  trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
+  trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
   switch (code)
     {
     case PLUS_EXPR:
index 6720af1332a213d90579728e8830d7ce92872d72..b75fcb39d50aead98174269551200078220efbce 100644 (file)
@@ -1,5 +1,6 @@
 /* Command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 This file is part of GCC.
@@ -487,6 +488,7 @@ decode_options (unsigned int argc, const char **argv)
 #endif
       flag_regmove = 1;
       flag_strict_aliasing = 1;
+      flag_strict_overflow = 1;
       flag_delete_null_pointer_checks = 1;
       flag_reorder_blocks = 1;
       flag_reorder_functions = 1;
index 2199c634b83d649fb23c2cf83b9f26cfc5dd10a6..0ce80c7f6c2f1ff96543cda265f2b98125ad1567 100644 (file)
@@ -1,6 +1,7 @@
 /* RTL simplification functions for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -3939,7 +3940,8 @@ simplify_const_relational_operation (enum rtx_code code,
          /* Optimize abs(x) < 0.0.  */
          if (trueop1 == CONST0_RTX (mode)
              && !HONOR_SNANS (mode)
-             && !(flag_wrapv && INTEGRAL_MODE_P (mode)))
+             && (!INTEGRAL_MODE_P (mode)
+                 || (!flag_wrapv && !flag_trapv && flag_strict_overflow)))
            {
              tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
                                                       : trueop0;
@@ -3952,7 +3954,8 @@ simplify_const_relational_operation (enum rtx_code code,
          /* Optimize abs(x) >= 0.0.  */
          if (trueop1 == CONST0_RTX (mode)
              && !HONOR_NANS (mode)
-             && !(flag_wrapv && INTEGRAL_MODE_P (mode)))
+             && (!INTEGRAL_MODE_P (mode)
+                 || (!flag_wrapv && !flag_trapv && flag_strict_overflow)))
            {
              tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
                                                       : trueop0;
index 9ed1d06b7ba65bd9384466d6397b0207f79ebf68..7278fb7fa40da2f66b02fc478a00ed87b81dbf5e 100644 (file)
@@ -1,3 +1,31 @@
+2007-01-27  Ian Lance Taylor  <iant@google.com>
+
+       * gcc.dg/strict-overflow-1.c: New test.
+       * gcc.dg/no-strict-overflow-1.c: New test.
+       * gcc.dg/strict-overflow-2.c: New test.
+       * gcc.dg/no-strict-overflow-2.c: New test.
+       * gcc.dg/strict-overflow-3.c: New test.
+       * gcc.dg/no-strict-overflow-3.c: New test.
+       * gcc.dg/strict-overflow-4.c: New test.
+       * gcc.dg/no-strict-overflow-4.c: New test.
+       * gcc.dg/fold-mod-1.c: Add -fstrict-overflow option.
+       * gcc.dg/pr15784-1.c: Likewise.
+       * gcc.dg/pr20922-1.c: Likewise.
+       * gcc.dg/pr20922-3.c: Likewise.
+       * gcc.dg/pr20922-4.c: Likewise.
+       * gcc.dg/pr20922-6.c: Likewise.
+       * gcc.dg/compare-4.c: Likewise.
+       * gcc.dg/torture/pr26898-1.c: Likewise.
+       * gcc.dg/tree-ssa/divide-1.c: Likewise.
+       * gcc.dg/tree-ssa/divide-2.c: Likewise.
+       * gcc.dg/tree-ssa/divide-3.c: Likewise.
+       * gcc.dg/tree-ssa/divide-4.c: Likewise.
+       * gcc.dg/tree-ssa/pr14490-1.c: Likewise.
+       * gcc.dg/tree-ssa/pr14490-3.c: Likewise.
+       * gcc.dg/tree-ssa/pr21082.c: Likewise.
+       * gcc.dg/tree-ssa/pr26899.c: Likewise.
+       * g++.dg/tree-ssa/pr21082.C: Likewise.
+
 2007-01-27  Roger Sayle  <roger@eyesopen.com>
 
        * gcc-dg/large-size-array-3.c: New test case.
index dab630fa503c0d01e60f3392a1755d880ec0e2b3..7c4261686abaf41b12e45b38d0ff1e58398f0fc8 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do link } */
+/* { dg-options "-fstrict-overflow" } */
 
 void link_error();
 
index 5f567c5df79d54539fc4c9417b635ef188e39ea3..aae7cbee32d888767164acb9388117e8692cd892 100644 (file)
@@ -2,7 +2,7 @@
    Origin: Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 5/13/2001.  */
 
 /* { dg-do compile } */
-/* { dg-options "-Wsign-compare" } */
+/* { dg-options "-Wsign-compare -fstrict-overflow" } */
 
 extern void bar(void);
 
@@ -21,7 +21,8 @@ int foo(int x, int y, unsigned u)
   if ((x ? 10 : (bar(),bar(),bar(),bar(),x==y)) < u)
     return x;
 
-  /* Test an ABS_EXPR, which is by definition non-negative.  */
+  /* Test an ABS_EXPR, which is by definition non-negative when
+     -fstrict-overflow is used.  */
   if (u < __builtin_abs(x))
     return x;
   if (__builtin_abs(x) < u)
index a8e2a5802ddcdb1c28f4fa75d4ef2505c9b2cc7a..bd4322e2a80fdc124b5547e84ef58a4e85e50ff9 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target int32plus } */
-/* { dg-options "-fdump-tree-gimple" } */
+/* { dg-options "-fdump-tree-gimple -fstrict-overflow" } */
 
 #define ABS(x) (x > 0 ? x : -x)
 
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-1.c b/gcc/testsuite/gcc.dg/no-strict-overflow-1.c
new file mode 100644 (file)
index 0000000..6d449ca
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of strict-overflow-1.c.  */
+
+/* We can only simplify the conditional when using strict overflow
+   semantics.  */
+
+int
+foo (int i)
+{
+  return i - 5 < 10;
+}
+
+/* { dg-final { scan-tree-dump "-[ ]*5" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-2.c b/gcc/testsuite/gcc.dg/no-strict-overflow-2.c
new file mode 100644 (file)
index 0000000..cfe4bc1
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of strict-overflow-2.c.  */
+
+/* We can only simplify the division when using strict overflow
+   semantics.  */
+
+int
+foo (int i)
+{
+  return (i * 100) / 10;
+}
+
+/* { dg-final { scan-tree-dump "100" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-3.c b/gcc/testsuite/gcc.dg/no-strict-overflow-3.c
new file mode 100644 (file)
index 0000000..a981179
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of strict-overflow-3.c.  */
+
+/* We can only simplify the conditional when using strict overflow
+   semantics.  */
+
+int
+foo (int i, int j)
+{
+  return i + 100 < j + 1000;
+}
+
+/* { dg-final { scan-tree-dump "1000" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c
new file mode 100644 (file)
index 0000000..da6264a
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of strict-overflow-4.c.  */
+
+/* We can only simplify the conditional when using strict overflow
+   semantics.  */
+
+int
+foo (int i)
+{
+  return i + 1 > i;
+}
+
+/* We expect to see "<bb N>"; confirm that, so that we know to count
+   it in the real test.  */
+/* { dg-final { scan-tree-dump-times "<bb\[^>\]*>" 1 "final_cleanup" } } */
+/* { dg-final { scan-tree-dump-times ">|<" 3 "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
index 0e492a3babe13cb0c0af7b88e341441dd95905a3..77e398e1da8687779992301fced5f890bdad4649 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fdump-tree-gimple" } */
+/* { dg-options "-fstrict-overflow -fdump-tree-gimple" } */
 /* Test for folding abs(x) where appropriate.  */
 #define abs(x) x > 0 ? x : -x
 extern double fabs (double);
index 64a75f525663ffda155b90e52b5bcc3be6c64290..cfa8a29ef7ee8d55e8304b9dd4c8a0ccd1cbe94b 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fno-wrapv -fdump-tree-gimple" } */
+/* { dg-options "-fno-wrapv -fstrict-overflow -fdump-tree-gimple" } */
 int f(int i)
 {
   return (i - 2) > i;
index ce400528d630a1e727560a8e6890ebce4a0562ca..84ecafef968eea6b98d16db5dc24033cdda0898a 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-ffast-math -fno-wrapv -fdump-tree-gimple" } */
+/* { dg-options "-ffast-math -fno-wrapv -fstrict-overflow -fdump-tree-gimple" } */
 int f(int i)
 {
   return (i - 2) <= i;
index 9b95b3829345bf31930dbc3dd5724c113d9e7d28..0240435fad2d28cfa0b7fde6cba69f1f34466ac9 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fno-wrapv -fdump-tree-gimple" } */
+/* { dg-options "-fno-wrapv -fstrict-overflow -fdump-tree-gimple" } */
 int f(int i)
 {
   return i < (i - 2);
index 0c099bd38211fa633d7853fcbaf93af3edee776d..65a8f1d568125d4a6d443e9f4badb891cf67f680 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-ffast-math -fno-wrapv -fdump-tree-gimple" } */
+/* { dg-options "-ffast-math -fno-wrapv -fstrict-overflow -fdump-tree-gimple" } */
 int f(int i)
 {
   return i >= (i - 2);
diff --git a/gcc/testsuite/gcc.dg/strict-overflow-1.c b/gcc/testsuite/gcc.dg/strict-overflow-1.c
new file mode 100644 (file)
index 0000000..1ff96f4
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of no-strict-overflow-1.c.  */
+
+/* We can only simplify the conditional when using strict overflow
+   semantics.  */
+
+int
+foo (int i)
+{
+  return i - 5 < 10;
+}
+
+/* { dg-final { scan-tree-dump-not "-[ ]*5" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/strict-overflow-2.c b/gcc/testsuite/gcc.dg/strict-overflow-2.c
new file mode 100644 (file)
index 0000000..c1ec195
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of no-strict-overflow-2.c.  */
+
+/* We can only simplify the division when using strict overflow
+   semantics.  */
+
+int
+foo (int i)
+{
+  return (i * 100) / 10;
+}
+
+/* { dg-final { scan-tree-dump-not "100" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/strict-overflow-3.c b/gcc/testsuite/gcc.dg/strict-overflow-3.c
new file mode 100644 (file)
index 0000000..f179324
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of no-strict-overflow-3.c.  */
+
+/* We can only simplify the conditional when using strict overflow
+   semantics.  */
+
+int
+foo (int i, int j)
+{
+  return i + 100 < j + 1000;
+}
+
+/* { dg-final { scan-tree-dump-not "1000" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/strict-overflow-4.c b/gcc/testsuite/gcc.dg/strict-overflow-4.c
new file mode 100644 (file)
index 0000000..c89db21
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  Dual of no-strict-overflow-4.c.  */
+
+/* We can only simplify the conditional when using strict overflow
+   semantics.  */
+
+int
+foo (int i)
+{
+  return i + 1 > i;
+}
+
+/* We expect to see "<bb N>"; confirm that, so that we know to count
+   it in the real test.  */
+/* { dg-final { scan-tree-dump-times "<bb\[^>\]*>" 1 "final_cleanup" } } */
+/* { dg-final { scan-tree-dump-times ">|<" 2 "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
index 12ca1f38a91939363d119c1ad9d2a3b61ac98ec7..6194129292d1483fa9e6e33588ef4b6ecb05e99e 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do link } */
+/* { dg-options "-fstrict-overflow" } */
 
 #include <limits.h>
 
index 90acd8b7abc37d1e975cd8318d1c6bc44cea4bde..fdd3f44e0404430376f531b0d3e33e3c7a756938 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized" } */
+/* { dg-options "-O1 -fstrict-overflow -fdump-tree-optimized" } */
 
 int f(int a)
 {
index 5d719c025017bdedeb6dc8176ec4acaa0d892367..6cd86b21f97509e46e40e34b0a4dc6f4507b5e2c 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized" } */
+/* { dg-options "-O1 -fstrict-overflow -fdump-tree-optimized" } */
 
 int f(int a)
 {
index fa3e35a6a0be51a79ff2e698abc657bf39f14cad..d305b549cbd9ba8c82c0e71708efffbb18c8dd7b 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized" } */
+/* { dg-options "-O1 -fstrict-overflow -fdump-tree-optimized" } */
 
 int f(int a)
 {
index 38c68cf6e8dda99bc037c6a3e7856c0751ddf64a..b1bb1efa9e1cc18d7fb2a7ba2324dbf2afad20d4 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized" } */
+/* { dg-options "-O1 -fstrict-overflow -fdump-tree-optimized" } */
 
 int f(int a)
 {
index f77599fe3a53f043d69ed10540d677249e80920f..b69bb70d305615ab072e0f5262b4e906a46fb54e 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fdump-tree-gimple" } */
+/* { dg-options "-fstrict-overflow -fdump-tree-gimple" } */
 int g(int x)
 {
    return (x - 10) < 0;
index df487a77dbcd1ac12e328d1249c4e22ad94a0efb..bf63d3afc790d73706813dfc7c291d8485168e13 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fdump-tree-gimple" } */
+/* { dg-options "-fstrict-overflow -fdump-tree-gimple" } */
 int g(int x)
 {
    return (x + 10) < 0;
index 5e19f56d94d32df533ca0b14a490808cff5f5abd..2e9941060958e9f0a8d9527f18c1a1b7049ed54e 100644 (file)
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-gimple" } */
+/* { dg-options "-fstrict-overflow -fdump-tree-gimple" } */
 
 int foo (int i, int j)
 {
index 2965357f9b5fd5f1c5b8464d47a1269894700758..c0590a5c4e590021347ba39c3048aaa2a8de1296 100644 (file)
@@ -1,5 +1,5 @@
 /* Exception handling semantics and decomposition for trees.
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -1853,7 +1853,7 @@ tree_could_trap_p (tree expr)
          honor_nans = flag_trapping_math && !flag_finite_math_only;
          honor_snans = flag_signaling_nans != 0;
        }
-      else if (INTEGRAL_TYPE_P (t) && TYPE_TRAP_SIGNED (t))
+      else if (INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t))
        honor_trapv = true;
     }
 
index 194690185cce8d8b83e65639cef65e0cd0c4e11a..a1fe07a9dc8230e5784cce8f235efe4d9674727f 100644 (file)
@@ -1,5 +1,5 @@
 /* Scalar evolution detector.
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <s.pop@laposte.net>
 
 This file is part of GCC.
@@ -2837,9 +2837,8 @@ simple_iv (struct loop *loop, tree stmt, tree op, affine_iv *iv,
       || chrec_contains_symbols_defined_in_loop (iv->base, loop->num))
     return false;
 
-  iv->no_overflow = (!folded_casts
-                    && !flag_wrapv
-                    && !TYPE_UNSIGNED (type));
+  iv->no_overflow = !folded_casts && TYPE_OVERFLOW_UNDEFINED (type);
+
   return true;
 }
 
index affb47d3b1c5f5ca506077a852f49572ea41a1e1..48e045b2429e04622038af98e5000201a88013ad 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions to determine/estimate number of iterations of a loop.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    
 This file is part of GCC.
    
@@ -1874,7 +1874,7 @@ infer_loop_bounds_from_signedness (struct loop *loop, tree stmt)
 {
   tree def, base, step, scev, type, low, high;
 
-  if (flag_wrapv || TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+  if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
     return;
 
   def = GIMPLE_STMT_OPERAND (stmt, 0);
@@ -1884,7 +1884,7 @@ infer_loop_bounds_from_signedness (struct loop *loop, tree stmt)
 
   type = TREE_TYPE (def);
   if (!INTEGRAL_TYPE_P (type)
-      || TYPE_UNSIGNED (type))
+      || !TYPE_OVERFLOW_UNDEFINED (type))
     return;
 
   scev = instantiate_parameters (loop, analyze_scalar_evolution (loop, def));
@@ -2094,9 +2094,8 @@ n_of_executions_at_most (tree stmt,
 bool
 nowrap_type_p (tree type)
 {
-  if (!flag_wrapv
-      && INTEGRAL_TYPE_P (type)
-      && !TYPE_UNSIGNED (type))
+  if (INTEGRAL_TYPE_P (type)
+      && TYPE_OVERFLOW_UNDEFINED (type))
     return true;
 
   if (POINTER_TYPE_P (type))
index fb310f23ed63f705c72c322fcf17bf6808314818..82d4814a30efe2b6a1d1a0b3a0f157f6f0184708 100644 (file)
@@ -1,5 +1,5 @@
 /* Lower vector operations to scalar operations.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
    
@@ -301,14 +301,14 @@ expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
       {
       case PLUS_EXPR:
       case MINUS_EXPR:
-        if (!TYPE_TRAP_SIGNED (type))
+        if (!TYPE_OVERFLOW_TRAPS (type))
           return expand_vector_addition (bsi, do_binop, do_plus_minus, type,
                                         TREE_OPERAND (rhs, 0),
                                         TREE_OPERAND (rhs, 1), code);
        break;
 
       case NEGATE_EXPR:
-        if (!TYPE_TRAP_SIGNED (type))
+        if (!TYPE_OVERFLOW_TRAPS (type))
           return expand_vector_addition (bsi, do_unop, do_negate, type,
                                         TREE_OPERAND (rhs, 0),
                                         NULL_TREE, code);
index ee137314dd406922521f07214da7d7b19ba096fc..ef805955efc224db112a3d35f5c2ce0a2ae61bdf 100644 (file)
@@ -1,5 +1,5 @@
 /* Loop Vectorization
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Dorit Naishlos <dorit@il.ibm.com>
 
 This file is part of GCC.
@@ -2033,7 +2033,7 @@ vect_is_simple_reduction (struct loop *loop, tree phi)
         }
       return NULL_TREE;
     }
-  else if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) && flag_trapv)
+  else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
     {
       /* Changing the order of operations changes the semantics.  */
       if (vect_print_dump_info (REPORT_DETAILS))
index 6fb2a7271ba09dad49163c2f42fd3d60adf1934e..86f3d1c3710c493590a1607da55c990e2fa996cf 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for Value Range Propagation (VRP).
-   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>.
 
 This file is part of GCC.
@@ -570,8 +570,7 @@ compare_values (tree val1, tree val2)
        return 0;
 
       /* If overflow is defined we cannot simplify more.  */
-      if (TYPE_UNSIGNED (TREE_TYPE (val1))
-         || flag_wrapv)
+      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
        return -2;
 
       if (code1 == SSA_NAME)
@@ -1215,8 +1214,7 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
 
   /* If we are not using wrapping arithmetic, operate symbolically
      on -INF and +INF.  */
-  if (TYPE_UNSIGNED (TREE_TYPE (val1))
-      || flag_wrapv)
+  if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
     {
       int checkz = compare_values (res, val1);
       bool overflow = false;
@@ -1503,7 +1501,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
         point.  */
       if (code == MULT_EXPR
          && vr0.type == VR_ANTI_RANGE
-         && (flag_wrapv || TYPE_UNSIGNED (TREE_TYPE (op0))))
+         && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
        {
          set_value_range_to_varying (vr);
          return;
@@ -1799,11 +1797,12 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
            ? TYPE_MIN_VALUE (TREE_TYPE (expr))
            : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
 
-      max = vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr))
-           ? (vr0.type == VR_ANTI_RANGE || flag_wrapv
-              ? TYPE_MIN_VALUE (TREE_TYPE (expr))
-              : TYPE_MAX_VALUE (TREE_TYPE (expr)))
-           : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+      max = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr))
+            ? ((vr0.type == VR_ANTI_RANGE
+                || TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr)))
+               ? TYPE_MIN_VALUE (TREE_TYPE (expr))
+               : TYPE_MAX_VALUE (TREE_TYPE (expr)))
+            : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min));
 
     }
   else if (code == NEGATE_EXPR
@@ -1828,7 +1827,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
     {
       /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
          useful range.  */
-      if (flag_wrapv
+      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr))
          && ((vr0.type == VR_RANGE
               && vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
              || (vr0.type == VR_ANTI_RANGE
@@ -1865,7 +1864,8 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
                 or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
                 flag_wrapv is set and the original anti-range doesn't include
                 TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
-             min = (flag_wrapv && vr0.min != type_min_value
+             min = ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
+                     && vr0.min != type_min_value)
                     ? int_const_binop (PLUS_EXPR,
                                        type_min_value,
                                        integer_one_node, 0)
index ddb7e6af24d9573dd97e426e38de33722611c4cb..5f45c94f9389eed498542b1ba6b93e4a5a1ea59b 100644 (file)
@@ -1237,9 +1237,6 @@ extern void omp_clause_range_check_failed (const tree, const char *, int,
 /* In integral and pointer types, means an unsigned type.  */
 #define TYPE_UNSIGNED(NODE) (TYPE_CHECK (NODE)->base.unsigned_flag)
 
-#define TYPE_TRAP_SIGNED(NODE) \
-  (flag_trapv && ! TYPE_UNSIGNED (NODE))
-
 /* Nonzero in a VAR_DECL means assembler code has been written.
    Nonzero in a FUNCTION_DECL means that the function has been compiled.
    This is interesting in an inline function, since it might not need