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 (); +}