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;