This is the mail archive of the 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]

Fix PR optimization/12215


This is again a problem with -fnon-call-exceptions, a regression from 3.2.3 
present on the 3.3 branch (and latent on mainline).

The CSE pass can destroy the CFG in presence of trapping loads, because it 
may emit insns right after those loads. Now trapping loads can cause a 
control flow transfer, so they are the last insns in their basic block. Once 
the CFG is destroyed, bogus edges are purged, which leads in turn to the 
deletion of basic blocks.

Bootstrapped/regtested on i586-redhat-linux-gnu (3.3 branch except Ada).
Ok for mainline and branch?

2003-09-12  Eric Botcazou  <>

        PR optimization/12215
        * cse.c (cse_set_around_loop): Emit the move at the beginning
	of the next basic block for trapping sets.

2003-09-12  Eric Botcazou  <>

        * g++.dg/opt/cfg2.C: New test.

Eric Botcazou
Index: cse.c
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision
diff -u -p -r1.244.2.2 cse.c
--- cse.c	29 Apr 2003 19:16:40 -0000
+++ cse.c	12 Sep 2003 11:12:21 -0000
@@ -6844,7 +6844,15 @@ cse_set_around_loop (x, insn, loop_start
 			      abort ();
-			  emit_insn_after (move, p);
+			  {
+			    if (control_flow_insn_p (p))
+			      /* p can cause a control flow transfer so it
+				 is the last insn of a basic block. We can't
+				 therefore use emit_insn_after.  */
+			      emit_insn_before (move, next_nonnote_insn (p));
+			    else
+			      emit_insn_after (move, p);
+			  }
// PR optimization/12215
// Origin: <>
// Reduced testcase by Wolfgang Bangerth <>

// This used to fail because the CSE pass destroyed the CFG in presence
// of trapping loads, which led to the deletion of basic blocks.

// { dg-do compile }
// { dg-options "-O2 -fno-gcse -fnon-call-exceptions" }

struct B {
  ~B() throw() {}

struct X {
  X(const char*, const B&);
  ~X() {}

bool m();
void f(int &i, float &arg0);

void g (const char **argv) {
  float val;
  int i = 1;

  try {
    while ( i < 1 )
        X arg(argv[i], B());
        if (m())

        f(i, val);
  } catch (...) {}

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