Commit 4fa26a60 by Roger Sayle Committed by Roger Sayle

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
parent 82a2669e
2003-05-31 Roger Sayle <roger@eyesopen.com>
* 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 <ebotcazou@libertysurf.fr> 2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
* doc/install.texi (mips-sgi-irix5): Add missing * doc/install.texi (mips-sgi-irix5): Add missing
......
...@@ -1914,6 +1914,9 @@ These nodes represent unary negation of the single operand, for both ...@@ -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 integer and floating-point types. The type of negation can be
determined by looking at the type of the expression. 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 @item BIT_NOT_EXPR
These nodes represent bitwise complement, and will always have integral These nodes represent bitwise complement, and will always have integral
type. The only operand is the value to be complemented. 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 ...@@ -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 always @code{a - (a/b)*b} where the division is as if computed by a
@code{TRUNC_DIV_EXPR}. @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 @item ARRAY_REF
These nodes represent array accesses. The first operand is the array; These nodes represent array accesses. The first operand is the array;
the second is the index. To calculate the address of the memory the second is the index. To calculate the address of the memory
......
...@@ -680,7 +680,7 @@ in the following sections. ...@@ -680,7 +680,7 @@ in the following sections.
-fargument-alias -fargument-noalias @gol -fargument-alias -fargument-noalias @gol
-fargument-noalias-global -fleading-underscore @gol -fargument-noalias-global -fleading-underscore @gol
-ftls-model=@var{model} @gol -ftls-model=@var{model} @gol
-ftrapv -fbounds-check} -ftrapv -fwrapv -fbounds-check}
@end table @end table
@menu @menu
...@@ -10850,6 +10850,14 @@ this option defaults to true and false respectively. ...@@ -10850,6 +10850,14 @@ this option defaults to true and false respectively.
This option generates traps for signed overflow on addition, subtraction, This option generates traps for signed overflow on addition, subtraction,
multiplication operations. 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 @item -fexceptions
@opindex fexceptions @opindex fexceptions
Enable exception handling. Generates extra code needed to propagate Enable exception handling. Generates extra code needed to propagate
......
...@@ -585,6 +585,9 @@ extern int frame_pointer_needed; ...@@ -585,6 +585,9 @@ extern int frame_pointer_needed;
for PLUS / SUB / MULT. */ for PLUS / SUB / MULT. */
extern int flag_trapv; 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. */ /* Value of the -G xx switch, and whether it was passed or not. */
extern unsigned HOST_WIDE_INT g_switch_value; extern unsigned HOST_WIDE_INT g_switch_value;
extern int g_switch_set; extern int g_switch_set;
......
...@@ -4381,6 +4381,7 @@ extract_muldiv_1 (t, c, code, wide_type) ...@@ -4381,6 +4381,7 @@ extract_muldiv_1 (t, c, code, wide_type)
overflowed. */ overflowed. */
if ((! TREE_UNSIGNED (ctype) if ((! TREE_UNSIGNED (ctype)
|| (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))) || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
&& ! flag_wrapv
&& ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR) && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
|| (tcode == MULT_EXPR || (tcode == MULT_EXPR
&& code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
...@@ -5765,7 +5766,8 @@ fold (expr) ...@@ -5765,7 +5766,8 @@ fold (expr)
return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0))); return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR 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) && negate_expr_p (arg1)
&& (! TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1)) && (! TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
&& (! TREE_SIDE_EFFECTS (arg1) || TREE_CONSTANT (arg0))) && (! TREE_SIDE_EFFECTS (arg1) || TREE_CONSTANT (arg0)))
......
2003-05-31 Roger Sayle <roger@eyesopen.com>
* lang.c (java_init_options): Prescribe wrap-around two's
complement arithmetic overflow by setting flag_wrapv.
2003-05-29 Roger Sayle <roger@eyesopen.com> 2003-05-29 Roger Sayle <roger@eyesopen.com>
* builtins.c (cos_builtin, sin_builtin, sqrt_builtin): Delete. * builtins.c (cos_builtin, sin_builtin, sqrt_builtin): Delete.
......
...@@ -740,6 +740,9 @@ java_init_options (void) ...@@ -740,6 +740,9 @@ java_init_options (void)
/* In Java floating point operations never trap. */ /* In Java floating point operations never trap. */
flag_trapping_math = 0; flag_trapping_math = 0;
/* In Java arithmetic overflow always wraps around. */
flag_wrapv = 1;
} }
static bool static bool
......
...@@ -6462,6 +6462,9 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location) ...@@ -6462,6 +6462,9 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
return 0; return 0;
case SIGN_EXTEND: 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)), return basic_induction_var (loop, XEXP (x, 0), GET_MODE (XEXP (x, 0)),
dest_reg, p, inc_val, mult_val, location); dest_reg, p, inc_val, mult_val, location);
......
2003-05-31 Roger Sayle <roger@eyesopen.com>
* gcc.dg/fwrapv-1.c: New test case.
* gcc.dg/fwrapv-2.c: New test case.
2003-05-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2003-05-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/10956 PR c++/10956
......
/* 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 <limits.h>
extern void abort ();
int test(int x)
{
return (2*x)/2;
}
main()
{
int x = INT_MAX;
if (test(x) == x)
abort ();
return 0;
}
/* 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 <limits.h>
extern void abort ();
int test(int x)
{
return (2*x)/2;
}
main()
{
int x = INT_MAX;
if (test(x) != x)
abort ();
return 0;
}
...@@ -977,8 +977,12 @@ typedef struct ...@@ -977,8 +977,12 @@ typedef struct
} }
lang_independent_options; lang_independent_options;
/* Nonzero if signed arithmetic overflow should trap. */
int flag_trapv = 0; 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. */ /* Add or remove a leading underscore from user symbols. */
int flag_leading_underscore = -1; int flag_leading_underscore = -1;
...@@ -1220,6 +1224,8 @@ static const lang_independent_options f_options[] = ...@@ -1220,6 +1224,8 @@ static const lang_independent_options f_options[] =
N_("Report on permanent memory allocation at end of run") }, N_("Report on permanent memory allocation at end of run") },
{ "trapv", &flag_trapv, 1, { "trapv", &flag_trapv, 1,
N_("Trap for signed overflow in addition / subtraction / multiplication") }, 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, { "new-ra", &flag_new_regalloc, 1,
N_("Use graph coloring register allocation.") }, N_("Use graph coloring register allocation.") },
}; };
......
2003-05-31 Roger Sayle <roger@eyesopen.com>
* libjava.lang/Overflow.java: New test.
* libjava.lang/Overflow.out: New file.
2003-05-06 Tom Tromey <tromey@redhat.com> 2003-05-06 Tom Tromey <tromey@redhat.com>
* libjava.lang/verify.java: New file. * libjava.lang/verify.java: New file.
......
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 ();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment