1; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s 2; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s --check-prefix=CHECK-O0 3; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s 4; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s --check-prefix=CHECK-O0 5 6; CHECK-LABEL: test1 7; CHECK: bl _gen 8; CHECK: sxth [[TMP:w.*]], w0 9; CHECK: add w0, [[TMP]], w1, sxtb 10; CHECK-O0-LABEL: test1 11; CHECK-O0: bl _gen 12; CHECK-O0: sxth [[TMP:w.*]], w0 13; CHECK-O0: add {{w[0-9]+}}, [[TMP]], w1, sxtb 14define i16 @test1(i32) { 15entry: 16 %call = call swiftcc { i16, i8 } @gen(i32 %0) 17 %v3 = extractvalue { i16, i8 } %call, 0 18 %v1 = sext i16 %v3 to i32 19 %v5 = extractvalue { i16, i8 } %call, 1 20 %v2 = sext i8 %v5 to i32 21 %add = add nsw i32 %v1, %v2 22 %conv = trunc i32 %add to i16 23 ret i16 %conv 24} 25 26declare swiftcc { i16, i8 } @gen(i32) 27 28; CHECK-LABEL: test2 29; CHECK: bl _gen2 30; CHECK: add [[TMP:x.*]], x0, x1 31; CHECK: add [[TMP2:x.*]], x2, x3 32; CHECK: add [[TMP]], [[TMP]], [[TMP2]] 33; CHECK: add x0, [[TMP]], x4 34; CHECK-O0-LABEL: test2 35; CHECK-O0: bl _gen2 36; CHECK-O0: add [[TMP:x.*]], x0, x1 37; CHECK-O0: add [[TMP]], [[TMP]], x2 38; CHECK-O0: add [[TMP]], [[TMP]], x3 39; CHECK-O0: add x0, [[TMP]], x4 40 41define i64 @test2(i64 %key) { 42entry: 43 %key.addr = alloca i64, align 4 44 store i64 %key, ptr %key.addr, align 4 45 %0 = load i64, ptr %key.addr, align 4 46 %call = call swiftcc { i64, i64, i64, i64, i64 } @gen2(i64 %0) 47 48 %v3 = extractvalue { i64, i64, i64, i64, i64 } %call, 0 49 %v5 = extractvalue { i64, i64, i64, i64, i64 } %call, 1 50 %v6 = extractvalue { i64, i64, i64, i64, i64 } %call, 2 51 %v7 = extractvalue { i64, i64, i64, i64, i64 } %call, 3 52 %v8 = extractvalue { i64, i64, i64, i64, i64 } %call, 4 53 54 %add = add nsw i64 %v3, %v5 55 %add1 = add nsw i64 %add, %v6 56 %add2 = add nsw i64 %add1, %v7 57 %add3 = add nsw i64 %add2, %v8 58 ret i64 %add3 59} 60; CHECK-LABEL: gen2: 61; CHECK: mov x1, x0 62; CHECK: mov x2, x0 63; CHECK: mov x3, x0 64; CHECK: mov x4, x0 65; CHECK: ret 66define swiftcc { i64, i64, i64, i64, i64 } @gen2(i64 %key) { 67 %Y = insertvalue { i64, i64, i64, i64, i64 } undef, i64 %key, 0 68 %Z = insertvalue { i64, i64, i64, i64, i64 } %Y, i64 %key, 1 69 %Z2 = insertvalue { i64, i64, i64, i64, i64 } %Z, i64 %key, 2 70 %Z3 = insertvalue { i64, i64, i64, i64, i64 } %Z2, i64 %key, 3 71 %Z4 = insertvalue { i64, i64, i64, i64, i64 } %Z3, i64 %key, 4 72 ret { i64, i64, i64, i64, i64 } %Z4 73} 74 75; CHECK-LABEL: test3 76; CHECK: bl _gen3 77; CHECK: add [[TMP:w.*]], w0, w1 78; CHECK: add [[TMP2:w.*]], w2, w3 79; CHECK: add w0, [[TMP]], [[TMP2]] 80; CHECK-O0-LABEL: test3 81; CHECK-O0: bl _gen3 82; CHECK-O0: add [[TMP:w.*]], w0, w1 83; CHECK-O0: add [[TMP]], [[TMP]], w2 84; CHECK-O0: add w0, [[TMP]], w3 85define i32 @test3(i32) { 86entry: 87 %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0) 88 89 %v3 = extractvalue { i32, i32, i32, i32 } %call, 0 90 %v5 = extractvalue { i32, i32, i32, i32 } %call, 1 91 %v6 = extractvalue { i32, i32, i32, i32 } %call, 2 92 %v7 = extractvalue { i32, i32, i32, i32 } %call, 3 93 94 %add = add nsw i32 %v3, %v5 95 %add1 = add nsw i32 %add, %v6 96 %add2 = add nsw i32 %add1, %v7 97 ret i32 %add2 98} 99 100declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key) 101 102; CHECK-LABEL: test4 103; CHECK: bl _gen4 104; CHECK: fadd s0, s0, s1 105; CHECK: fadd s0, s0, s2 106; CHECK: fadd s0, s0, s3 107; CHECK-O0-LABEL: test4 108; CHECK-O0: bl _gen4 109; CHECK-O0: fadd s0, s0, s1 110; CHECK-O0: fadd s0, s0, s2 111; CHECK-O0: fadd s0, s0, s3 112define float @test4(float) { 113entry: 114 %call = call swiftcc { float, float, float, float } @gen4(float %0) 115 116 %v3 = extractvalue { float, float, float, float } %call, 0 117 %v5 = extractvalue { float, float, float, float } %call, 1 118 %v6 = extractvalue { float, float, float, float } %call, 2 119 %v7 = extractvalue { float, float, float, float } %call, 3 120 121 %add = fadd float %v3, %v5 122 %add1 = fadd float %add, %v6 123 %add2 = fadd float %add1, %v7 124 ret float %add2 125} 126 127declare swiftcc { float, float, float, float } @gen4(float %key) 128 129; CHECK-LABEL: test5 130; CHECK: bl _gen5 131; CHECK: fadd d0, d0, d1 132; CHECK: fadd d0, d0, d2 133; CHECK: fadd d0, d0, d3 134; CHECK-O0-LABEL: test5 135; CHECK-O0: bl _gen5 136; CHECK-O0: fadd d0, d0, d1 137; CHECK-O0: fadd d0, d0, d2 138; CHECK-O0: fadd d0, d0, d3 139define swiftcc double @test5(){ 140entry: 141 %call = call swiftcc { double, double, double, double } @gen5() 142 143 %v3 = extractvalue { double, double, double, double } %call, 0 144 %v5 = extractvalue { double, double, double, double } %call, 1 145 %v6 = extractvalue { double, double, double, double } %call, 2 146 %v7 = extractvalue { double, double, double, double } %call, 3 147 148 %add = fadd double %v3, %v5 149 %add1 = fadd double %add, %v6 150 %add2 = fadd double %add1, %v7 151 ret double %add2 152} 153 154declare swiftcc { double, double, double, double } @gen5() 155 156; CHECK-LABEL: test6 157; CHECK: bl _gen6 158; CHECK-DAG: fadd d0, d0, d1 159; CHECK-DAG: fadd d0, d0, d2 160; CHECK-DAG: fadd d0, d0, d3 161; CHECK-DAG: add [[TMP:w.*]], w0, w1 162; CHECK-DAG: add [[TMP2:w.*]], w2, w3 163; CHECK-DAG: add w0, [[TMP]], [[TMP2]] 164; CHECK-O0-LABEL: test6 165; CHECK-O0: bl _gen6 166; CHECK-O0-DAG: fadd d0, d0, d1 167; CHECK-O0-DAG: fadd d0, d0, d2 168; CHECK-O0-DAG: fadd d0, d0, d3 169; CHECK-O0-DAG: add [[TMP:w.*]], w0, w1 170; CHECK-O0-DAG: add [[TMP]], [[TMP]], w2 171; CHECK-O0-DAG: add w0, [[TMP]], w3 172define swiftcc { double, i32 } @test6() { 173entry: 174 %call = call swiftcc { double, double, double, double, i32, i32, i32, i32 } @gen6() 175 176 %v3 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 0 177 %v5 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 1 178 %v6 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 2 179 %v7 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 3 180 %v3.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 4 181 %v5.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 5 182 %v6.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 6 183 %v7.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 7 184 185 %add = fadd double %v3, %v5 186 %add1 = fadd double %add, %v6 187 %add2 = fadd double %add1, %v7 188 189 %add.i = add nsw i32 %v3.i, %v5.i 190 %add1.i = add nsw i32 %add.i, %v6.i 191 %add2.i = add nsw i32 %add1.i, %v7.i 192 193 %Y = insertvalue { double, i32 } undef, double %add2, 0 194 %Z = insertvalue { double, i32 } %Y, i32 %add2.i, 1 195 ret { double, i32} %Z 196} 197 198declare swiftcc { double, double, double, double, i32, i32, i32, i32 } @gen6() 199 200; CHECK-LABEL: _gen7 201; CHECK-DAG: mov w1, w0 202; CHECK-DAG: mov w2, w0 203; CHECK-DAG: mov w3, w0 204; CHECK: ret 205; CHECK-O0-LABEL: _gen7 206; CHECK-O0: mov w3, w0 207; CHECK-O0: mov w0, w3 208; CHECK-O0: mov w1, w3 209; CHECK-O0: mov w2, w3 210define swiftcc { i32, i32, i32, i32 } @gen7(i32 %key) { 211 %v0 = insertvalue { i32, i32, i32, i32 } undef, i32 %key, 0 212 %v1 = insertvalue { i32, i32, i32, i32 } %v0, i32 %key, 1 213 %v2 = insertvalue { i32, i32, i32, i32 } %v1, i32 %key, 2 214 %v3 = insertvalue { i32, i32, i32, i32 } %v2, i32 %key, 3 215 ret { i32, i32, i32, i32 } %v3 216} 217 218; CHECK-LABEL: _gen9 219; CHECK: mov w1, w0 220; CHECK: mov w2, w0 221; CHECK: mov w3, w0 222; CHECK: ret 223; CHECK-O0-LABEL: _gen9 224; CHECK-O0: mov w3, w0 225; CHECK-O0: mov w0, w3 226; CHECK-O0: mov w1, w3 227; CHECK-O0: mov w2, w3 228define swiftcc { i8, i8, i8, i8 } @gen9(i8 %key) { 229 %v0 = insertvalue { i8, i8, i8, i8 } undef, i8 %key, 0 230 %v1 = insertvalue { i8, i8, i8, i8 } %v0, i8 %key, 1 231 %v2 = insertvalue { i8, i8, i8, i8 } %v1, i8 %key, 2 232 %v3 = insertvalue { i8, i8, i8, i8 } %v2, i8 %key, 3 233 ret { i8, i8, i8, i8 } %v3 234} 235 236; CHECK-LABEL: _gen10 237; CHECK: fmov d1, d0 238; CHECK: fmov d2, d0 239; CHECK: mov w1, w0 240; CHECK: fmov d3, d0 241; CHECK: mov w2, w0 242; CHECK: mov w3, w0 243; CHECK: ret 244define swiftcc { double, double, double, double, i32, i32, i32, i32 } @gen10(double %keyd, i32 %keyi) { 245 %v0 = insertvalue { double, double, double, double, i32, i32, i32, i32 } undef, double %keyd, 0 246 %v1 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v0, double %keyd, 1 247 %v2 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v1, double %keyd, 2 248 %v3 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v2, double %keyd, 3 249 %v4 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v3, i32 %keyi, 4 250 %v5 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v4, i32 %keyi, 5 251 %v6 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v5, i32 %keyi, 6 252 %v7 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v6, i32 %keyi, 7 253 ret { double, double, double, double, i32, i32, i32, i32 } %v7 254} 255 256; CHECK-LABEL: _test11 257; CHECK: bl _gen11 258; CHECK: fadd.4s v0, v0, v1 259; CHECK: fadd.4s v0, v0, v2 260; CHECK: fadd.4s v0, v0, v3 261define swiftcc <4 x float> @test11() { 262entry: 263 %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11() 264 265 %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 0 266 %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 1 267 %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 2 268 %v7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 3 269 270 %add = fadd <4 x float> %v3, %v5 271 %add1 = fadd <4 x float> %add, %v6 272 %add2 = fadd <4 x float> %add1, %v7 273 ret <4 x float> %add2 274} 275 276declare swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11() 277 278; CHECK-LABEL: _test12 279; CHECK: fadd.4s v0, v0, v1 280; CHECK: fmov s1, s3 281; CHECK: fadd.4s v0, v0, v2 282define swiftcc { <4 x float>, float } @test12() #0 { 283entry: 284 %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12() 285 286 %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 0 287 %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 1 288 %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 2 289 %v8 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 3 290 291 %add = fadd <4 x float> %v3, %v5 292 %add1 = fadd <4 x float> %add, %v6 293 %res.0 = insertvalue { <4 x float>, float } undef, <4 x float> %add1, 0 294 %res = insertvalue { <4 x float>, float } %res.0, float %v8, 1 295 ret { <4 x float>, float } %res 296} 297 298declare swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12() 299