Patchwork Fix PR middle-end/55321

login
register
mail settings
Submitter Eric Botcazou
Date Nov. 29, 2012, 2:29 p.m.
Message ID <3518611.zZ98rW8iyM@polaris>
Download mbox | patch
Permalink /patch/202759/
State New
Headers show

Comments

Eric Botcazou - Nov. 29, 2012, 2:29 p.m.
> Well, there's a call at the tree level for __sync_synchronize as well.
> 
> So the question is: why does __s_s ICE but memcmp doesn't? I suppose
> it's the mere rarity with which HAVE_cmpmemsi is defined, and expansion
> of gen_cmpmemsi fails.
> 
> There are plenty of other calls to emit_library_call_value that are
> not subsequently protected by emit_libcall_block_1, but they are probably
> sufficiently rare on common platforms that they'd be difficult to trigger.

You're right, here's a patch that marks all no-throw libcalls as no-nonlocal.

Tested on x86_64-suse-linux, OK for the mainline?


2012-11-29  Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/55321
	* calls.c (emit_library_call_value_1): Mark as no-nonlocal if no-throw.
Richard Henderson - Nov. 29, 2012, 5:15 p.m.
On 2012-11-29 06:29, Eric Botcazou wrote:
> 	PR middle-end/55321
> 	* calls.c (emit_library_call_value_1): Mark as no-nonlocal if no-throw.

Ok.


r~

Patch

Index: calls.c
===================================================================
--- calls.c	(revision 193921)
+++ calls.c	(working copy)
@@ -4196,13 +4196,11 @@  emit_library_call_value_1 (int retval, r
      that it should complain if nonvolatile values are live.  For
      functions that cannot return, inform flow that control does not
      fall through.  */
-
   if (flags & ECF_NORETURN)
     {
       /* The barrier note must be emitted
 	 immediately after the CALL_INSN.  Some ports emit more than
 	 just a CALL_INSN above, so we must search for it here.  */
-
       rtx last = get_last_insn ();
       while (!CALL_P (last))
 	{
@@ -4214,6 +4212,21 @@  emit_library_call_value_1 (int retval, r
       emit_barrier_after (last);
     }
 
+  /* Consider that "regular" libcalls, i.e. all of them except for LCT_THROW
+     and LCT_RETURNS_TWICE, cannot perform non-local gotos.  */
+  if (flags & ECF_NOTHROW)
+    {
+      rtx last = get_last_insn ();
+      while (!CALL_P (last))
+	{
+	  last = PREV_INSN (last);
+	  /* There was no CALL_INSN?  */
+	  gcc_assert (last != before_call);
+	}
+
+      make_reg_eh_region_note_nothrow_nononlocal (last);
+    }
+
   /* Now restore inhibit_defer_pop to its actual original value.  */
   OK_DEFER_POP;