aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2010-10-23 16:18:32 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2010-10-23 16:18:32 +0000
commit0e1b8b109fb5a19dc3576a14416383299566ff00 (patch)
treecf7659287d28d44a74afdea7975d98bd017ddb0d
parent67f67405cb4f5fec7950c18f5e15da06d4852acb (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/simplify-rtx.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20101011-1.c45
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20101011-1.x2
-rw-r--r--gcc/tree-vrp.c16
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. */