public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() @ 2021-02-18 14:45 sebastian.huber@embedded-brains.de 2021-02-18 14:52 ` [Bug c/99151] " jakub at gcc dot gnu.org ` (8 more replies) 0 siblings, 9 replies; 10+ messages in thread From: sebastian.huber@embedded-brains.de @ 2021-02-18 14:45 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 Bug ID: 99151 Summary: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sebastian.huber@embedded-brains.de Target Milestone: --- The following test code: _Noreturn void r(void); void u(void); void g(void) { r(); } void f(void) { u(); __builtin_unreachable(); } Produces code the following code on a sample set of architectures. There should be no stack frame set up. There should be no instructions after the no-return function calls (for example sparc). sparc-rtems6-gcc -O2 -o - -S unreachable.c .file "unreachable.c" .section ".text" .align 4 .global g .type g, #function .proc 020 g: save %sp, -96, %sp call r, 0 nop nop .size g, .-g .align 4 .global f .type f, #function .proc 020 f: save %sp, -96, %sp call u, 0 nop nop .size f, .-f .ident "GCC: (GNU) 10.2.1 20210205 (RTEMS 6, RSB 61dcadee0825867ebe51f9f367430ef75b8fe9c0, Newlib d4a756f)" arm-rtems6-gcc -O2 -o - -S unreachable.c .cpu arm7tdmi .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 2 .eabi_attribute 30, 2 .eabi_attribute 34, 0 .eabi_attribute 18, 4 .file "unreachable.c" .text .align 2 .global g .arch armv4t .syntax unified .arm .fpu softvfp .type g, %function g: @ Function supports interworking. @ Volatile: function does not return. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 push {r4, lr} bl r .size g, .-g .align 2 .global f .syntax unified .arm .fpu softvfp .type f, %function f: @ Function supports interworking. @ Volatile: function does not return. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 push {r4, lr} bl u .size f, .-f .ident "GCC: (GNU) 10.2.1 20210205 (RTEMS 6, RSB 61dcadee0825867ebe51f9f367430ef75b8fe9c0, Newlib d4a756f)" powerpc-rtems6-gcc -O2 -o - -S unreachable.c .file "unreachable.c" .machine ppc .section ".text" .align 2 .globl g .type g, @function g: .LFB0: .cfi_startproc stwu 1,-16(1) .cfi_def_cfa_offset 16 mflr 0 stw 0,20(1) .cfi_offset 65, 4 bl r .cfi_endproc .LFE0: .size g,.-g .align 2 .globl f .type f, @function f: .LFB1: .cfi_startproc stwu 1,-16(1) .cfi_def_cfa_offset 16 mflr 0 stw 0,20(1) .cfi_offset 65, 4 bl u .cfi_endproc .LFE1: .size f,.-f .ident "GCC: (GNU) 10.2.1 20210205 (RTEMS 6, RSB 61dcadee0825867ebe51f9f367430ef75b8fe9c0, Newlib d4a756f)" .section .note.GNU-stack,"",@progbits ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de @ 2021-02-18 14:52 ` jakub at gcc dot gnu.org 2021-02-18 14:56 ` sebastian.huber@embedded-brains.de ` (7 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: jakub at gcc dot gnu.org @ 2021-02-18 14:52 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- This is done intentionally, so that one gets e.g. usable backtraces from abort. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de 2021-02-18 14:52 ` [Bug c/99151] " jakub at gcc dot gnu.org @ 2021-02-18 14:56 ` sebastian.huber@embedded-brains.de 2021-02-18 19:15 ` pinskia at gcc dot gnu.org ` (6 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: sebastian.huber@embedded-brains.de @ 2021-02-18 14:56 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 --- Comment #2 from Sebastian Huber <sebastian.huber@embedded-brains.de> --- (In reply to Jakub Jelinek from comment #1) > This is done intentionally, so that one gets e.g. usable backtraces from > abort. Ok, the stack frame could be a feature. The extra nop on SPARC hurts a bit in my case since I have to show that my program has no unreachable code and here I get an unreachable nop: f: save %sp, -96, %sp call u, 0 nop nop <--------------- unreachable ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de 2021-02-18 14:52 ` [Bug c/99151] " jakub at gcc dot gnu.org 2021-02-18 14:56 ` sebastian.huber@embedded-brains.de @ 2021-02-18 19:15 ` pinskia at gcc dot gnu.org 2021-02-19 6:46 ` [Bug middle-end/99151] " sebastian.huber@embedded-brains.de ` (5 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: pinskia at gcc dot gnu.org @ 2021-02-18 19:15 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 --- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Is the nop due to alignment? ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de ` (2 preceding siblings ...) 2021-02-18 19:15 ` pinskia at gcc dot gnu.org @ 2021-02-19 6:46 ` sebastian.huber@embedded-brains.de 2021-03-01 11:17 ` ebotcazou at gcc dot gnu.org ` (4 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: sebastian.huber@embedded-brains.de @ 2021-02-19 6:46 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 --- Comment #4 from Sebastian Huber <sebastian.huber@embedded-brains.de> --- (In reply to Andrew Pinski from comment #3) > Is the nop due to alignment? With -g and -coverage I get this code: sparc-rtems7-gcc -O2 -o - -S unreachable.c -fverbose-asm -g -coverage .file "unreachable.c" ! GNU C17 (GCC) version 11.0.0 20210205 (RTEMS 7, RSB 61dcadee0825867ebe51f9f367430ef75b8fe9c0, Newlib d4a756f) (sparc-rtems7) ! compiled by GNU C version 11.0.0 20201130 (experimental) [revision b46314c78061a5156bac44a317c87d32b00d4295], GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.18-GMP ! GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ! options passed: -mcpu=v7 -g -O2 -fprofile-arcs -ftest-coverage .section ".text" .LLtext0: .cfi_sections .debug_frame .align 4 .global g .type g, #function .proc 020 g: .LLFB0: .file 1 "unreachable.c" .loc 1 5 1 view -0 .cfi_startproc save %sp, -96, %sp ! .cfi_window_save .cfi_register 15, 31 .cfi_def_cfa_register 30 sethi %hi(__gcov0.g), %g1 !, tmp112 ldd [%g1+%lo(__gcov0.g)], %i4 ! __gcov0.g[0], __gcov0.g[0] addcc %i5, 1, %g3 ! __gcov0.g[0],, tmp115 addx %i4, 0, %g2 ! __gcov0.g[0],, .loc 1 6 9 view .LLVU1 call r, 0 !, .LLVL0: std %g2, [%g1+%lo(__gcov0.g)] ! tmp115, __gcov0.g[0] nop In the the no-return function case, this nop has no line debug information and there is no profiling counter increment. .cfi_endproc .LLFE0: .size g, .-g .align 4 .global f .type f, #function .proc 020 f: .LLFB1: .loc 1 11 1 view -0 .cfi_startproc save %sp, -96, %sp ! .cfi_window_save .cfi_register 15, 31 .cfi_def_cfa_register 30 sethi %hi(__gcov0.f), %g1 !, tmp114 ldd [%g1+%lo(__gcov0.f)], %i2 ! __gcov0.f[0], __gcov0.f[0] addcc %i3, 1, %g3 ! __gcov0.f[0],, tmp117 addx %i2, 0, %g2 ! __gcov0.f[0],, or %g1, %lo(__gcov0.f), %i5 ! tmp114,, tmp113 .loc 1 12 9 view .LLVU3 call u, 0 !, .LLVL1: std %g2, [%g1+%lo(__gcov0.f)] ! tmp117, __gcov0.f[0] ldd [%i5+8], %i2 ! __gcov0.f[1], __gcov0.f[1] addcc %i3, 1, %g3 ! __gcov0.f[1],, tmp123 addx %i2, 0, %g2 ! __gcov0.f[1],, std %g2, [%i5+8] ! tmp123, __gcov0.f[1] .loc 1 13 9 view .LLVU4 .cfi_endproc .LLFE1: .size f, .-f In the __builtin_unreachable() case we don't have a nop, but a profiling counter increment is there. clang 9 generates this code: clang -O2 -o - -S unreachable.c -fverbose-asm -g -coverage --target=sparc .text .file "unreachable.c" .globl g ! -- Begin function g .p2align 2 .type g,@function g: ! @g .Lfunc_begin0: .file 1 "/home/EB/sebastian_h/src/rtems/unreachable.c" .loc 1 5 0 ! unreachable.c:5:0 .cfi_startproc ! %bb.0: save %sp, -96, %sp .cfi_def_cfa_register %fp .cfi_window_save .cfi_register 15, 31 .Ltmp0: .loc 1 6 9 prologue_end ! unreachable.c:6:9 sethi %hi(__llvm_gcov_ctr), %i0 ldd [%i0+%lo(__llvm_gcov_ctr)], %i2 addcc %i3, 1, %i5 addxcc %i2, 0, %i4 call r std %i4, [%i0+%lo(__llvm_gcov_ctr)] .Ltmp1: .Lfunc_end0: .size g, .Lfunc_end0-g .cfi_endproc ! -- End function .globl f ! -- Begin function f .p2align 2 .type f,@function f: ! @f .Lfunc_begin1: .loc 1 11 0 ! unreachable.c:11:0 .cfi_startproc ! %bb.0: save %sp, -96, %sp .cfi_def_cfa_register %fp .cfi_window_save .cfi_register 15, 31 .Ltmp2: .loc 1 12 9 prologue_end ! unreachable.c:12:9 sethi %hi(__llvm_gcov_ctr.1), %i0 ldd [%i0+%lo(__llvm_gcov_ctr.1)], %i2 addcc %i3, 1, %i5 addxcc %i2, 0, %i4 call u std %i4, [%i0+%lo(__llvm_gcov_ctr.1)] .Ltmp3: .Lfunc_end1: .size f, .Lfunc_end1-f .cfi_endproc ! -- End function There are no nops and no unreachable profiling counter increments. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de ` (3 preceding siblings ...) 2021-02-19 6:46 ` [Bug middle-end/99151] " sebastian.huber@embedded-brains.de @ 2021-03-01 11:17 ` ebotcazou at gcc dot gnu.org 2021-03-01 12:36 ` sebastian.huber@embedded-brains.de ` (3 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: ebotcazou at gcc dot gnu.org @ 2021-03-01 11:17 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 Eric Botcazou <ebotcazou at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ebotcazou at gcc dot gnu.org Status|UNCONFIRMED |RESOLVED Resolution|--- |WONTFIX --- Comment #5 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- static void sparc_asm_function_epilogue (FILE *file) { /* If the last two instructions of a function are "call foo; dslot;" the return address might point to the first instruction in the next function and we have to output a dummy nop for the sake of sane backtraces in such cases. This is pointless for sibling calls since the return address is explicitly adjusted. */ ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de ` (4 preceding siblings ...) 2021-03-01 11:17 ` ebotcazou at gcc dot gnu.org @ 2021-03-01 12:36 ` sebastian.huber@embedded-brains.de 2021-03-01 12:53 ` ebotcazou at gcc dot gnu.org ` (2 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: sebastian.huber@embedded-brains.de @ 2021-03-01 12:36 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 --- Comment #6 from Sebastian Huber <sebastian.huber@embedded-brains.de> --- (In reply to Eric Botcazou from comment #5) > static void > sparc_asm_function_epilogue (FILE *file) > { > /* If the last two instructions of a function are "call foo; dslot;" > the return address might point to the first instruction in the next > function and we have to output a dummy nop for the sake of sane > backtraces in such cases. This is pointless for sibling calls since > the return address is explicitly adjusted. */ This nop behaviour could be a bit inconsistent across architectures. For example, arm and powerpc don't generate a nop here. I still think that the profiling counter increment in the __builtin_unreachable() path is a bug. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de ` (5 preceding siblings ...) 2021-03-01 12:36 ` sebastian.huber@embedded-brains.de @ 2021-03-01 12:53 ` ebotcazou at gcc dot gnu.org 2021-03-01 13:04 ` sebastian.huber@embedded-brains.de 2021-03-01 13:21 ` jakub at gcc dot gnu.org 8 siblings, 0 replies; 10+ messages in thread From: ebotcazou at gcc dot gnu.org @ 2021-03-01 12:53 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 --- Comment #7 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- > This nop behaviour could be a bit inconsistent across architectures. For > example, arm and powerpc don't generate a nop here. Well, it's low-level trickery so architecture-dependent by definition. > I still think that the profiling counter increment in the > __builtin_unreachable() path is a bug. How so? I only see a missed optimization, but with -fprofile-arcs -ftest-coverage you're splitting hairs IMO. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de ` (6 preceding siblings ...) 2021-03-01 12:53 ` ebotcazou at gcc dot gnu.org @ 2021-03-01 13:04 ` sebastian.huber@embedded-brains.de 2021-03-01 13:21 ` jakub at gcc dot gnu.org 8 siblings, 0 replies; 10+ messages in thread From: sebastian.huber@embedded-brains.de @ 2021-03-01 13:04 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 --- Comment #8 from Sebastian Huber <sebastian.huber@embedded-brains.de> --- (In reply to Eric Botcazou from comment #7) > > I still think that the profiling counter increment in the > > __builtin_unreachable() path is a bug. > > How so? I only see a missed optimization, but with -fprofile-arcs > -ftest-coverage you're splitting hairs IMO. The __builtin_unreachable() explicitly mentions the use case with a function which doesn't return in the documentation: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html I would expect from the compiler that it generates then similar code. Having a profiling counter increment in one case and not in the other is not really a nice behaviour. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de ` (7 preceding siblings ...) 2021-03-01 13:04 ` sebastian.huber@embedded-brains.de @ 2021-03-01 13:21 ` jakub at gcc dot gnu.org 8 siblings, 0 replies; 10+ messages in thread From: jakub at gcc dot gnu.org @ 2021-03-01 13:21 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151 Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at gcc dot gnu.org, | |marxin at gcc dot gnu.org --- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- We certainly don't claim it is the exact same thing as using the noreturn attribute, it is not. We could in profile.c ignore edges that lead to basic blocks that start with __builtin_unreachable () call as the first non-debug stmt after labels if it was really important, but I'm not convinced it is. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-03-01 13:21 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-02-18 14:45 [Bug c/99151] New: Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable() sebastian.huber@embedded-brains.de 2021-02-18 14:52 ` [Bug c/99151] " jakub at gcc dot gnu.org 2021-02-18 14:56 ` sebastian.huber@embedded-brains.de 2021-02-18 19:15 ` pinskia at gcc dot gnu.org 2021-02-19 6:46 ` [Bug middle-end/99151] " sebastian.huber@embedded-brains.de 2021-03-01 11:17 ` ebotcazou at gcc dot gnu.org 2021-03-01 12:36 ` sebastian.huber@embedded-brains.de 2021-03-01 12:53 ` ebotcazou at gcc dot gnu.org 2021-03-01 13:04 ` sebastian.huber@embedded-brains.de 2021-03-01 13:21 ` jakub at gcc dot gnu.org
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).