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