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.