From 4fa26a60791ec314128a9683fd4d657b251d0268 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sat, 31 May 2003 13:23:32 +0000 Subject: flags.h (flag_wrapv): New flag controlling overflow semantics. * flags.h (flag_wrapv): New flag controlling overflow semantics. * toplev.c (flag_wrapv): Declare the variable with default false. (lang_independent_options): New option "-fwrapv" to set the above. * fold-const.c (extract_muldiv_1): Disable optimization of (2*x)/2 as x, when signed arithmetic overflow wraps around. (fold): Optimize "-A - B" as "-B - A" if overflow wraps around. * loop.c (basic_induction_var): Ignore BIVs that rely on undefined overflow when flag_wrapv is true. * java/lang.c (java_init_options): Prescribe wrap-around two's complement arithmetic overflow by setting flag_wrapv. * doc/invoke.texi: Document new -fwrapv command line option. * doc/c-tree.texi: Mention that the overflow semantics of NEGATE_EXPR, PLUS_EXPR, MINUS_EXPR and MULT_EXPR is dependent upon both flag_wrapv and flag_trapv. * gcc.dg/fwrapv-1.c: New test case. * gcc.dg/fwrapv-2.c: New test case. * libjava.lang/Overflow.java: New test. * libjava.lang/Overflow.out: New file. From-SVN: r67270 --- gcc/ChangeLog | 17 +++++++++++++++++ gcc/doc/c-tree.texi | 6 ++++++ gcc/doc/invoke.texi | 10 +++++++++- gcc/flags.h | 3 +++ gcc/fold-const.c | 4 +++- gcc/java/ChangeLog | 5 +++++ gcc/java/lang.c | 3 +++ gcc/loop.c | 3 +++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/fwrapv-1.c | 28 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/fwrapv-2.c | 28 ++++++++++++++++++++++++++++ gcc/toplev.c | 6 ++++++ libjava/testsuite/ChangeLog | 5 +++++ libjava/testsuite/libjava.lang/Overflow.java | 16 ++++++++++++++++ libjava/testsuite/libjava.lang/Overflow.out | 0 15 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/fwrapv-1.c create mode 100644 gcc/testsuite/gcc.dg/fwrapv-2.c create mode 100644 libjava/testsuite/libjava.lang/Overflow.java create mode 100644 libjava/testsuite/libjava.lang/Overflow.out diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af2db15..061d593 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2003-05-31 Roger Sayle + + * flags.h (flag_wrapv): New flag controlling overflow semantics. + * toplev.c (flag_wrapv): Declare the variable with default false. + (lang_independent_options): New option "-fwrapv" to set the above. + + * fold-const.c (extract_muldiv_1): Disable optimization of (2*x)/2 + as x, when signed arithmetic overflow wraps around. + (fold): Optimize "-A - B" as "-B - A" if overflow wraps around. + * loop.c (basic_induction_var): Ignore BIVs that rely on undefined + overflow when flag_wrapv is true. + + * doc/invoke.texi: Document new -fwrapv command line option. + * doc/c-tree.texi: Mention that the overflow semantics of + NEGATE_EXPR, PLUS_EXPR, MINUS_EXPR and MULT_EXPR is dependent + upon both flag_wrapv and flag_trapv. + 2003-05-31 Eric Botcazou * doc/install.texi (mips-sgi-irix5): Add missing diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi index ff5a5fa..48e7e12 100644 --- a/gcc/doc/c-tree.texi +++ b/gcc/doc/c-tree.texi @@ -1914,6 +1914,9 @@ These nodes represent unary negation of the single operand, for both integer and floating-point types. The type of negation can be determined by looking at the type of the expression. +The behavior of this operation on signed arithmetic overflow is +controlled by the @code{flag_wrapv} and @code{flag_trapv} variables. + @item BIT_NOT_EXPR These nodes represent bitwise complement, and will always have integral type. The only operand is the value to be complemented. @@ -2067,6 +2070,9 @@ The @code{TRUNC_MOD_EXPR} of two operands @code{a} and @code{b} is always @code{a - (a/b)*b} where the division is as if computed by a @code{TRUNC_DIV_EXPR}. +The behavior of these operations on signed arithmetic overflow is +controlled by the @code{flag_wrapv} and @code{flag_trapv} variables. + @item ARRAY_REF These nodes represent array accesses. The first operand is the array; the second is the index. To calculate the address of the memory diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index df43850..e3edc07 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -680,7 +680,7 @@ in the following sections. -fargument-alias -fargument-noalias @gol -fargument-noalias-global -fleading-underscore @gol -ftls-model=@var{model} @gol --ftrapv -fbounds-check} +-ftrapv -fwrapv -fbounds-check} @end table @menu @@ -10850,6 +10850,14 @@ this option defaults to true and false respectively. This option generates traps for signed overflow on addition, subtraction, multiplication operations. +@item -fwrapv +@opindex fwrapv +This option instructs the compiler to assume that signed arithmetic +overflow of addition, subtraction and multiplication wraps around +using twos-complement representation. This flag enables some optimzations +and disables other. This option is enabled by default for the Java +front-end, as required by the Java language specification. + @item -fexceptions @opindex fexceptions Enable exception handling. Generates extra code needed to propagate diff --git a/gcc/flags.h b/gcc/flags.h index 4050517..c904288 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -585,6 +585,9 @@ extern int frame_pointer_needed; for PLUS / SUB / MULT. */ extern int flag_trapv; +/* Nonzero if the signed arithmetic overflow should wrap around. */ +extern int flag_wrapv; + /* Value of the -G xx switch, and whether it was passed or not. */ extern unsigned HOST_WIDE_INT g_switch_value; extern int g_switch_set; diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 381bc9c..e81e809 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4381,6 +4381,7 @@ extract_muldiv_1 (t, c, code, wide_type) overflowed. */ if ((! TREE_UNSIGNED (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 @@ -5765,7 +5766,8 @@ fold (expr) return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0))); /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ if (TREE_CODE (arg0) == NEGATE_EXPR - && FLOAT_TYPE_P (type) + && (FLOAT_TYPE_P (type) + || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)) && negate_expr_p (arg1) && (! TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1)) && (! TREE_SIDE_EFFECTS (arg1) || TREE_CONSTANT (arg0))) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 8dc9eca..b41f316 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2003-05-31 Roger Sayle + + * lang.c (java_init_options): Prescribe wrap-around two's + complement arithmetic overflow by setting flag_wrapv. + 2003-05-29 Roger Sayle * builtins.c (cos_builtin, sin_builtin, sqrt_builtin): Delete. diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 031ddcc..918be0a 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -740,6 +740,9 @@ java_init_options (void) /* In Java floating point operations never trap. */ flag_trapping_math = 0; + + /* In Java arithmetic overflow always wraps around. */ + flag_wrapv = 1; } static bool diff --git a/gcc/loop.c b/gcc/loop.c index e5ae479..737ec89 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -6462,6 +6462,9 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location) return 0; case SIGN_EXTEND: + /* Ignore this BIV if signed arithmetic overflow is defined. */ + if (flag_wrapv) + return 0; return basic_induction_var (loop, XEXP (x, 0), GET_MODE (XEXP (x, 0)), dest_reg, p, inc_val, mult_val, location); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 628551e..65d84e7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-05-31 Roger Sayle + + * gcc.dg/fwrapv-1.c: New test case. + * gcc.dg/fwrapv-2.c: New test case. + 2003-05-31 Kriang Lerdsuwanakij PR c++/10956 diff --git a/gcc/testsuite/gcc.dg/fwrapv-1.c b/gcc/testsuite/gcc.dg/fwrapv-1.c new file mode 100644 index 0000000..f7ddda4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fwrapv-1.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2003 Free Software Foundation. + + Test that the -fwrapv command line option is accepted and disables + "unsafe" optimizations that rely on undefined arithmetic overflow. + + Written by Roger Sayle, 24th March 2003. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -fwrapv" } */ + +#include + +extern void abort (); + +int test(int x) +{ + return (2*x)/2; +} + +main() +{ + int x = INT_MAX; + + if (test(x) == x) + abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/fwrapv-2.c b/gcc/testsuite/gcc.dg/fwrapv-2.c new file mode 100644 index 0000000..cb4270e --- /dev/null +++ b/gcc/testsuite/gcc.dg/fwrapv-2.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2003 Free Software Foundation. + + Test that the -fno-wrapv command line option is accepted and enables + "unsafe" optimizations that rely on undefined arithmetic overflow. + + Written by Roger Sayle, 31st May 2003. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -fno-wrapv" } */ + +#include + +extern void abort (); + +int test(int x) +{ + return (2*x)/2; +} + +main() +{ + int x = INT_MAX; + + if (test(x) != x) + abort (); + return 0; +} + diff --git a/gcc/toplev.c b/gcc/toplev.c index 7cfb29e..f2c352f 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -977,8 +977,12 @@ typedef struct } lang_independent_options; +/* Nonzero if signed arithmetic overflow should trap. */ int flag_trapv = 0; +/* Nonzero if signed arithmetic overflow should wrap around. */ +int flag_wrapv = 0; + /* Add or remove a leading underscore from user symbols. */ int flag_leading_underscore = -1; @@ -1220,6 +1224,8 @@ static const lang_independent_options f_options[] = N_("Report on permanent memory allocation at end of run") }, { "trapv", &flag_trapv, 1, N_("Trap for signed overflow in addition / subtraction / multiplication") }, + { "wrapv", &flag_wrapv, 1, + N_("Assume signed arithmetic overflow wraps around") }, { "new-ra", &flag_new_regalloc, 1, N_("Use graph coloring register allocation.") }, }; diff --git a/libjava/testsuite/ChangeLog b/libjava/testsuite/ChangeLog index 6ea10ff..ee7883b 100644 --- a/libjava/testsuite/ChangeLog +++ b/libjava/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-05-31 Roger Sayle + + * libjava.lang/Overflow.java: New test. + * libjava.lang/Overflow.out: New file. + 2003-05-06 Tom Tromey * libjava.lang/verify.java: New file. diff --git a/libjava/testsuite/libjava.lang/Overflow.java b/libjava/testsuite/libjava.lang/Overflow.java new file mode 100644 index 0000000..312e9cb --- /dev/null +++ b/libjava/testsuite/libjava.lang/Overflow.java @@ -0,0 +1,16 @@ +class Overflow +{ + static int test(int x) + { + return (2*x)/2; + } + + public static void main(String argv[]) + { + int x = Integer.MAX_VALUE; + + if (test(x) == x) + throw new RuntimeException (); + } +} + diff --git a/libjava/testsuite/libjava.lang/Overflow.out b/libjava/testsuite/libjava.lang/Overflow.out new file mode 100644 index 0000000..e69de29 -- cgit v1.1