diff options
author | Ian Lance Taylor <iant@google.com> | 2010-10-23 16:18:32 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2010-10-23 16:18:32 +0000 |
commit | 0e1b8b109fb5a19dc3576a14416383299566ff00 (patch) | |
tree | cf7659287d28d44a74afdea7975d98bd017ddb0d | |
parent | 67f67405cb4f5fec7950c18f5e15da06d4852acb (diff) | |
download | gcc-0e1b8b109fb5a19dc3576a14416383299566ff00.zip gcc-0e1b8b109fb5a19dc3576a14416383299566ff00.tar.gz gcc-0e1b8b109fb5a19dc3576a14416383299566ff00.tar.bz2 |
tree-vrp.c (extract_range_from_binary_expr): If flag_non_call_exceptions don't eliminate division by zero.
gcc/:
* tree-vrp.c (extract_range_from_binary_expr): If
flag_non_call_exceptions don't eliminate division by zero.
* simplify-rtx.c (simplify_binary_operation_1): Likewise.
gcc/testsuite/:
* gcc.c-torture/execute/20101011-1.c: New test.
* gcc.c-torture/execute/20101011-1.x: New test driver.
From-SVN: r165884
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20101011-1.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20101011-1.x | 2 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 16 |
6 files changed, 76 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53b43f0..a2dee2e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-10-23 Ian Lance Taylor <iant@google.com> + + * tree-vrp.c (extract_range_from_binary_expr): If + flag_non_call_exceptions don't eliminate division by zero. + * simplify-rtx.c (simplify_binary_operation_1): Likewise. + 2010-10-23 Nathan Froyd <froydnj@codesourcery.com> * cppbuiltin.c (define_builtin_macros_for_type_sizes): Define diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index e45917f..84f3863 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2755,7 +2755,8 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, else { /* 0/x is 0 (or x&0 if x has side-effects). */ - if (trueop0 == CONST0_RTX (mode)) + if (trueop0 == CONST0_RTX (mode) + && !cfun->can_throw_non_call_exceptions) { if (side_effects_p (op1)) return simplify_gen_binary (AND, mode, op1, trueop0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d742fbf..3ab40ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-10-23 Ian Lance Taylor <iant@google.com> + + * gcc.c-torture/execute/20101011-1.c: New test. + * gcc.c-torture/execute/20101011-1.x: New test driver. + 2010-10-23 Tobias Burnus <burnus@net-b.de> PR fortran/46122 diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c new file mode 100644 index 0000000..4c36ad3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c @@ -0,0 +1,45 @@ +/* With -fnon-call-exceptions 0 / 0 should not be eliminated. The .x + file sets the option. */ + +#ifdef SIGNAL_SUPPRESS +# define DO_TEST 0 +#elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) || defined (__POWERPC__) || defined (__ppc) + /* On PPC division by zero does not trap. */ +# define DO_TEST 0 +#elif defined (__SPU__) + /* On SPU division by zero does not trap. */ +# define DO_TEST 0 +#else +# define DO_TEST 1 +#endif + +#if DO_TEST + +#include <signal.h> + +void +sigfpe (int signum __attribute__ ((unused))) +{ + exit (0); +} + +#endif + +/* When optimizing, the compiler is smart enough to constant fold the + static unset variables i and j to produce 0 / 0, but it can't + eliminate the assignment to the global k. */ +static int i; +static int j; +int k; + +int +main () +{ +#ifdef DO_TEST + signal (SIGFPE, sigfpe); + k = i / j; + abort (); +#else + exit (0); +#endif +} diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.x b/gcc/testsuite/gcc.c-torture/execute/20101011-1.x new file mode 100644 index 0000000..b5c080d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.x @@ -0,0 +1,2 @@ +set additional_flags "-fnon-call-exceptions" +return 0 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 8ab986e..2103e1b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2456,6 +2456,22 @@ extract_range_from_binary_expr (value_range_t *vr, } } + /* For divisions, if flag_non_call_exceptions is true, we must + not eliminate a division by zero. */ + if ((code == TRUNC_DIV_EXPR + || code == FLOOR_DIV_EXPR + || code == CEIL_DIV_EXPR + || code == EXACT_DIV_EXPR + || code == ROUND_DIV_EXPR) + && cfun->can_throw_non_call_exceptions + && (vr1.type != VR_RANGE + || symbolic_range_p (&vr1) + || range_includes_zero_p (&vr1))) + { + set_value_range_to_varying (vr); + return; + } + /* For divisions, if op0 is VR_RANGE, we can deduce a range even if op1 is VR_VARYING, VR_ANTI_RANGE, symbolic or can include 0. */ |