It turned out we can't simply emit trap insn during epilogue
expansion, since epilogue is expanded on FALLTHRU edge to EXIT BB.
Later passes rightfully choke on control flow insn in BB with FALTHRU
exit edge.

So, instead of using TRAP_IF in the prologue, use UNSPEC_VOLATILE that
directly emits "ud2".

2017-08-02  Uros Bizjak  <ubiz...@gmail.com>

    PR target/81644
    * config/i386/i386.md (unspecv): Add UNSPECV_UD2.
    (ud2): New insn pattern.
    * config/i386/i386.c (ix86_expand_epilogue):
    For naked functions, generate ud2 instead of trap insn

testsuite/ChangeLog:

2017-08-02  Uros Bizjak  <ubiz...@gmail.com>

    PR target/81644
    * gcc.target/i386/pr81644.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c  (revision 250818)
+++ config/i386/i386.c  (working copy)
@@ -15199,7 +15199,7 @@ ix86_expand_epilogue (int style)
   if (ix86_function_naked (current_function_decl))
     {
       /* The program should not reach this point.  */
-      emit_insn (gen_trap ());
+      emit_insn (gen_ud2 ());
       return;
     }
 
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 250818)
+++ config/i386/i386.md (working copy)
@@ -201,6 +201,7 @@
 ])
 
 (define_c_enum "unspecv" [
+  UNSPECV_UD2
   UNSPECV_BLOCKAGE
   UNSPECV_STACK_PROBE
   UNSPECV_PROBE_STACK_RANGE
@@ -18606,6 +18607,18 @@
 }
   [(set_attr "length" "2")])
 
+(define_insn "ud2"
+  [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
+  ""
+{
+#ifdef HAVE_AS_IX86_UD2
+  return "ud2";
+#else
+  return ASM_SHORT "0x0b0f";
+#endif
+}
+  [(set_attr "length" "2")])
+
 (define_expand "prefetch"
   [(prefetch (match_operand 0 "address_operand")
             (match_operand:SI 1 "const_int_operand")
Index: testsuite/gcc.target/i386/pr81644.c
===================================================================
--- testsuite/gcc.target/i386/pr81644.c (nonexistent)
+++ testsuite/gcc.target/i386/pr81644.c (working copy)
@@ -0,0 +1,15 @@
+/* PR target/81644 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-mregparm=1" { target ia32 } } */
+
+void b (void);
+
+void
+__attribute__ ((naked))
+a (int z)
+{
+  if (z)
+    return;
+  b ();
+}

Reply via email to