[Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable()

2021-03-01 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151

Jakub Jelinek  changed:

   What|Removed |Added

 CC||hubicka at gcc dot gnu.org,
   ||marxin at gcc dot gnu.org

--- Comment #9 from Jakub Jelinek  ---
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.

[Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable()

2021-03-01 Thread sebastian.huber--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151

--- Comment #8 from Sebastian Huber  ---
(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.

[Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable()

2021-03-01 Thread ebotcazou at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151

--- Comment #7 from Eric Botcazou  ---
> 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.

[Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable()

2021-03-01 Thread sebastian.huber--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151

--- Comment #6 from Sebastian Huber  ---
(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.

[Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable()

2021-03-01 Thread ebotcazou at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151

Eric Botcazou  changed:

   What|Removed |Added

 CC||ebotcazou at gcc dot gnu.org
 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |WONTFIX

--- Comment #5 from Eric Botcazou  ---
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.  */

[Bug middle-end/99151] Missed optimization: Superfluous stack frame and code with noreturn or __builtin_unreachable()

2021-02-18 Thread sebastian.huber--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99151

--- Comment #4 from Sebastian Huber  ---
(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
callr, 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
callu, 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
.p2align2
.type   g,@function
g:  ! @g
.Lfunc_begin0:
.file   1 "/home/EB/sebastian_h/src/rtems/unreachable.c"
.loc1 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:
.loc1 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
.p2align2
.type   f,@function
f:  ! @f
.Lfunc_begin1:
.loc1 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:
.loc1 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.