tree-vrp.c (extract_range_from_binary_expr): If flag_non_call_exceptions don't elimin...
authorIan Lance Taylor <iant@google.com>
Sat, 23 Oct 2010 16:18:32 +0000 (16:18 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 23 Oct 2010 16:18:32 +0000 (16:18 +0000)
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

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20101011-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20101011-1.x [new file with mode: 0644]
gcc/tree-vrp.c

index 53b43f020a9caf545fde75554a3e1d121d0e3da4..a2dee2ef5b30dde88d7c6c20e219a664758e4d71 100644 (file)
@@ -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
index e45917f8df39451f1108cd3092fde0957731146a..84f3863e0b0340643318d5e95e00cc3122908c94 100644 (file)
@@ -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);
index d742fbfacf1325e059efffd467c2f0cb8acc915f..3ab40ac7fc8ba705f9ee3558bccbbcc00bd265e3 100644 (file)
@@ -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 (file)
index 0000000..4c36ad3
--- /dev/null
@@ -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 (file)
index 0000000..b5c080d
--- /dev/null
@@ -0,0 +1,2 @@
+set additional_flags "-fnon-call-exceptions"
+return 0
index 8ab986ef1bd107db2efd0049566c50039a912fa3..2103e1b61bb3609601c8c08c4d9e105c208fe59d 100644 (file)
@@ -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.  */