Skip to content

[aarch64] Potential tail call miscompilation, causing branch protection to fault #167181

@3405691582

Description

@3405691582

Here is a reasonably minimal reproducing case (see https://godbolt.org/z/3jxdMY44d):

define internal tailcc void @g(ptr swiftasync %0) #0 {
  call ptr @h() #2
  musttail call tailcc void@f(
    ptr null, ptr null, ptr null, ptr null, 
    ptr null, ptr null, ptr null, ptr null, ptr null) 
  ret void
}

define void @f(ptr, ptr, ptr, ptr, ptr, ptr, ptr, 
    ptr, ptr, ptr) #0 {
        ret void
}

define void @h() #2 {
    ret void
}

define protected i32 @main(i32 %0, ptr %1) #0 {
entry:
  call void @g()
  ret i32 0
}

attributes #0 = { 
    "branch-target-enforcement" 
    "frame-pointer"="non-leaf" 
    "no-trapping-math"="true" 
    "sign-return-address"="non-leaf" 
    "sign-return-address-key"="a_key" 
    "stack-protector-buffer-size"="8" 
    "target-cpu"="generic"
    "target-features"="+fp-armv8,+neon,+strict-align,+v8a" 
}

!llvm.module.flags = !{!2, !3}

!2 = !{i32 8, !"branch-target-enforcement", i32 1}
!3 = !{i32 8, !"sign-return-address", i32 1}

Function g's stack pointer appears to not be restored properly:

g:
        hint    #25
        orr     x29, x29, #0x1000000000000000
        sub     sp, sp, #48
...
        add     sp, sp, #32
        hint    #29
        b       f

(This causes crashes in Swift when branch protection is enabled since Swift uses tail-calls in its concurrency system, see swiftlang/swift#80059)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions