Hi,

this is the build failure of the Ada runtime on the ARM:

+===========================GNAT BUG DETECTED==============================+
| 4.8.0 20121111 (experimental) (armv5tel-unknown-linux-gnueabi) GCC error:|
| in merge_latch_edges, at cfgloop.c:678                                   |
| Error detected around s-stposu.adb:565:8                                 |
| Please submit a bug report; see http://gcc.gnu.org/bugs.html.     

The problem is that get_loop_latch_edges finds no latch edges for a loop 
because the header of the loop doesn't dominate any of its predecessors.
The reason is that a new edge is added during RTL expansion, which changes the 
dominance info.  This edge is from a call to __sync_synchronize to a non-local 
label generated for a __builtin_setjmp_receiver.

Fixed by marking the call as "nononlocal", tested on x86_64-suse-linux, OK for 
the mainline?


2012-11-15  Eric Botcazou  <ebotca...@adacore.com>

        PR middle-end/55321
        * optabs.c (mark_nothrow_nononlocal): New function extracted from...
        (emit_libcall_block_1): ...here.  Call it.
        (expand_mem_thread_fence): Call it for synchronize_libfunc.


2012-11-15  Eric Botcazou  <ebotca...@adacore.com>

        * loop_optimization14.ad[sb]: New test.
        * loop_optimization14_pkg.ads: New helper.


-- 
Eric Botcazou
Index: optabs.c
===================================================================
--- optabs.c	(revision 193528)
+++ optabs.c	(working copy)
@@ -3838,6 +3838,23 @@ no_conflict_move_test (rtx dest, const_r
 }
 
 
+/* Look for any CALL_INSNs in the insn chain starting at INSN and attach a
+   REG_EH_REGION reg note to indicate that this call cannot throw or execute
+   a nonlocal goto (unless there is already a REG_EH_REGION note, in which
+   case we update it).  */
+
+static void
+mark_nothrow_nononlocal (rtx insn)
+{
+  while (insn)
+    {
+      if (CALL_P (insn))
+	make_reg_eh_region_note_nothrow_nononlocal (insn);
+
+      insn = NEXT_INSN (insn);
+    }
+}
+
 /* Emit code to make a call to a constant function or a library call.
 
    INSNS is a list containing all insns emitted in the call.
@@ -3881,15 +3898,7 @@ emit_libcall_block_1 (rtx insns, rtx tar
 	  }
     }
   else
-    {
-      /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
-	 reg note to indicate that this call cannot throw or execute a nonlocal
-	 goto (unless there is already a REG_EH_REGION note, in which case
-	 we update it).  */
-      for (insn = insns; insn; insn = NEXT_INSN (insn))
-	if (CALL_P (insn))
-	  make_reg_eh_region_note_nothrow_nononlocal (insn);
-    }
+    mark_nothrow_nononlocal (insns);
 
   /* First emit all insns that set pseudos.  Remove them from the list as
      we go.  Avoid insns that set pseudos which were referenced in previous
@@ -7404,7 +7413,15 @@ expand_mem_thread_fence (enum memmodel m
       if (HAVE_memory_barrier)
 	emit_insn (gen_memory_barrier ());
       else if (synchronize_libfunc != NULL_RTX)
-	emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
+	{
+	  rtx insns;
+	  start_sequence ();
+	  emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
+	  insns = get_insns ();
+	  end_sequence ();
+	  mark_nothrow_nononlocal (insns);
+	  emit_insn (insns);
+	}
       else
 	expand_asm_memory_barrier ();
     }
-- PR middle-end/55321
-- { dg-do compile }
-- { dg-options "-O" }

with Loop_Optimization14_Pkg; use Loop_Optimization14_Pkg;

package body Loop_Optimization14 is

   procedure Finalize_Pool (Pool : in out Rec) is
      Raised : Boolean := False;
   begin
      Pool.A := True;

      while not Pool.B loop

         begin
            Proc (Pool.B);

         exception
            when others =>
               if not Raised then
                  Raised := True;
               end if;
         end;
      end loop;

   end;

end Loop_Optimization14;
package Loop_Optimization14 is

   type Rec is record
      A : Boolean;
      pragma Atomic (A);

      B : Boolean;

   end record;

   procedure Finalize_Pool (Pool : in out Rec);

end Loop_Optimization14;
package Loop_Optimization14_Pkg is

   procedure Proc (B : in out Boolean);

end Loop_Optimization14_Pkg;

Reply via email to