1 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 2 3 ; Parameter with swiftself should be allocated to r10. 4 ; CHECK-LABEL: swiftself_param: 5 ; CHECK: lgr %r2, %r10 6 define i8 *@swiftself_param(i8* swiftself %addr0) { 7 ret i8 *%addr0 8 } 9 10 ; Check that r10 is used to pass a swiftself argument. 11 ; CHECK-LABEL: call_swiftself: 12 ; CHECK: lgr %r10, %r2 13 ; CHECK: brasl %r14, swiftself_param 14 define i8 *@call_swiftself(i8* %arg) { 15 %res = call i8 *@swiftself_param(i8* swiftself %arg) 16 ret i8 *%res 17 } 18 19 ; r10 should be saved by the callee even if used for swiftself 20 ; CHECK-LABEL: swiftself_clobber: 21 ; CHECK: stmg %r10, 22 ; ... 23 ; CHECK: lmg %r10, 24 ; CHECK: br %r14 25 define i8 *@swiftself_clobber(i8* swiftself %addr0) { 26 call void asm sideeffect "", "~{r10}"() 27 ret i8 *%addr0 28 } 29 30 ; Demonstrate that we do not need any loads when calling multiple functions 31 ; with swiftself argument. 32 ; CHECK-LABEL: swiftself_passthrough: 33 ; CHECK-NOT: lg{{.*}}r10, 34 ; CHECK: brasl %r14, swiftself_param 35 ; CHECK-NOT: lg{{.*}}r10, 36 ; CHECK-NEXT: brasl %r14, swiftself_param 37 define void @swiftself_passthrough(i8* swiftself %addr0) { 38 call i8 *@swiftself_param(i8* swiftself %addr0) 39 call i8 *@swiftself_param(i8* swiftself %addr0) 40 ret void 41 } 42 43 ; Normally, we can use a tail call if the callee swiftself is the same as the 44 ; caller one. Not yet supported on SystemZ. 45 ; CHECK-LABEL: swiftself_tail: 46 ; CHECK: lgr %r[[REG1:[0-9]+]], %r10 47 ; CHECK: lgr %r10, %r[[REG1]] 48 ; CHECK: brasl %r14, swiftself_param 49 ; CHECK: br %r14 50 define i8* @swiftself_tail(i8* swiftself %addr0) { 51 call void asm sideeffect "", "~{r10}"() 52 %res = tail call i8* @swiftself_param(i8* swiftself %addr0) 53 ret i8* %res 54 } 55 56 ; We can not use a tail call if the callee swiftself is not the same as the 57 ; caller one. 58 ; CHECK-LABEL: swiftself_notail: 59 ; CHECK: lgr %r10, %r2 60 ; CHECK: brasl %r14, swiftself_param 61 ; CHECK: lmg %r10, 62 ; CHECK: br %r14 63 define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind { 64 %res = tail call i8* @swiftself_param(i8* swiftself %addr1) 65 ret i8* %res 66 } 67