CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
195 lines
7.0 KiB
LLVM
195 lines
7.0 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=corei7 < %s | FileCheck %s
|
|
|
|
; This test checks various function call behaviors between preserve_none and
|
|
; normal calling conventions.
|
|
|
|
declare preserve_nonecc void @callee(ptr)
|
|
|
|
; Normal caller calls preserve_none callee. Will not generated tail call because
|
|
; of incompatible calling convention. Callee saved registers are saved/restored
|
|
; around the call.
|
|
define void @caller1(ptr %a) {
|
|
; CHECK-LABEL: caller1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: pushq %r14
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24
|
|
; CHECK-NEXT: pushq %r13
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: pushq %r12
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 40
|
|
; CHECK-NEXT: pushq %rbx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-NEXT: .cfi_offset %rbx, -48
|
|
; CHECK-NEXT: .cfi_offset %r12, -40
|
|
; CHECK-NEXT: .cfi_offset %r13, -32
|
|
; CHECK-NEXT: .cfi_offset %r14, -24
|
|
; CHECK-NEXT: .cfi_offset %r15, -16
|
|
; CHECK-NEXT: movq %rdi, %r12
|
|
; CHECK-NEXT: callq callee@PLT
|
|
; CHECK-NEXT: popq %rbx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 40
|
|
; CHECK-NEXT: popq %r12
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: popq %r13
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24
|
|
; CHECK-NEXT: popq %r14
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: popq %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
tail call preserve_nonecc void @callee(ptr %a)
|
|
ret void
|
|
}
|
|
|
|
; Preserve_none caller calls preserve_none callee. Same function body.
|
|
; The tail call is preserved. No registers are saved/restored around the call.
|
|
; Actually a simple jmp instruction is generated.
|
|
define preserve_nonecc void @caller2(ptr %a) {
|
|
; CHECK-LABEL: caller2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: jmp callee@PLT # TAILCALL
|
|
tail call preserve_nonecc void @callee(ptr %a)
|
|
ret void
|
|
}
|
|
|
|
%S = type { [3 x i64] }
|
|
declare preserve_nonecc void @callee_byval(ptr byval(%S) align 8)
|
|
|
|
; Preserve_none caller with a byval argument from a local alloca should not
|
|
; be lowered as a sibling tail call, as this would corrupt the stack frame
|
|
; containing the byval copy.
|
|
define preserve_nonecc void @caller_byval_alloca() {
|
|
; CHECK-LABEL: caller_byval_alloca:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: subq $56, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 64
|
|
; CHECK-NEXT: xorps %xmm0, %xmm0
|
|
; CHECK-NEXT: movups %xmm0, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: movups %xmm0, (%rsp)
|
|
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: callq callee_byval@PLT
|
|
; CHECK-NEXT: addq $56, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
%s = alloca %S, align 8
|
|
%a0 = getelementptr inbounds %S, ptr %s, i32 0, i32 0, i32 0
|
|
store i64 0, ptr %a0, align 8
|
|
%a1 = getelementptr inbounds %S, ptr %s, i32 0, i32 0, i32 1
|
|
store i64 0, ptr %a1, align 8
|
|
%a2 = getelementptr inbounds %S, ptr %s, i32 0, i32 0, i32 2
|
|
store i64 0, ptr %a2, align 8
|
|
tail call preserve_nonecc void @callee_byval(ptr byval(%S) align 8 %s)
|
|
ret void
|
|
}
|
|
|
|
; Test that byval arguments from an incoming pointer are correctly copied.
|
|
define preserve_nonecc void @caller_byval_ptr(ptr %a) {
|
|
; CHECK-LABEL: caller_byval_ptr:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: subq $24, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: movq 16(%r12), %rax
|
|
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: movups (%r12), %xmm0
|
|
; CHECK-NEXT: movups %xmm0, (%rsp)
|
|
; CHECK-NEXT: callq callee_byval@PLT
|
|
; CHECK-NEXT: addq $24, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
call preserve_nonecc void @callee_byval(ptr byval(%S) align 8 %a)
|
|
ret void
|
|
}
|
|
|
|
; Preserve_none function can use more registers to pass parameters.
|
|
declare preserve_nonecc i64 @callee_with_many_param2(i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11)
|
|
define preserve_nonecc i64 @callee_with_many_param(i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12) {
|
|
; CHECK-LABEL: callee_with_many_param:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: movq %r13, %r12
|
|
; CHECK-NEXT: movq %r14, %r13
|
|
; CHECK-NEXT: movq %r15, %r14
|
|
; CHECK-NEXT: movq %rdi, %r15
|
|
; CHECK-NEXT: movq %rsi, %rdi
|
|
; CHECK-NEXT: movq %rdx, %rsi
|
|
; CHECK-NEXT: movq %rcx, %rdx
|
|
; CHECK-NEXT: movq %r8, %rcx
|
|
; CHECK-NEXT: movq %r9, %r8
|
|
; CHECK-NEXT: movq %r11, %r9
|
|
; CHECK-NEXT: movq %rax, %r11
|
|
; CHECK-NEXT: callq callee_with_many_param2@PLT
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
%ret = call preserve_nonecc i64 @callee_with_many_param2(i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12)
|
|
ret i64 %ret
|
|
}
|
|
|
|
define i64 @caller3() {
|
|
; CHECK-LABEL: caller3:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: pushq %r14
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24
|
|
; CHECK-NEXT: pushq %r13
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: pushq %r12
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 40
|
|
; CHECK-NEXT: pushq %rbx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-NEXT: .cfi_offset %rbx, -48
|
|
; CHECK-NEXT: .cfi_offset %r12, -40
|
|
; CHECK-NEXT: .cfi_offset %r13, -32
|
|
; CHECK-NEXT: .cfi_offset %r14, -24
|
|
; CHECK-NEXT: .cfi_offset %r15, -16
|
|
; CHECK-NEXT: movl $1, %r12d
|
|
; CHECK-NEXT: movl $2, %r13d
|
|
; CHECK-NEXT: movl $3, %r14d
|
|
; CHECK-NEXT: movl $4, %r15d
|
|
; CHECK-NEXT: movl $5, %edi
|
|
; CHECK-NEXT: movl $6, %esi
|
|
; CHECK-NEXT: movl $7, %edx
|
|
; CHECK-NEXT: movl $8, %ecx
|
|
; CHECK-NEXT: movl $9, %r8d
|
|
; CHECK-NEXT: movl $10, %r9d
|
|
; CHECK-NEXT: movl $11, %r11d
|
|
; CHECK-NEXT: movl $12, %eax
|
|
; CHECK-NEXT: callq callee_with_many_param@PLT
|
|
; CHECK-NEXT: popq %rbx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 40
|
|
; CHECK-NEXT: popq %r12
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: popq %r13
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24
|
|
; CHECK-NEXT: popq %r14
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: popq %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
%ret = call preserve_nonecc i64 @callee_with_many_param(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12)
|
|
ret i64 %ret
|
|
}
|
|
|
|
; Non-volatile registers are used to pass the first few parameters.
|
|
declare void @boring()
|
|
declare preserve_nonecc void @continuation(ptr, ptr, ptr, ptr)
|
|
define preserve_nonecc void @entry(ptr %r12, ptr %r13, ptr %r14, ptr %r15) {
|
|
; CHECK-LABEL: entry:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: callq boring@PLT
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: jmp continuation@PLT # TAILCALL
|
|
call void @boring()
|
|
musttail call preserve_nonecc void @continuation(ptr %r12, ptr %r13, ptr %r14, ptr %r15)
|
|
ret void
|
|
}
|