https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66215
Bug ID: 66215 Summary: [4.8/4.9/5/6 Regression] Wrong after label NOP emission for -mhotpatch Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: marxin at gcc dot gnu.org Target Milestone: --- Target: 390-linux Hi. Starting from r221381 GCC does not place nops right after function label. Unfortunately, the problematic patch was also backported to gcc4-[89] and gcc-5. $ cat /tmp/s390.c static int foo() { return 0; } int main(int argc, char **argv) { return foo(); } $ ./xgcc -B. /tmp/s390.c -mhotpatch=2,3 -o o0.s -S -fno-inline $ cat o0.s | head .. .text .align 8 .type foo, @function nopr %r7 # pre-label NOPs for hotpatch (2 halfwords) nopr %r7 # alignment for hotpatch .align 8 foo: # post-label NOPs for hotpatch (3 halfwords) .LFB0: stm %r11,%r14,44(%r15) .LCFI0: lr %r11,%r15 .LCFI1: nop 0 nopr %r7 lhi %r1,0 lr %r2,%r1 l %r4,56(%r11) lm %r11,%r14,44(%r11) .LCFI2: br %r4 Problem is that patched compiler relies that NOTE_INSN_FUNCTION_BEG is at the beginning of function. /* Inject nops for hotpatching. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + { + if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + break; + } Problem is that if you use -O2, 256r.sched2 reorders insns after pro_and_epilogue, where NOTE_INSN_FUNCTION_BEG is placed at the beginning. On the other hand, if you try -O0, -O1, as the pass is not executed, emission of NOTE_INSN_FUNCTION_BEG is not reordered. $ cat s390.c.242r.pro_and_epilogue foo (note 1 0 5 NOTE_INSN_DELETED) (note 5 1 18 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (insn/f 18 5 19 2 (set (mem:SI (plus:SI (reg/f:SI 15 %r15) (const_int 56 [0x38])) [1 S4 A8]) (reg:SI 14 %r14)) /tmp/s390.c:7 -1 (nil)) (insn 19 18 20 2 (set (reg:SI 5 %r5) (unspec_volatile [ (const_int 0 [0]) ] UNSPECV_MAIN_POOL)) /tmp/s390.c:7 -1 (nil)) (note 20 19 17 2 NOTE_INSN_PROLOGUE_END) (insn 17 20 4 2 (set (reg:SI 5 %r5) (unspec_volatile [ (const_int 0 [0]) ] UNSPECV_MAIN_POOL)) 675 {main_pool} (nil)) (note 4 17 8 2 NOTE_INSN_FUNCTION_BEG) (insn 8 4 24 2 (set (reg:SI 1 %r1) (mem/u/c:SI (unspec:SI [ (symbol_ref/u:SI ("*.LC0") [flags 0x2]) (reg:SI 5 %r5) ] UNSPEC_LTREF) [2 S4 A32])) /tmp/s390.c:8 68 {*movsi_esa} (expr_list:REG_EQUAL (symbol_ref:SI ("foo") [flags 0x3] <function_decl 0x7fc55997e3e0 foo>) (nil))) (note 24 8 23 2 NOTE_INSN_EPILOGUE_BEG) (insn/f 23 24 9 2 (set (reg:SI 14 %r14) (mem:SI (plus:SI (reg/f:SI 15 %r15) (const_int 56 [0x38])) [1 S4 A8])) /tmp/s390.c:9 -1 (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI 15 %r15) (const_int 96 [0x60])) (expr_list:REG_CFA_RESTORE (reg:SI 14 %r14) (nil)))) (call_insn/u/j 9 23 10 2 (set (reg:SI 2 %r2) (call (mem:QI (reg:SI 1 %r1) [0 foo S1 A8]) (const_int 0 [0]))) /tmp/s390.c:8 631 {*sibcall_value_br} (expr_list:REG_CALL_DECL (symbol_ref:SI ("foo") [flags 0x3] <function_decl 0x7fc55997e3e0 foo>) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil))) (nil)) (barrier 10 9 16) (note 16 10 0 NOTE_INSN_DELETED) $ cat s390.c.256r.sched2 (note 1 0 3 NOTE_INSN_DELETED) (note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 2 3 15 2 NOTE_INSN_FUNCTION_BEG) (insn/f 15 2 16 2 (set (mem:SI (plus:SI (reg/f:SI 15 %r15) (const_int 56 [0x38])) [1 S4 A8]) (reg:SI 14 %r14)) /tmp/s390.c:2 68 {*movsi_esa} (expr_list:REG_DEAD (reg:SI 14 %r14) (nil))) (insn 16 15 17 2 (set (reg:SI 5 %r5) (unspec_volatile [ (const_int 0 [0]) ] UNSPECV_MAIN_POOL)) /tmp/s390.c:2 675 {main_pool} (expr_list:REG_UNUSED (reg:SI 5 %r5) (nil))) (note 17 16 14 2 NOTE_INSN_PROLOGUE_END) (insn 14 17 25 2 (set (reg:SI 5 %r5) (unspec_volatile [ (const_int 0 [0]) ] UNSPECV_MAIN_POOL)) 675 {main_pool} (expr_list:REG_UNUSED (reg:SI 5 %r5) (nil))) (note 25 14 21 2 NOTE_INSN_EPILOGUE_BEG) (insn 21 25 9 2 (set (reg:SI 4 %r4) (mem:SI (plus:SI (reg/f:SI 15 %r15) (const_int 56 [0x38])) [1 S4 A8])) /tmp/s390.c:4 68 {*movsi_esa} (nil)) (insn 9 21 22 2 (set (reg/i:SI 2 %r2) (const_int 0 [0])) /tmp/s390.c:4 68 {*movsi_esa} (nil)) (insn/f 22 9 10 2 (set (reg:SI 14 %r14) (mem:SI (plus:SI (reg/f:SI 15 %r15) (const_int 56 [0x38])) [1 S4 A8])) /tmp/s390.c:4 68 {*movsi_esa} (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI 15 %r15) (const_int 96 [0x60])) (expr_list:REG_CFA_RESTORE (reg:SI 14 %r14) (nil)))) (insn 10 22 23 2 (use (reg/i:SI 2 %r2)) /tmp/s390.c:4 -1 (nil)) (jump_insn 23 10 24 2 (parallel [ (return) (use (reg:SI 4 %r4)) ]) /tmp/s390.c:4 681 {*return} (expr_list:REG_DEAD (reg:SI 4 %r4) (nil)) -> return) So the question is if NOTE_INSN_FUNCTION_BEG is not correctly located by pro_and_epilogue, or we should fix NOP emission? Thanks, Martin