1; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s | FileCheck %s 2; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s 3 4; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s | FileCheck %s 5; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s 6 7; Test how llvm handles return type of {i16, i8}. The return value will be 8; passed in %r0 and %r1. 9; CHECK-LABEL: test: 10; CHECK: bl {{.*}}gen 11; CHECK: sxth {{.*}}, r0 12; CHECK: sxtab r0, {{.*}}, r1 13; CHECK-O0-LABEL: test: 14; CHECK-O0: bl {{.*}}gen 15; CHECK-O0: sxth r0, r0 16; CHECK-O0: sxtb r1, r1 17; CHECK-O0: add r0, r0, r1 18define i16 @test(i32 %key) { 19entry: 20 %key.addr = alloca i32, align 4 21 store i32 %key, i32* %key.addr, align 4 22 %0 = load i32, i32* %key.addr, align 4 23 %call = call swiftcc { i16, i8 } @gen(i32 %0) 24 %v3 = extractvalue { i16, i8 } %call, 0 25 %v1 = sext i16 %v3 to i32 26 %v5 = extractvalue { i16, i8 } %call, 1 27 %v2 = sext i8 %v5 to i32 28 %add = add nsw i32 %v1, %v2 29 %conv = trunc i32 %add to i16 30 ret i16 %conv 31} 32 33declare swiftcc { i16, i8 } @gen(i32) 34 35; We can't pass every return value in register, instead, pass everything in 36; memroy. 37; The caller provides space for the return value and passes the address in %r0. 38; The first input argument will be in %r1. 39; CHECK-LABEL: test2: 40; CHECK: mov r1, r0 41; CHECK: mov r0, sp 42; CHECK: bl {{.*}}gen2 43; CHECK-DAG: add 44; CHECK-DAG: ldr {{.*}}, [sp, #16] 45; CHECK-DAG: add 46; CHECK-DAG: add 47; CHECK-DAG: add 48; CHECK-O0-LABEL: test2: 49; CHECK-O0: str r0 50; CHECK-O0: mov r0, sp 51; CHECK-O0: bl {{.*}}gen2 52; CHECK-O0-DAG: ldr {{.*}}, [sp] 53; CHECK-O0-DAG: ldr {{.*}}, [sp, #4] 54; CHECK-O0-DAG: ldr {{.*}}, [sp, #8] 55; CHECK-O0-DAG: ldr {{.*}}, [sp, #12] 56; CHECK-O0-DAG: ldr {{.*}}, [sp, #16] 57; CHECK-O0-DAG: add 58; CHECK-O0-DAG: add 59; CHECK-O0-DAG: add 60; CHECK-O0-DAG: add 61define i32 @test2(i32 %key) #0 { 62entry: 63 %key.addr = alloca i32, align 4 64 store i32 %key, i32* %key.addr, align 4 65 %0 = load i32, i32* %key.addr, align 4 66 %call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0) 67 68 %v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0 69 %v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1 70 %v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2 71 %v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3 72 %v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4 73 74 %add = add nsw i32 %v3, %v5 75 %add1 = add nsw i32 %add, %v6 76 %add2 = add nsw i32 %add1, %v7 77 %add3 = add nsw i32 %add2, %v8 78 ret i32 %add3 79} 80 81; The address of the return value is passed in %r0. 82; CHECK-LABEL: gen2: 83; CHECK-DAG: str r1, [r0] 84; CHECK-DAG: str r1, [r0, #4] 85; CHECK-DAG: str r1, [r0, #8] 86; CHECK-DAG: str r1, [r0, #12] 87; CHECK-DAG: str r1, [r0, #16] 88; CHECK-O0-LABEL: gen2: 89; CHECK-O0-DAG: str r1, [r0] 90; CHECK-O0-DAG: str r1, [r0, #4] 91; CHECK-O0-DAG: str r1, [r0, #8] 92; CHECK-O0-DAG: str r1, [r0, #12] 93; CHECK-O0-DAG: str r1, [r0, #16] 94define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) { 95 %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0 96 %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1 97 %Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2 98 %Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3 99 %Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4 100 ret { i32, i32, i32, i32, i32 } %Z4 101} 102 103; The return value {i32, i32, i32, i32} will be returned via registers %r0, %r1, 104; %r2, %r3. 105; CHECK-LABEL: test3: 106; CHECK: bl {{.*}}gen3 107; CHECK: add r0, r0, r1 108; CHECK: add r0, r0, r2 109; CHECK: add r0, r0, r3 110; CHECK-O0-LABEL: test3: 111; CHECK-O0: bl {{.*}}gen3 112; CHECK-O0: add r0, r0, r1 113; CHECK-O0: add r0, r0, r2 114; CHECK-O0: add r0, r0, r3 115define i32 @test3(i32 %key) #0 { 116entry: 117 %key.addr = alloca i32, align 4 118 store i32 %key, i32* %key.addr, align 4 119 %0 = load i32, i32* %key.addr, align 4 120 %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0) 121 122 %v3 = extractvalue { i32, i32, i32, i32 } %call, 0 123 %v5 = extractvalue { i32, i32, i32, i32 } %call, 1 124 %v6 = extractvalue { i32, i32, i32, i32 } %call, 2 125 %v7 = extractvalue { i32, i32, i32, i32 } %call, 3 126 127 %add = add nsw i32 %v3, %v5 128 %add1 = add nsw i32 %add, %v6 129 %add2 = add nsw i32 %add1, %v7 130 ret i32 %add2 131} 132 133declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key) 134