1; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE --check-prefix=CHECK-ARMV7 %s 2; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s 3 4declare i8* @malloc(i64) 5declare void @free(i8*) 6%swift_error = type { i64, i8 } 7%struct.S = type { i32, i32, i32, i32, i32, i32 } 8 9; This tests the basic usage of a swifterror parameter. "foo" is the function 10; that takes a swifterror parameter and "caller" is the caller of "foo". 11define float @foo(%swift_error** swifterror %error_ptr_ref) { 12; CHECK-APPLE-LABEL: foo: 13; CHECK-APPLE: mov r0, #16 14; CHECK-APPLE: malloc 15; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], #1 16; CHECK-APPLE-DAG: mov r6, r{{.*}} 17; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8] 18 19; CHECK-O0-LABEL: foo: 20; CHECK-O0: mov r{{.*}}, #16 21; CHECK-O0: malloc 22; CHECK-O0: mov [[ID2:r[0-9]+]], r0 23; CHECK-O0: mov [[ID:r[0-9]+]], #1 24; CHECK-O0: strb [[ID]], [r0, #8] 25; CHECK-O0: mov r6, [[ID2]] 26entry: 27 %call = call i8* @malloc(i64 16) 28 %call.0 = bitcast i8* %call to %swift_error* 29 store %swift_error* %call.0, %swift_error** %error_ptr_ref 30 %tmp = getelementptr inbounds i8, i8* %call, i64 8 31 store i8 1, i8* %tmp 32 ret float 1.0 33} 34 35; "caller" calls "foo" that takes a swifterror parameter. 36define float @caller(i8* %error_ref) { 37; CHECK-APPLE-LABEL: caller: 38; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0 39; CHECK-APPLE-DAG: mov r6, #0 40; CHECK-APPLE: bl {{.*}}foo 41; CHECK-APPLE: cmp r6, #0 42; Access part of the error object and save it to error_ref 43; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8] 44; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]] 45; CHECK-APPLE: mov r0, r6 46; CHECK-APPLE: bl {{.*}}free 47 48; CHECK-O0-LABEL: caller: 49; spill r0 50; CHECK-O0-DAG: mov r6, #0 51; CHECK-O0-DAG: str r0, [sp, [[SLOT:#[0-9]+]] 52; CHECK-O0: bl {{.*}}foo 53; CHECK-O0: mov [[TMP:r[0-9]+]], r6 54; CHECK-O0: str [[TMP]], [sp] 55; CHECK-O0: bne 56; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8] 57; CHECK-O0: ldr [[ID:r[0-9]+]], [sp, [[SLOT]]] 58; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]] 59; reload r0 60; CHECK-O0: ldr r0, [sp] 61; CHECK-O0: free 62entry: 63 %error_ptr_ref = alloca swifterror %swift_error* 64 store %swift_error* null, %swift_error** %error_ptr_ref 65 %call = call float @foo(%swift_error** swifterror %error_ptr_ref) 66 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 67 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 68 %tmp = bitcast %swift_error* %error_from_foo to i8* 69 br i1 %had_error_from_foo, label %handler, label %cont 70cont: 71 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 72 %t = load i8, i8* %v1 73 store i8 %t, i8* %error_ref 74 br label %handler 75handler: 76 call void @free(i8* %tmp) 77 ret float 1.0 78} 79 80; "caller2" is the caller of "foo", it calls "foo" inside a loop. 81define float @caller2(i8* %error_ref) { 82; CHECK-APPLE-LABEL: caller2: 83; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0 84; CHECK-APPLE-DAG: mov r6, #0 85; CHECK-APPLE: bl {{.*}}foo 86; CHECK-APPLE: cmp r6, #0 87; CHECK-APPLE: bne 88; Access part of the error object and save it to error_ref 89; CHECK-APPLE: ldrb [[CODE:r[0-9]+]], [r6, #8] 90; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]] 91; CHECK-APPLE: mov r0, r6 92; CHECK-APPLE: bl {{.*}}free 93 94; CHECK-O0-LABEL: caller2: 95; spill r0 96; CHECK-O0-DAG: str r0, 97; CHECK-O0-DAG: mov r6, #0 98; CHECK-O0: bl {{.*}}foo 99; CHECK-O0: mov r{{.*}}, r6 100; CHECK-O0: str r0, [sp] 101; CHECK-O0: bne 102; CHECK-O0: ble 103; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8] 104; reload r0 105; CHECK-O0: ldr [[ID:r[0-9]+]], 106; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]] 107; CHECK-O0: ldr r0, [sp] 108; CHECK-O0: free 109entry: 110 %error_ptr_ref = alloca swifterror %swift_error* 111 br label %bb_loop 112bb_loop: 113 store %swift_error* null, %swift_error** %error_ptr_ref 114 %call = call float @foo(%swift_error** swifterror %error_ptr_ref) 115 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 116 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 117 %tmp = bitcast %swift_error* %error_from_foo to i8* 118 br i1 %had_error_from_foo, label %handler, label %cont 119cont: 120 %cmp = fcmp ogt float %call, 1.000000e+00 121 br i1 %cmp, label %bb_end, label %bb_loop 122bb_end: 123 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 124 %t = load i8, i8* %v1 125 store i8 %t, i8* %error_ref 126 br label %handler 127handler: 128 call void @free(i8* %tmp) 129 ret float 1.0 130} 131 132; "foo_if" is a function that takes a swifterror parameter, it sets swifterror 133; under a certain condition. 134define float @foo_if(%swift_error** swifterror %error_ptr_ref, i32 %cc) { 135; CHECK-APPLE-LABEL: foo_if: 136; CHECK-APPLE: cmp r0, #0 137; CHECK-APPLE: eq 138; CHECK-APPLE: mov r0, #16 139; CHECK-APPLE: malloc 140; CHECK-APPLE: mov [[ID:r[0-9]+]], #1 141; CHECK-APPLE-DAG: mov r6, r{{.*}} 142; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8] 143 144; CHECK-O0-LABEL: foo_if: 145; CHECK-O0: cmp r0, #0 146; spill to stack 147; CHECK-O0: str r6 148; CHECK-O0: beq 149; CHECK-O0: mov r0, #16 150; CHECK-O0: malloc 151; CHECK-O0: mov [[ID:r[0-9]+]], r0 152; CHECK-O0: mov [[ID2:[a-z0-9]+]], #1 153; CHECK-O0: strb [[ID2]], [r0, #8] 154; CHECK-O0: mov r6, [[ID]] 155; reload from stack 156; CHECK-O0: ldr r6 157entry: 158 %cond = icmp ne i32 %cc, 0 159 br i1 %cond, label %gen_error, label %normal 160 161gen_error: 162 %call = call i8* @malloc(i64 16) 163 %call.0 = bitcast i8* %call to %swift_error* 164 store %swift_error* %call.0, %swift_error** %error_ptr_ref 165 %tmp = getelementptr inbounds i8, i8* %call, i64 8 166 store i8 1, i8* %tmp 167 ret float 1.0 168 169normal: 170 ret float 0.0 171} 172 173; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror 174; under a certain condition inside a loop. 175define float @foo_loop(%swift_error** swifterror %error_ptr_ref, i32 %cc, float %cc2) { 176; CHECK-APPLE-LABEL: foo_loop: 177; CHECK-APPLE: mov [[CODE:r[0-9]+]], r0 178; swifterror is kept in a register 179; CHECK-APPLE: mov [[ID:r[0-9]+]], r6 180; CHECK-APPLE: cmp [[CODE]], #0 181; CHECK-APPLE: beq 182; CHECK-APPLE: mov r0, #16 183; CHECK-APPLE: malloc 184; CHECK-APPLE: strb r{{.*}}, [{{.*}}[[ID]], #8] 185; CHECK-APPLE: ble 186; CHECK-APPLE: mov r6, [[ID]] 187 188; CHECK-O0-LABEL: foo_loop: 189; CHECK-O0: mov r{{.*}}, r6 190; CHECK-O0: cmp r{{.*}}, #0 191; CHECK-O0: beq 192; CHECK-O0-DAG: movw r{{.*}}, #1 193; CHECK-O0-DAG: mov r{{.*}}, #16 194; CHECK-O0: malloc 195; CHECK-O0-DAG: mov [[ID:r[0-9]+]], r0 196; CHECK-O0-DAG: ldr [[ID2:r[0-9]+]], [sp{{.*}}] 197; CHECK-O0: strb [[ID2]], [{{.*}}[[ID]], #8] 198; spill r0 199; CHECK-O0: str r0, [sp{{.*}}] 200; CHECK-O0: vcmpe 201; CHECK-O0: ble 202; reload from stack 203; CHECK-O0: ldr r6 204entry: 205 br label %bb_loop 206 207bb_loop: 208 %cond = icmp ne i32 %cc, 0 209 br i1 %cond, label %gen_error, label %bb_cont 210 211gen_error: 212 %call = call i8* @malloc(i64 16) 213 %call.0 = bitcast i8* %call to %swift_error* 214 store %swift_error* %call.0, %swift_error** %error_ptr_ref 215 %tmp = getelementptr inbounds i8, i8* %call, i64 8 216 store i8 1, i8* %tmp 217 br label %bb_cont 218 219bb_cont: 220 %cmp = fcmp ogt float %cc2, 1.000000e+00 221 br i1 %cmp, label %bb_end, label %bb_loop 222bb_end: 223 ret float 0.0 224} 225 226; "foo_sret" is a function that takes a swifterror parameter, it also has a sret 227; parameter. 228define void @foo_sret(%struct.S* sret %agg.result, i32 %val1, %swift_error** swifterror %error_ptr_ref) { 229; CHECK-APPLE-LABEL: foo_sret: 230; CHECK-APPLE: mov [[SRET:r[0-9]+]], r0 231; CHECK-APPLE: mov r0, #16 232; CHECK-APPLE: malloc 233; CHECK-APPLE: mov [[REG:r[0-9]+]], #1 234; CHECK-APPLE-DAG: mov r6, r0 235; CHECK-APPLE-DAG: strb [[REG]], [r0, #8] 236; CHECK-APPLE-DAG: str r{{.*}}, [{{.*}}[[SRET]], #4] 237 238; CHECK-O0-LABEL: foo_sret: 239; CHECK-O0: mov r{{.*}}, #16 240; spill to stack: sret and val1 241; CHECK-O0-DAG: str r0 242; CHECK-O0-DAG: str r1 243; CHECK-O0: malloc 244; CHECK-O0: mov [[ID:r[0-9]+]], #1 245; CHECK-O0: strb [[ID]], [r0, #8] 246; reload from stack: sret and val1 247; CHECK-O0: ldr 248; CHECK-O0: ldr 249; CHECK-O0: str r{{.*}}, [{{.*}}, #4] 250; CHECK-O0: mov r6 251entry: 252 %call = call i8* @malloc(i64 16) 253 %call.0 = bitcast i8* %call to %swift_error* 254 store %swift_error* %call.0, %swift_error** %error_ptr_ref 255 %tmp = getelementptr inbounds i8, i8* %call, i64 8 256 store i8 1, i8* %tmp 257 %v2 = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1 258 store i32 %val1, i32* %v2 259 ret void 260} 261 262; "caller3" calls "foo_sret" that takes a swifterror parameter. 263define float @caller3(i8* %error_ref) { 264; CHECK-APPLE-LABEL: caller3: 265; CHECK-APPLE: mov [[ID:r[0-9]+]], r0 266; CHECK-APPLE: mov r6, #0 267; CHECK-APPLE: bl {{.*}}foo_sret 268; CHECK-APPLE: cmp r6, #0 269; Access part of the error object and save it to error_ref 270; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8] 271; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]] 272; CHECK-APPLE: mov r0, r6 273; CHECK-APPLE: bl {{.*}}free 274 275; CHECK-O0-LABEL: caller3: 276; CHECK-O0-DAG: mov r6, #0 277; CHECK-O0-DAG: mov r0 278; CHECK-O0-DAG: mov r1 279; CHECK-O0: bl {{.*}}foo_sret 280; CHECK-O0: mov [[ID2:r[0-9]+]], r6 281; CHECK-O0: cmp r6 282; CHECK-O0: str [[ID2]], [sp[[SLOT:.*]]] 283; CHECK-O0: bne 284; Access part of the error object and save it to error_ref 285; CHECK-O0: ldrb [[CODE:r[0-9]+]] 286; CHECK-O0: ldr [[ID:r[0-9]+]] 287; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]] 288; CHECK-O0: ldr r0, [sp[[SLOT]] 289; CHECK-O0: bl {{.*}}free 290entry: 291 %s = alloca %struct.S, align 8 292 %error_ptr_ref = alloca swifterror %swift_error* 293 store %swift_error* null, %swift_error** %error_ptr_ref 294 call void @foo_sret(%struct.S* sret %s, i32 1, %swift_error** swifterror %error_ptr_ref) 295 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 296 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 297 %tmp = bitcast %swift_error* %error_from_foo to i8* 298 br i1 %had_error_from_foo, label %handler, label %cont 299cont: 300 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 301 %t = load i8, i8* %v1 302 store i8 %t, i8* %error_ref 303 br label %handler 304handler: 305 call void @free(i8* %tmp) 306 ret float 1.0 307} 308 309; "foo_vararg" is a function that takes a swifterror parameter, it also has 310; variable number of arguments. 311declare void @llvm.va_start(i8*) nounwind 312define float @foo_vararg(%swift_error** swifterror %error_ptr_ref, ...) { 313; CHECK-APPLE-LABEL: foo_vararg: 314; CHECK-APPLE: mov r0, #16 315; CHECK-APPLE: malloc 316; CHECK-APPLE: mov [[REG:r[0-9]+]], r0 317; CHECK-APPLE: mov [[ID:r[0-9]+]], #1 318; CHECK-APPLE-DAG: strb [[ID]], [{{.*}}[[REG]], #8] 319; CHECK-APPLE-DAG: mov r6, [[REG]] 320 321entry: 322 %call = call i8* @malloc(i64 16) 323 %call.0 = bitcast i8* %call to %swift_error* 324 store %swift_error* %call.0, %swift_error** %error_ptr_ref 325 %tmp = getelementptr inbounds i8, i8* %call, i64 8 326 store i8 1, i8* %tmp 327 328 %args = alloca i8*, align 8 329 %a10 = alloca i32, align 4 330 %a11 = alloca i32, align 4 331 %a12 = alloca i32, align 4 332 %v10 = bitcast i8** %args to i8* 333 call void @llvm.va_start(i8* %v10) 334 %v11 = va_arg i8** %args, i32 335 store i32 %v11, i32* %a10, align 4 336 %v12 = va_arg i8** %args, i32 337 store i32 %v12, i32* %a11, align 4 338 %v13 = va_arg i8** %args, i32 339 store i32 %v13, i32* %a12, align 4 340 341 ret float 1.0 342} 343 344; "caller4" calls "foo_vararg" that takes a swifterror parameter. 345define float @caller4(i8* %error_ref) { 346; CHECK-APPLE-LABEL: caller4: 347; CHECK-APPLE: mov [[ID:r[0-9]+]], r0 348; CHECK-APPLE: mov r6, #0 349; CHECK-APPLE: bl {{.*}}foo_vararg 350; CHECK-APPLE: cmp r6, #0 351; Access part of the error object and save it to error_ref 352; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8] 353; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]] 354; CHECK-APPLE: mov r0, r6 355; CHECK-APPLE: bl {{.*}}free 356entry: 357 %error_ptr_ref = alloca swifterror %swift_error* 358 store %swift_error* null, %swift_error** %error_ptr_ref 359 360 %a10 = alloca i32, align 4 361 %a11 = alloca i32, align 4 362 %a12 = alloca i32, align 4 363 store i32 10, i32* %a10, align 4 364 store i32 11, i32* %a11, align 4 365 store i32 12, i32* %a12, align 4 366 %v10 = load i32, i32* %a10, align 4 367 %v11 = load i32, i32* %a11, align 4 368 %v12 = load i32, i32* %a12, align 4 369 370 %call = call float (%swift_error**, ...) @foo_vararg(%swift_error** swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12) 371 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 372 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 373 %tmp = bitcast %swift_error* %error_from_foo to i8* 374 br i1 %had_error_from_foo, label %handler, label %cont 375 376cont: 377 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 378 %t = load i8, i8* %v1 379 store i8 %t, i8* %error_ref 380 br label %handler 381handler: 382 call void @free(i8* %tmp) 383 ret float 1.0 384} 385 386; Check that we don't blow up on tail calling swifterror argument functions. 387define float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref) { 388entry: 389 %0 = tail call float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref) 390 ret float %0 391} 392define swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref) { 393entry: 394 %0 = tail call swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref) 395 ret float %0 396} 397 398; CHECK-APPLE-LABEL: swifterror_clobber 399; CHECK-APPLE: mov [[REG:r[0-9]+]], r6 400; CHECK-APPLE: nop 401; CHECK-APPLE: mov r6, [[REG]] 402define swiftcc void @swifterror_clobber(%swift_error** nocapture swifterror %err) { 403 call void asm sideeffect "nop", "~{r6}"() 404 ret void 405} 406 407; CHECK-APPLE-LABEL: swifterror_reg_clobber 408; CHECK-APPLE: push {{.*}}r6 409; CHECK-APPLE: nop 410; CHECK-APPLE: pop {{.*}}r6 411define swiftcc void @swifterror_reg_clobber(%swift_error** nocapture %err) { 412 call void asm sideeffect "nop", "~{r6}"() 413 ret void 414} 415 416; CHECK-ARMV7-LABEL: _params_in_reg 417; Store callee saved registers excluding swifterror. 418; CHECK-ARMV7: push {r4, r5, r7, r8, r10, r11, lr} 419; Store swiftself (r10) and swifterror (r6). 420; CHECK-ARMV7-DAG: str r6, [s[[STK1:.*]]] 421; CHECK-ARMV7-DAG: str r10, [s[[STK2:.*]]] 422; Store arguments. 423; CHECK-ARMV7: mov r4, r3 424; CHECK-ARMV7: mov r5, r2 425; CHECK-ARMV7: mov r8, r1 426; CHECK-ARMV7: mov r11, r0 427; Setup call. 428; CHECK-ARMV7: mov r0, #1 429; CHECK-ARMV7: mov r1, #2 430; CHECK-ARMV7: mov r2, #3 431; CHECK-ARMV7: mov r3, #4 432; CHECK-ARMV7: mov r10, #0 433; CHECK-ARMV7: mov r6, #0 434; CHECK-ARMV7: bl _params_in_reg2 435; Restore original arguments. 436; CHECK-ARMV7-DAG: ldr r10, [s[[STK2]]] 437; CHECK-ARMV7-DAG: ldr r6, [s[[STK1]]] 438; CHECK-ARMV7: mov r0, r11 439; CHECK-ARMV7: mov r1, r8 440; CHECK-ARMV7: mov r2, r5 441; CHECK-ARMV7: mov r3, r4 442; CHECK-ARMV7: bl _params_in_reg2 443; CHECK-ARMV7: pop {r4, r5, r7, r8, r10, r11, pc} 444define swiftcc void @params_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) { 445 %error_ptr_ref = alloca swifterror %swift_error*, align 8 446 store %swift_error* null, %swift_error** %error_ptr_ref 447 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref) 448 call swiftcc void @params_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err) 449 ret void 450} 451declare swiftcc void @params_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) 452 453; CHECK-ARMV7-LABEL: params_and_return_in_reg 454; CHECK-ARMV7: push {r4, r5, r7, r8, r10, r11, lr} 455; Store swifterror and swiftself 456; CHECK-ARMV7: mov r4, r6 457; CHECK-ARMV7: str r10, [s[[STK1:.*]]] 458; Store arguments. 459; CHECK-ARMV7: str r3, [s[[STK2:.*]]] 460; CHECK-ARMV7: mov r5, r2 461; CHECK-ARMV7: mov r8, r1 462; CHECK-ARMV7: mov r11, r0 463; Setup call. 464; CHECK-ARMV7: mov r0, #1 465; CHECK-ARMV7: mov r1, #2 466; CHECK-ARMV7: mov r2, #3 467; CHECK-ARMV7: mov r3, #4 468; CHECK-ARMV7: mov r10, #0 469; CHECK-ARMV7: mov r6, #0 470; CHECK-ARMV7: bl _params_in_reg2 471; Restore original arguments. 472; CHECK-ARMV7: ldr r3, [s[[STK2]]] 473; CHECK-ARMV7: ldr r10, [s[[STK1]]] 474; Store %error_ptr_ref; 475; CHECK-ARMV7: str r6, [s[[STK3:.*]]] 476; Restore original arguments. 477; CHECK-ARMV7: mov r0, r11 478; CHECK-ARMV7: mov r1, r8 479; CHECK-ARMV7: mov r2, r5 480; CHECK-ARMV7: mov r6, r4 481; CHECK-ARMV7: bl _params_and_return_in_reg2 482; Store swifterror return %err; 483; CHECK-ARMV7: str r6, [s[[STK1]]] 484; Load swifterror value %error_ptr_ref. 485; CHECK-ARMV7: ldr r6, [s[[STK3]]] 486; Save return values. 487; CHECK-ARMV7: mov r5, r0 488; CHECK-ARMV7: mov r4, r1 489; CHECK-ARMV7: mov r8, r2 490; CHECK-ARMV7: mov r11, r3 491; Setup call. 492; CHECK-ARMV7: mov r0, #1 493; CHECK-ARMV7: mov r1, #2 494; CHECK-ARMV7: mov r2, #3 495; CHECK-ARMV7: mov r3, #4 496; CHECK-ARMV7: mov r10, #0 497; CHECK-ARMV7: bl _params_in_reg2 498; Load swifterror %err; 499; CHECK-ARMV7: ldr r6, [s[[STK1]]] 500; Restore return values for returning. 501; CHECK-ARMV7: mov r0, r5 502; CHECK-ARMV7: mov r1, r4 503; CHECK-ARMV7: mov r2, r8 504; CHECK-ARMV7: mov r3, r11 505; CHECK-ARMV7: pop {r4, r5, r7, r8, r10, r11, pc} 506define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) { 507 %error_ptr_ref = alloca swifterror %swift_error*, align 8 508 store %swift_error* null, %swift_error** %error_ptr_ref 509 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref) 510 %val = call swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err) 511 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref) 512 ret { i32, i32, i32, i32 }%val 513} 514 515declare swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) 516