diff mbox

[PTX] no return fns

Message ID 5665B170.9070708@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Dec. 7, 2015, 4:18 p.m. UTC
calls to no return fns can cause problems with the PTX JIT.  It doesn't 
understand their no-return nature and can erroneously think there are unexitable 
loops (depending on the precise placement of bbs).  It can get so upset it 
segfaults.

gcc.dg/pr68671.c started causing this last week, with what looked like 
incomplete jump threading.

This patch changes call emission to look for a noreturn note and emit a trap 
insn after the call.  The JIT  no longer explodes.

nathan

Comments

Nathan Sidwell Dec. 7, 2015, 5:03 p.m. UTC | #1
On 12/07/15 11:18, Nathan Sidwell wrote:
> calls to no return fns can cause problems with the PTX JIT.  It doesn't
> understand their no-return nature and can erroneously think there are unexitable
> loops (depending on the precise placement of bbs).  It can get so upset it
> segfaults.
>
> gcc.dg/pr68671.c started causing this last week, with what looked like
> incomplete jump threading.

Bernd, I meant to ask if you recalled previous tests you failed because of this 
problem?  I'm retesting
  gcc.c-torture/compile/920723-1.c
  gcc.c-torture/compile/pr33855.c
  gcc.c-torture/execute/981019-1.c

to see if they are culprits.

nathan
Alexander Monakov Dec. 7, 2015, 5:08 p.m. UTC | #2
Hello Nathan,

On Mon, 7 Dec 2015, Nathan Sidwell wrote:
> This patch changes call emission to look for a noreturn note and emit a trap
> insn after the call.  The JIT  no longer explodes.

I think there's a potential issue with the patch: when the noreturn function
has a non-void return value, your patch places 'trap' between 'call' and
'ld.param' insns.  That violates the PTX specification, which demands:

    All st.param instructions used for passing arguments to function call must
    immediately precede the corresponding call instruction and ld.param
    instruction used for collecting return value must immediately follow the
    call instruction without any control flow alteration.

Alexander
Bernd Schmidt Dec. 7, 2015, 5:33 p.m. UTC | #3
On 12/07/2015 06:03 PM, Nathan Sidwell wrote:
> On 12/07/15 11:18, Nathan Sidwell wrote:
>> calls to no return fns can cause problems with the PTX JIT.  It doesn't
>> understand their no-return nature and can erroneously think there are
>> unexitable
>> loops (depending on the precise placement of bbs).  It can get so
>> upset it
>> segfaults.
>>
>> gcc.dg/pr68671.c started causing this last week, with what looked like
>> incomplete jump threading.
>
> Bernd, I meant to ask if you recalled previous tests you failed because
> of this problem?  I'm retesting
>   gcc.c-torture/compile/920723-1.c
>   gcc.c-torture/compile/pr33855.c
>   gcc.c-torture/execute/981019-1.c

I don't completely recall what reasons there were for ptxas crashes (or 
if we indeed reliably figured out the causes). Uninitialized registers 
come to mind, but I don't think I recall issues with noreturn.


Bernd
Nathan Sidwell Dec. 7, 2015, 5:34 p.m. UTC | #4
On 12/07/15 12:08, Alexander Monakov wrote:
> Hello Nathan,
>
> On Mon, 7 Dec 2015, Nathan Sidwell wrote:
>> This patch changes call emission to look for a noreturn note and emit a trap
>> insn after the call.  The JIT  no longer explodes.
>
> I think there's a potential issue with the patch: when the noreturn function
> has a non-void return value, your patch places 'trap' between 'call' and

Aren't noreturn fns required to be void?  It certainly doesn't make sense for 
them to do otherwise.

> 'ld.param' insns.  That violates the PTX specification, which demands:
>
>      All st.param instructions used for passing arguments to function call must
>      immediately precede the corresponding call instruction and ld.param
>      instruction used for collecting return value must immediately follow the
>      call instruction without any control flow alteration.

so I don't think this can happen ...

nathan
Bernd Schmidt Dec. 7, 2015, 5:42 p.m. UTC | #5
On 12/07/2015 06:34 PM, Nathan Sidwell wrote:

> Aren't noreturn fns required to be void?  It certainly doesn't make
> sense for them to do otherwise.

The documentation says "it makes no sense" for them to have a type other 
than void, but I don't think that translates into a requirement. I 
suppose you could imagine a situation where you call various functions 
through a given function pointer type, and one of them doesn't return 
and could be marked as such.


Bernd
Nathan Sidwell Dec. 7, 2015, 8:34 p.m. UTC | #6
On 12/07/15 12:42, Bernd Schmidt wrote:
> On 12/07/2015 06:34 PM, Nathan Sidwell wrote:
>
>> Aren't noreturn fns required to be void?  It certainly doesn't make
>> sense for them to do otherwise.
>
> The documentation says "it makes no sense" for them to have a type other than
> void, but I don't think that translates into a requirement. I suppose you could
> imagine a situation where you call various functions through a given function
> pointer type, and one of them doesn't return and could be marked as such.

experimentation shows PTX JIT is fine with the trap before (an unreachable) ld.param

nathan
diff mbox

Patch

2015-12-07  Nathan Sidwell  <nathan@acm.org>

	gcc/
	* config/nvptx/nvptx.c (nvptx_output_call_insn): Emit trap after no
	return call.

	gcc/testsuite/
	* gcc.target/nvptx/abort.c: New.

Index: config/nvptx/nvptx.c
===================================================================
--- config/nvptx/nvptx.c	(revision 231362)
+++ config/nvptx/nvptx.c	(working copy)
@@ -1890,6 +1890,13 @@  nvptx_output_call_insn (rtx_insn *insn,
     }
   fprintf (asm_out_file, ";\n");
 
+  if (find_reg_note (insn, REG_NORETURN, NULL))
+    /* No return functions confuse the PTX JIT, as it doesn't realize
+       the flow control barrier they imply.  It can seg fault if it
+       encounters what looks like an unexitable loop.  Emit a trailing
+       trap, which it does grok.  */
+    fprintf (asm_out_file, "\t\ttrap; // (noreturn)\n");
+
   return result != NULL_RTX ? "\tld.param%t0\t%0, [%%retval_in];\n\t}" : "}";
 }
 
Index: testsuite/gcc.target/nvptx/abort.c
===================================================================
--- testsuite/gcc.target/nvptx/abort.c	(revision 0)
+++ testsuite/gcc.target/nvptx/abort.c	(working copy)
@@ -0,0 +1,13 @@ 
+/* { dg-do compile} */
+/* Annotate no return functions with a trailing 'trap'.  */
+
+extern void abort ();
+
+int main (int argc, char **argv)
+{
+  if (argc > 2)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "call abort;\[\r\n\t \]+trap;" } } */