brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 3a8368a Raw
96 lines · plain
1; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTAARCH64 %s2; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s3; RUN: llc -verify-machineinstrs -mtriple=aarch64-unknown-linux-gnu -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTAARCH64 %s4; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTARM64_32 %s5 6; Parameter with swiftself should be allocated to x20.7; CHECK-LABEL: swiftself_param:8; CHECK: mov x0, x209; CHECK-NEXT: ret10define ptr @swiftself_param(ptr swiftself %addr0) {11  ret ptr %addr012}13 14; Check that x20 is used to pass a swiftself argument.15; CHECK-LABEL: call_swiftself:16; CHECK: mov x20, x017; CHECK: bl {{_?}}swiftself_param18; CHECK: ret19define ptr @call_swiftself(ptr %arg) {20  %res = call ptr @swiftself_param(ptr swiftself %arg)21  ret ptr %res22}23 24; x20 should be saved by the callee even if used for swiftself25; CHECK-LABEL: swiftself_clobber:26; CHECK: {{stp|str}} {{.*}}x20{{.*}}sp27; ...28; CHECK: {{ldp|ldr}} {{.*}}x20{{.*}}sp29; CHECK: ret30define ptr @swiftself_clobber(ptr swiftself %addr0) {31  call void asm sideeffect "", "~{x20}"()32  ret ptr %addr033}34 35; Demonstrate that we do not need any movs when calling multiple functions36; with swiftself argument.37; CHECK-LABEL: swiftself_passthrough:38; OPT-NOT: mov{{.*}}x2039; OPT: bl {{_?}}swiftself_param40; OPT-NOT: mov{{.*}}x2041; OPT-NEXT: bl {{_?}}swiftself_param42; OPT: ret43define void @swiftself_passthrough(ptr swiftself %addr0) {44  call ptr @swiftself_param(ptr swiftself %addr0)45  call ptr @swiftself_param(ptr swiftself %addr0)46  ret void47}48 49; We can use a tail call if the callee swiftself is the same as the caller one.50; This should also work with fast-isel.51; CHECK-LABEL: swiftself_tail:52; OPTAARCH64: b {{_?}}swiftself_param53; OPTAARCH64-NOT: ret54; OPTARM64_32: b {{_?}}swiftself_param55define ptr @swiftself_tail(ptr swiftself %addr0) {56  call void asm sideeffect "", "~{x20}"()57  %res = musttail call ptr @swiftself_param(ptr swiftself %addr0)58  ret ptr %res59}60 61; We can not use a tail call if the callee swiftself is not the same as the62; caller one.63; CHECK-LABEL: swiftself_notail:64; CHECK: mov x20, x065; CHECK: bl {{_?}}swiftself_param66; CHECK: ret67define ptr @swiftself_notail(ptr swiftself %addr0, ptr %addr1) nounwind {68  %res = tail call ptr @swiftself_param(ptr swiftself %addr1)69  ret ptr %res70}71 72; We cannot pretend that 'x0' is alive across the thisreturn_attribute call as73; we normally would. We marked the first parameter with swiftself which means it74; will no longer be passed in x0.75declare swiftcc ptr @thisreturn_attribute(ptr returned swiftself)76; OPTAARCH64-LABEL: swiftself_nothisreturn:77; OPTAARCH64-DAG: ldr  x20, [x20]78; OPTAARCH64-DAG: mov [[CSREG:x[1-9].*]], x879; OPTAARCH64: bl {{_?}}thisreturn_attribute80; OPTAARCH64: str x0, [[[CSREG]]81; OPTAARCH64: ret82 83; OPTARM64_32-LABEL: swiftself_nothisreturn:84; OPTARM64_32-DAG: ldr  w20, [x20]85; OPTARM64_32-DAG: mov [[CSREG:x[1-9].*]], x886; OPTARM64_32: bl {{_?}}thisreturn_attribute87; OPTARM64_32: str w0, [[[CSREG]]88; OPTARM64_32: ret89define hidden swiftcc void @swiftself_nothisreturn(ptr noalias nocapture sret(ptr), ptr noalias nocapture readonly swiftself) {90entry:91  %2 = load ptr, ptr %1, align 892  %3 = tail call swiftcc ptr @thisreturn_attribute(ptr swiftself %2)93  store ptr %3, ptr %0, align 894  ret void95}96