Skip to content

cmd/compile: emits unnecessary deferreturn #5712

@dvyukov

Description

@dvyukov
parent: 17086:2879112bff3d tip, linux/amd64

The program is:

package main

import "sync"

func main() {
    println(foo(0))
}

func foo(x int) int {
    // fast path
    if x != 42 {
        return x
    }
    // slow path
    mu.Lock()
    defer mu.Unlock()
    seq++
    return seq
}

var (
    mu  sync.Mutex
    seq int
)

The generated code for fast path is:

func foo(x int) int {
  400c40:       64 48 8b 0c 25 f0 ff    mov    %fs:0xfffffffffffffff0,%rcx
  400c47:       ff ff 
  400c49:       48 3b 21                cmp    (%rcx),%rsp
  400c4c:       77 05                   ja     400c53 <main.foo+0x13>
  400c4e:       e8 bd 81 01 00          callq  418e10 <runtime.morestack16>
  400c53:       48 83 ec 08             sub    $0x8,%rsp
  400c57:       48 8b 44 24 10          mov    0x10(%rsp),%rax
  400c5c:       48 c7 44 24 18 00 00    movq   $0x0,0x18(%rsp)
  400c63:       00 00 
        if x != 42 {
  400c65:       48 83 f8 2a             cmp    $0x2a,%rax
  400c69:       74 0f                   je     400c7a <main.foo+0x3a>
                return x
  400c6b:       48 89 44 24 18          mov    %rax,0x18(%rsp)
        }
        mu.Lock()
        defer mu.Unlock()
        seq++
        return seq
}
  400c70:       e8 eb b7 00 00          callq  40c460 <runtime.deferreturn>
  400c75:       48 83 c4 08             add    $0x8,%rsp
  400c79:       c3                      retq   


If the compiler performs some CFG analysis, it can figure out that 'callq
runtime.deferreturn' is unnecessary in this case.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions