https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105772
Bug ID: 105772 Summary: [debug, i386] sched2 moves get_pc_thunk call past debug_insn Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- Consider the test-case source gdb/testsuite/gdb.base/break1.c ( https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/testsuite/gdb.base/break1.c;h=24d0d15dc2e8bd14f6b14fabbb38fec43db9c990;hb=HEAD ) containing function marker4. Extracting the relevant part: ... struct some_struct { int a_field; int b_field; union { int z_field; }; }; struct some_struct values[50]; void marker4 (long d) { values[0].a_field = d; } /* set breakpoint 14 here */ ... When compiling with gcc 12.1.0 and -O2 like so: ... $ gcc -fno-stack-protector -m32 -fPIE -pie -w -c -g break1.c -O2 ... we have before sched2: ... (note 4 1 14 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 14 4 11 2 NOTE_INSN_PROLOGUE_END) (insn/f 11 14 3 2 (parallel [ (set (reg:SI 0 ax [82]) (unspec:SI [ (const_int 0 [0]) ] UNSPEC_SET_GOT)) (clobber (reg:CC 17 flags)) ]) 931 {*set_got} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUIV (unspec:SI [ (const_int 0 [0]) ] UNSPEC_SET_GOT) (expr_list:REG_CFA_FLUSH_QUEUE (nil) (nil))))) (note 3 11 6 2 NOTE_INSN_FUNCTION_BEG) (debug_insn 6 3 12 2 (debug_marker) "break1.c":59:25 -1 (nil)) (insn 12 6 8 2 (set (reg/v:SI 1 dx [orig:83 d ] [83]) (mem/c:SI (plus:SI (reg/f:SI 7 sp) (const_int 4 [0x4])) [5 d+0 S4 A32])) "break1.c":59:43 81 {*movsi_internal} (expr_list:REG_EQUIV (mem/c:SI (reg/f:SI 16 argp) [5 d+0 S4 A32]) (nil))) ... and after: ... (note 4 1 14 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 14 4 3 2 NOTE_INSN_PROLOGUE_END) (note 3 14 6 2 NOTE_INSN_FUNCTION_BEG) (debug_insn 6 3 11 2 (debug_marker) "break1.c":59:25 -1 (nil)) (insn/f:TI 11 6 12 2 (parallel [ (set (reg:SI 0 ax [82]) (unspec:SI [ (const_int 0 [0]) ] UNSPEC_SET_GOT)) (clobber (reg:CC 17 flags)) ]) 931 {*set_got} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUIV (unspec:SI [ (const_int 0 [0]) ] UNSPEC_SET_GOT) (expr_list:REG_CFA_FLUSH_QUEUE (nil) (nil))))) (insn 12 11 8 2 (set (reg/v:SI 1 dx [orig:83 d ] [83]) (mem/c:SI (plus:SI (reg/f:SI 7 sp) (const_int 4 [0x4])) [5 d+0 S4 A32])) "break1.c":59:43 81 {*movsi_internal} (expr_list:REG_EQUIV (mem/c:SI (reg/f:SI 16 argp) [5 d+0 S4 A32]) (nil))) ... This moves the get_pc_thunk call after the debug_insn, making it (in terms of debug info) part of the first statement instead of the prologue. That is, with -O1 we have insn: ... 0000000d <marker4>: d: e8 fc ff ff ff call e <marker4+0x1> 12: 05 01 00 00 00 add $0x1,%eax 17: 8b 54 24 04 mov 0x4(%esp),%edx 1b: 89 90 00 00 00 00 mov %edx,0x0(%eax) 21: c3 ret ... and line info: ... File name Line number Starting address View Stmt break1.c 59 0xd x break1.c 59 0xd 1 break1.c 59 0x17 x break1.c 59 0x17 1 break1.c 59 0x21 break1.c - 0x22 ... so at 0x17 we have the start of a statement. But with -O2 we have identical insn: ... 00000030 <marker4>: 30: e8 fc ff ff ff call 31 <marker4+0x1> 35: 05 01 00 00 00 add $0x1,%eax 3a: 8b 54 24 04 mov 0x4(%esp),%edx 3e: 89 90 00 00 00 00 mov %edx,0x0(%eax) 44: c3 ret ... but different line info: ... File name Line number Starting address View Stmt break1.c 59 0x30 x break1.c 59 0x30 1 x break1.c 59 0x3a break1.c 59 0x44 break1.c - 0x45 ... so at 0x3a we don't have the start of a statement.