https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81820
Bug ID: 81820 Summary: -Os may remove debug info Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com CC: ubizjak at gmail dot com Target Milestone: --- Target: x86 r251028 improves -Os on x86 since -Os implies -fno-omit-frame-pointer and r251028 removes frame pointer when it is not needed: [hjl@gnu-tools-1 debug]$ cat y.c struct S { float f, g; }; void foo (struct S *p) { struct S s1, s2; s1 = *p; s2 = s1; *(int *) &s2.f = 0; asm volatile ("nop" : : : "memory"); asm volatile ("nop" : : : "memory"); s2 = s1; asm volatile ("nop" : : : "memory"); asm volatile ("nop" : : : "memory"); } [hjl@gnu-tools-1 debug]$ /usr/gcc-7.1.1-x32/bin/gcc -S -Os -m32 y.c [hjl@gnu-tools-1 debug]$ cat y.s .file "y.c" .text .globl foo .type foo, @function foo: .LFB0: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 #APP # 10 "y.c" 1 nop # 0 "" 2 # 11 "y.c" 1 nop # 0 "" 2 # 13 "y.c" 1 nop # 0 "" 2 # 14 "y.c" 1 nop # 0 "" 2 #NO_APP popl %ebp .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc .LFE0: .size foo, .-foo .ident "GCC: (GNU) 7.1.1 20170724" .section .note.GNU-stack,"",@progbits [hjl@gnu-tools-1 debug]$ /export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -Os -S -m32 y.c [hjl@gnu-tools-1 debug]$ cat y.s .file "y.c" .text .globl foo .type foo, @function foo: .LFB0: .cfi_startproc #APP # 10 "y.c" 1 nop # 0 "" 2 # 11 "y.c" 1 nop # 0 "" 2 # 13 "y.c" 1 nop # 0 "" 2 # 14 "y.c" 1 nop # 0 "" 2 #NO_APP ret .cfi_endproc .LFE0: .size foo, .-foo .ident "GCC: (GNU) 8.0.0 20170811 (experimental)" .section .note.GNU-stack,"",@progbits [hjl@gnu-tools-1 debug]$ However with -Os -g, frame pointer is used in debug_insn: (note 3 4 6 2 NOTE_INSN_FUNCTION_BEG) (debug_insn 6 3 7 2 (var_location:SF D#4 (mem:SF (mem/f/c:SI (plus:SI (reg/f:SI 6 bp) (const_int 8 [0x8])) [4 p+0 S4 A32]) [0 MEM[(struct S *)p_2(D)]+0 S4 A32])) "y.c":7 -1 (nil)) (debug_insn 7 6 8 2 (var_location:SF s1$f (debug_expr:SF D#4)) "y.c":7 -1 (nil)) (debug_insn 8 7 9 2 (var_location:SF D#3 (mem:SF (plus:SI (mem/f/c:SI (plus:SI (reg/f:SI 6 bp) (const_int 8 [0x8])) [4 p+0 S4 A32]) (const_int 4 [0x4])) [0 MEM[(struct S *)p_2(D) + 4B]+0 S4 A32])) "y.c":7 -1 (nil)) (debug_insn 9 8 11 2 (var_location:SF s1$g (debug_expr:SF D#3)) "y.c":7 -1 (nil)) (debug_insn 11 9 12 2 (var_location:SF s2$g (debug_expr:SF D#3)) "y.c":8 -1 (nil)) (debug_insn 12 11 13 2 (var_location:SI s2 (const_int 0 [0])) "y.c":9 -1 (nil)) (insn 13 12 14 2 (parallel [ (asm_operands/v ("nop") ("") 0 [] [] [] y.c:10) (clobber (mem:BLK (scratch) [0 A8])) (clobber (reg:CCFP 18 fpsr)) (clobber (reg:CC 17 flags)) ]) "y.c":10 -1 (nil)) before frame pointer is eliminated. After frame pointer is eliminated, these debug insns are removed and debug info is lost. We should update debug_insn when frame pointer is removed to ensure that -g doesn't change codegen.