This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR tree-opt/33615 [1/2] Hoisting of throwing expression for -fnon-call-exceptions


If the following C++ code is compiled with -fnon-call-exceptions,
the tree optimisers still hoist 1.0 / 0.0:

---------------------------------------------------------
extern volatile int y;

double
foo (double a, int x)
{
  while (x--)
    {
      y++;
      a += 1.0 / 0.0;
    }
  return a;
}
---------------------------------------------------------

Header copying ensures that 1.0 / 0.0 is only executed when the
incoming x is nonzero, but it still happens before the first
assignment to "y".

At -O, the hoisting is done by LIM; at -O2, it's done be PRE.
I think both are caused by missing tree_could_throw_p checks.
Perhaps we need some new predicate here, to check tree_could_throw_p
and other "cannot move" properties such as volatility?

However, I've gone for the simpler fix of just adding the
apparently-missing checks.  This first patch fixes the LIM case.
Bootstrapped & regression-tested on x86_64-linux-gnu.  Also
regression-tested on mipsisa32-elf.  OK to install?

Richard

gcc/
	PR tree-optimization/33615
	* tree-ssa-loop-im.c (movement_possibility): Return MOVE_IMPOSSIBLE
	if the rhs might throw.

gcc/testsuite/
	PR tree-optimization/33615
	* g++.dg/tree-ssa/pr33615.C: New test.

Index: gcc/tree-ssa-loop-im.c
===================================================================
--- gcc/tree-ssa-loop-im.c	2007-10-01 23:23:16.000000000 +0100
+++ gcc/tree-ssa-loop-im.c	2007-10-01 23:39:36.000000000 +0100
@@ -260,7 +260,8 @@ movement_possibility (tree stmt)
 
   rhs = GIMPLE_STMT_OPERAND (stmt, 1);
 
-  if (TREE_SIDE_EFFECTS (rhs))
+  if (TREE_SIDE_EFFECTS (rhs)
+      || tree_could_throw_p (rhs))
     return MOVE_IMPOSSIBLE;
 
   if (TREE_CODE (lhs) != SSA_NAME
Index: gcc/testsuite/g++.dg/tree-ssa/pr33615.C
===================================================================
--- /dev/null	2007-09-27 09:37:00.556097250 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr33615.C	2007-10-01 23:39:36.000000000 +0100
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fnon-call-exceptions -fdump-tree-lim-details -w" } */
+
+extern volatile int y;
+
+double
+foo (double a, int x)
+{
+  while (x--)
+    {
+      y++;
+      a += 1.0 / 0.0;
+    }
+  return a;
+}
+
+// The expression 1.0 / 0.0 should not be treated as a loop invariant
+// if it may throw an exception.
+// { dg-final { scan-tree-dump-times "invariant up to" 0 "lim" } }
+// { dg-final { cleanup-tree-dump "lim" } }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]