mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-15 14:40:54 +08:00
common.opt: Add fstrict-overflow.
./: * 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
This commit is contained in:
parent
b73a605656
commit
eeef0e452e
gcc
ChangeLogcommon.optconvert.c
doc
flags.hfold-const.coptabs.copts.csimplify-rtx.ctestsuite
ChangeLog
tree-eh.ctree-scalar-evolution.ctree-ssa-loop-niter.ctree-vect-generic.ctree-vectorizer.ctree-vrp.ctree.hg++.dg/tree-ssa
gcc.dg
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
18
gcc/flags.h
18
gcc/flags.h
@ -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 */
|
||||
|
@ -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)));
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* { dg-do link } */
|
||||
/* { dg-options "-fstrict-overflow" } */
|
||||
|
||||
void link_error();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
16
gcc/testsuite/gcc.dg/no-strict-overflow-1.c
Normal file
16
gcc/testsuite/gcc.dg/no-strict-overflow-1.c
Normal file
@ -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" } } */
|
16
gcc/testsuite/gcc.dg/no-strict-overflow-2.c
Normal file
16
gcc/testsuite/gcc.dg/no-strict-overflow-2.c
Normal file
@ -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" } } */
|
16
gcc/testsuite/gcc.dg/no-strict-overflow-3.c
Normal file
16
gcc/testsuite/gcc.dg/no-strict-overflow-3.c
Normal file
@ -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" } } */
|
19
gcc/testsuite/gcc.dg/no-strict-overflow-4.c
Normal file
19
gcc/testsuite/gcc.dg/no-strict-overflow-4.c
Normal file
@ -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" } } */
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
16
gcc/testsuite/gcc.dg/strict-overflow-1.c
Normal file
16
gcc/testsuite/gcc.dg/strict-overflow-1.c
Normal file
@ -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" } } */
|
16
gcc/testsuite/gcc.dg/strict-overflow-2.c
Normal file
16
gcc/testsuite/gcc.dg/strict-overflow-2.c
Normal file
@ -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" } } */
|
16
gcc/testsuite/gcc.dg/strict-overflow-3.c
Normal file
16
gcc/testsuite/gcc.dg/strict-overflow-3.c
Normal file
@ -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" } } */
|
19
gcc/testsuite/gcc.dg/strict-overflow-4.c
Normal file
19
gcc/testsuite/gcc.dg/strict-overflow-4.c
Normal file
@ -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" } } */
|
@ -1,4 +1,5 @@
|
||||
/* { dg-do link } */
|
||||
/* { dg-options "-fstrict-overflow" } */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
/* { dg-options "-fstrict-overflow -fdump-tree-gimple" } */
|
||||
|
||||
int foo (int i, int j)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user