From 47d397e1369479523eaecd1a6b35d610dbd9da96 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 23 Oct 2010 16:18:32 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165884 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++ gcc/simplify-rtx.c | 3 +- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/20101011-1.c | 45 ++++++++++++++++++++++++ gcc/testsuite/gcc.c-torture/execute/20101011-1.x | 2 ++ gcc/tree-vrp.c | 16 +++++++++ 6 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20101011-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/20101011-1.x 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 + + * 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 * 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 + + * gcc.c-torture/execute/20101011-1.c: New test. + * gcc.c-torture/execute/20101011-1.x: New test driver. + 2010-10-23 Tobias Burnus 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 + +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. */ -- 2.7.4