1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s 3; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s 4; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-linux-androideabi | FileCheck --check-prefix=CHECK-ANDROID %s 5 6declare i8* @malloc(i64) 7declare void @free(i8*) 8%swift_error = type { i64, i8 } 9%struct.S = type { i32, i32, i32, i32, i32, i32 } 10 11; This tests the basic usage of a swifterror parameter. "foo" is the function 12; that takes a swifterror parameter and "caller" is the caller of "foo". 13define float @foo(%swift_error** swifterror %error_ptr_ref) { 14; CHECK-APPLE-LABEL: foo: 15; CHECK-APPLE: @ %bb.0: @ %entry 16; CHECK-APPLE-NEXT: push {lr} 17; CHECK-APPLE-NEXT: mov r0, #16 18; CHECK-APPLE-NEXT: mov r1, #0 19; CHECK-APPLE-NEXT: bl _malloc 20; CHECK-APPLE-NEXT: mov r8, r0 21; CHECK-APPLE-NEXT: mov r0, #1 22; CHECK-APPLE-NEXT: strb r0, [r8, #8] 23; CHECK-APPLE-NEXT: mov r0, #1065353216 24; CHECK-APPLE-NEXT: pop {lr} 25; CHECK-APPLE-NEXT: bx lr 26; 27; CHECK-O0-LABEL: foo: 28; CHECK-O0: @ %bb.0: @ %entry 29; CHECK-O0-NEXT: push {r7, lr} 30; CHECK-O0-NEXT: mov r7, sp 31; CHECK-O0-NEXT: mov r0, #16 32; CHECK-O0-NEXT: mov r1, #0 33; CHECK-O0-NEXT: bl _malloc 34; CHECK-O0-NEXT: mov r1, r0 35; CHECK-O0-NEXT: mov r8, r1 36; CHECK-O0-NEXT: mov r0, #1 37; CHECK-O0-NEXT: strb r0, [r1, #8] 38; CHECK-O0-NEXT: mov r0, #1065353216 39; CHECK-O0-NEXT: pop {r7, pc} 40; 41; CHECK-ANDROID-LABEL: foo: 42; CHECK-ANDROID: @ %bb.0: @ %entry 43; CHECK-ANDROID-NEXT: .save {r11, lr} 44; CHECK-ANDROID-NEXT: push {r11, lr} 45; CHECK-ANDROID-NEXT: mov r0, #16 46; CHECK-ANDROID-NEXT: mov r1, #0 47; CHECK-ANDROID-NEXT: bl malloc 48; CHECK-ANDROID-NEXT: mov r8, r0 49; CHECK-ANDROID-NEXT: mov r0, #1 50; CHECK-ANDROID-NEXT: strb r0, [r8, #8] 51; CHECK-ANDROID-NEXT: mov r0, #1065353216 52; CHECK-ANDROID-NEXT: pop {r11, pc} 53 54entry: 55 %call = call i8* @malloc(i64 16) 56 %call.0 = bitcast i8* %call to %swift_error* 57 store %swift_error* %call.0, %swift_error** %error_ptr_ref 58 %tmp = getelementptr inbounds i8, i8* %call, i64 8 59 store i8 1, i8* %tmp 60 ret float 1.0 61} 62 63; "caller" calls "foo" that takes a swifterror parameter. 64define float @caller(i8* %error_ref) { 65; CHECK-APPLE-LABEL: caller: 66; CHECK-APPLE: @ %bb.0: @ %entry 67; CHECK-APPLE-NEXT: push {r4, r8, lr} 68; CHECK-APPLE-NEXT: sub sp, sp, #4 69; CHECK-APPLE-NEXT: mov r8, #0 70; CHECK-APPLE-NEXT: mov r4, r0 71; CHECK-APPLE-NEXT: bl _foo 72; CHECK-APPLE-NEXT: mov r0, r8 73; CHECK-APPLE-NEXT: cmp r8, #0 74; CHECK-APPLE-NEXT: ldrbeq r1, [r0, #8] 75; CHECK-APPLE-NEXT: strbeq r1, [r4] 76; CHECK-APPLE-NEXT: bl _free 77; CHECK-APPLE-NEXT: mov r0, #1065353216 78; CHECK-APPLE-NEXT: add sp, sp, #4 79; CHECK-APPLE-NEXT: pop {r4, r8, pc} 80; 81; CHECK-O0-LABEL: caller: 82; CHECK-O0: @ %bb.0: @ %entry 83; CHECK-O0-NEXT: push {r7, lr} 84; CHECK-O0-NEXT: mov r7, sp 85; CHECK-O0-NEXT: push {r8} 86; CHECK-O0-NEXT: sub sp, sp, #12 87; CHECK-O0-NEXT: @ implicit-def: $r1 88; CHECK-O0-NEXT: str r0, [sp] @ 4-byte Spill 89; CHECK-O0-NEXT: mov r8, #0 90; CHECK-O0-NEXT: bl _foo 91; CHECK-O0-NEXT: str r8, [sp, #4] @ 4-byte Spill 92; CHECK-O0-NEXT: movw r0, #0 93; CHECK-O0-NEXT: cmp r8, r0 94; CHECK-O0-NEXT: bne LBB1_2 95; CHECK-O0-NEXT: @ %bb.1: @ %cont 96; CHECK-O0-NEXT: ldr r1, [sp] @ 4-byte Reload 97; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 98; CHECK-O0-NEXT: ldrb r0, [r0, #8] 99; CHECK-O0-NEXT: strb r0, [r1] 100; CHECK-O0-NEXT: LBB1_2: @ %handler 101; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 102; CHECK-O0-NEXT: bl _free 103; CHECK-O0-NEXT: mov r0, #1065353216 104; CHECK-O0-NEXT: sub sp, r7, #4 105; CHECK-O0-NEXT: pop {r8} 106; CHECK-O0-NEXT: pop {r7, pc} 107; 108; CHECK-ANDROID-LABEL: caller: 109; CHECK-ANDROID: @ %bb.0: @ %entry 110; CHECK-ANDROID-NEXT: .save {r4, r8, r11, lr} 111; CHECK-ANDROID-NEXT: push {r4, r8, r11, lr} 112; CHECK-ANDROID-NEXT: .pad #8 113; CHECK-ANDROID-NEXT: sub sp, sp, #8 114; CHECK-ANDROID-NEXT: mov r8, #0 115; CHECK-ANDROID-NEXT: mov r4, r0 116; CHECK-ANDROID-NEXT: bl foo 117; CHECK-ANDROID-NEXT: mov r0, r8 118; CHECK-ANDROID-NEXT: cmp r8, #0 119; CHECK-ANDROID-NEXT: ldrbeq r1, [r0, #8] 120; CHECK-ANDROID-NEXT: strbeq r1, [r4] 121; CHECK-ANDROID-NEXT: bl free 122; CHECK-ANDROID-NEXT: mov r0, #1065353216 123; CHECK-ANDROID-NEXT: add sp, sp, #8 124; CHECK-ANDROID-NEXT: pop {r4, r8, r11, pc} 125; Access part of the error object and save it to error_ref 126 127; spill r0 128; reload r0 129entry: 130 %error_ptr_ref = alloca swifterror %swift_error* 131 store %swift_error* null, %swift_error** %error_ptr_ref 132 %call = call float @foo(%swift_error** swifterror %error_ptr_ref) 133 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 134 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 135 %tmp = bitcast %swift_error* %error_from_foo to i8* 136 br i1 %had_error_from_foo, label %handler, label %cont 137cont: 138 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 139 %t = load i8, i8* %v1 140 store i8 %t, i8* %error_ref 141 br label %handler 142handler: 143 call void @free(i8* %tmp) 144 ret float 1.0 145} 146 147; "caller2" is the caller of "foo", it calls "foo" inside a loop. 148define float @caller2(i8* %error_ref) { 149; CHECK-APPLE-LABEL: caller2: 150; CHECK-APPLE: @ %bb.0: @ %entry 151; CHECK-APPLE-NEXT: push {r4, r8, lr} 152; CHECK-APPLE-NEXT: vpush {d8} 153; CHECK-APPLE-NEXT: sub sp, sp, #4 154; CHECK-APPLE-NEXT: vmov.f32 s16, #1.000000e+00 155; CHECK-APPLE-NEXT: mov r4, r0 156; CHECK-APPLE-NEXT: LBB2_1: @ %bb_loop 157; CHECK-APPLE-NEXT: @ =>This Inner Loop Header: Depth=1 158; CHECK-APPLE-NEXT: mov r8, #0 159; CHECK-APPLE-NEXT: bl _foo 160; CHECK-APPLE-NEXT: cmp r8, #0 161; CHECK-APPLE-NEXT: bne LBB2_4 162; CHECK-APPLE-NEXT: @ %bb.2: @ %cont 163; CHECK-APPLE-NEXT: @ in Loop: Header=BB2_1 Depth=1 164; CHECK-APPLE-NEXT: vmov s0, r0 165; CHECK-APPLE-NEXT: vcmp.f32 s0, s16 166; CHECK-APPLE-NEXT: vmrs APSR_nzcv, fpscr 167; CHECK-APPLE-NEXT: ble LBB2_1 168; CHECK-APPLE-NEXT: @ %bb.3: @ %bb_end 169; CHECK-APPLE-NEXT: ldrb r0, [r8, #8] 170; CHECK-APPLE-NEXT: strb r0, [r4] 171; CHECK-APPLE-NEXT: LBB2_4: @ %handler 172; CHECK-APPLE-NEXT: mov r0, r8 173; CHECK-APPLE-NEXT: bl _free 174; CHECK-APPLE-NEXT: mov r0, #1065353216 175; CHECK-APPLE-NEXT: add sp, sp, #4 176; CHECK-APPLE-NEXT: vpop {d8} 177; CHECK-APPLE-NEXT: pop {r4, r8, pc} 178; 179; CHECK-O0-LABEL: caller2: 180; CHECK-O0: @ %bb.0: @ %entry 181; CHECK-O0-NEXT: push {r7, lr} 182; CHECK-O0-NEXT: mov r7, sp 183; CHECK-O0-NEXT: push {r8} 184; CHECK-O0-NEXT: sub sp, sp, #16 185; CHECK-O0-NEXT: @ implicit-def: $r1 186; CHECK-O0-NEXT: str r0, [sp, #8] @ 4-byte Spill 187; CHECK-O0-NEXT: LBB2_1: @ %bb_loop 188; CHECK-O0-NEXT: @ =>This Inner Loop Header: Depth=1 189; CHECK-O0-NEXT: mov r8, #0 190; CHECK-O0-NEXT: bl _foo 191; CHECK-O0-NEXT: vmov s0, r0 192; CHECK-O0-NEXT: vstr s0, [sp] @ 4-byte Spill 193; CHECK-O0-NEXT: str r8, [sp, #4] @ 4-byte Spill 194; CHECK-O0-NEXT: movw r0, #0 195; CHECK-O0-NEXT: cmp r8, r0 196; CHECK-O0-NEXT: bne LBB2_4 197; CHECK-O0-NEXT: @ %bb.2: @ %cont 198; CHECK-O0-NEXT: @ in Loop: Header=BB2_1 Depth=1 199; CHECK-O0-NEXT: vldr s0, [sp] @ 4-byte Reload 200; CHECK-O0-NEXT: vmov.f32 s2, #1.000000e+00 201; CHECK-O0-NEXT: vcmp.f32 s0, s2 202; CHECK-O0-NEXT: vmrs APSR_nzcv, fpscr 203; CHECK-O0-NEXT: ble LBB2_1 204; CHECK-O0-NEXT: @ %bb.3: @ %bb_end 205; CHECK-O0-NEXT: ldr r1, [sp, #8] @ 4-byte Reload 206; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 207; CHECK-O0-NEXT: ldrb r0, [r0, #8] 208; CHECK-O0-NEXT: strb r0, [r1] 209; CHECK-O0-NEXT: LBB2_4: @ %handler 210; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 211; CHECK-O0-NEXT: bl _free 212; CHECK-O0-NEXT: mov r0, #1065353216 213; CHECK-O0-NEXT: sub sp, r7, #4 214; CHECK-O0-NEXT: pop {r8} 215; CHECK-O0-NEXT: pop {r7, pc} 216; 217; CHECK-ANDROID-LABEL: caller2: 218; CHECK-ANDROID: @ %bb.0: @ %entry 219; CHECK-ANDROID-NEXT: .save {r4, r8, r11, lr} 220; CHECK-ANDROID-NEXT: push {r4, r8, r11, lr} 221; CHECK-ANDROID-NEXT: .vsave {d8} 222; CHECK-ANDROID-NEXT: vpush {d8} 223; CHECK-ANDROID-NEXT: .pad #8 224; CHECK-ANDROID-NEXT: sub sp, sp, #8 225; CHECK-ANDROID-NEXT: vmov.f32 s16, #1.000000e+00 226; CHECK-ANDROID-NEXT: mov r4, r0 227; CHECK-ANDROID-NEXT: .LBB2_1: @ %bb_loop 228; CHECK-ANDROID-NEXT: @ =>This Inner Loop Header: Depth=1 229; CHECK-ANDROID-NEXT: mov r8, #0 230; CHECK-ANDROID-NEXT: bl foo 231; CHECK-ANDROID-NEXT: cmp r8, #0 232; CHECK-ANDROID-NEXT: bne .LBB2_4 233; CHECK-ANDROID-NEXT: @ %bb.2: @ %cont 234; CHECK-ANDROID-NEXT: @ in Loop: Header=BB2_1 Depth=1 235; CHECK-ANDROID-NEXT: vmov s0, r0 236; CHECK-ANDROID-NEXT: vcmp.f32 s0, s16 237; CHECK-ANDROID-NEXT: vmrs APSR_nzcv, fpscr 238; CHECK-ANDROID-NEXT: ble .LBB2_1 239; CHECK-ANDROID-NEXT: @ %bb.3: @ %bb_end 240; CHECK-ANDROID-NEXT: ldrb r0, [r8, #8] 241; CHECK-ANDROID-NEXT: strb r0, [r4] 242; CHECK-ANDROID-NEXT: .LBB2_4: @ %handler 243; CHECK-ANDROID-NEXT: mov r0, r8 244; CHECK-ANDROID-NEXT: bl free 245; CHECK-ANDROID-NEXT: mov r0, #1065353216 246; CHECK-ANDROID-NEXT: add sp, sp, #8 247; CHECK-ANDROID-NEXT: vpop {d8} 248; CHECK-ANDROID-NEXT: pop {r4, r8, r11, pc} 249; Access part of the error object and save it to error_ref 250 251; spill r0 252; reload r0 253entry: 254 %error_ptr_ref = alloca swifterror %swift_error* 255 br label %bb_loop 256bb_loop: 257 store %swift_error* null, %swift_error** %error_ptr_ref 258 %call = call float @foo(%swift_error** swifterror %error_ptr_ref) 259 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 260 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 261 %tmp = bitcast %swift_error* %error_from_foo to i8* 262 br i1 %had_error_from_foo, label %handler, label %cont 263cont: 264 %cmp = fcmp ogt float %call, 1.000000e+00 265 br i1 %cmp, label %bb_end, label %bb_loop 266bb_end: 267 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 268 %t = load i8, i8* %v1 269 store i8 %t, i8* %error_ref 270 br label %handler 271handler: 272 call void @free(i8* %tmp) 273 ret float 1.0 274} 275 276; "foo_if" is a function that takes a swifterror parameter, it sets swifterror 277; under a certain condition. 278define float @foo_if(%swift_error** swifterror %error_ptr_ref, i32 %cc) { 279; CHECK-APPLE-LABEL: foo_if: 280; CHECK-APPLE: @ %bb.0: @ %entry 281; CHECK-APPLE-NEXT: push {lr} 282; CHECK-APPLE-NEXT: cmp r0, #0 283; CHECK-APPLE-NEXT: beq LBB3_2 284; CHECK-APPLE-NEXT: @ %bb.1: @ %gen_error 285; CHECK-APPLE-NEXT: mov r0, #16 286; CHECK-APPLE-NEXT: mov r1, #0 287; CHECK-APPLE-NEXT: bl _malloc 288; CHECK-APPLE-NEXT: mov r8, r0 289; CHECK-APPLE-NEXT: mov r0, #1 290; CHECK-APPLE-NEXT: vmov.f32 s0, #1.000000e+00 291; CHECK-APPLE-NEXT: strb r0, [r8, #8] 292; CHECK-APPLE-NEXT: b LBB3_3 293; CHECK-APPLE-NEXT: LBB3_2: 294; CHECK-APPLE-NEXT: vldr s0, LCPI3_0 295; CHECK-APPLE-NEXT: LBB3_3: @ %common.ret 296; CHECK-APPLE-NEXT: vmov r0, s0 297; CHECK-APPLE-NEXT: pop {lr} 298; CHECK-APPLE-NEXT: bx lr 299; CHECK-APPLE-NEXT: .p2align 2 300; CHECK-APPLE-NEXT: @ %bb.4: 301; CHECK-APPLE-NEXT: .data_region 302; CHECK-APPLE-NEXT: LCPI3_0: 303; CHECK-APPLE-NEXT: .long 0x00000000 @ float 0 304; CHECK-APPLE-NEXT: .end_data_region 305; 306; CHECK-O0-LABEL: foo_if: 307; CHECK-O0: @ %bb.0: @ %entry 308; CHECK-O0-NEXT: push {r7, lr} 309; CHECK-O0-NEXT: mov r7, sp 310; CHECK-O0-NEXT: sub sp, sp, #4 311; CHECK-O0-NEXT: str r8, [sp] @ 4-byte Spill 312; CHECK-O0-NEXT: cmp r0, #0 313; CHECK-O0-NEXT: beq LBB3_2 314; CHECK-O0-NEXT: @ %bb.1: @ %gen_error 315; CHECK-O0-NEXT: mov r0, #16 316; CHECK-O0-NEXT: mov r1, #0 317; CHECK-O0-NEXT: bl _malloc 318; CHECK-O0-NEXT: mov r1, r0 319; CHECK-O0-NEXT: mov r8, r1 320; CHECK-O0-NEXT: mov r0, #1 321; CHECK-O0-NEXT: strb r0, [r1, #8] 322; CHECK-O0-NEXT: mov r0, #1065353216 323; CHECK-O0-NEXT: mov sp, r7 324; CHECK-O0-NEXT: pop {r7, pc} 325; CHECK-O0-NEXT: LBB3_2: @ %normal 326; CHECK-O0-NEXT: ldr r8, [sp] @ 4-byte Reload 327; CHECK-O0-NEXT: mov r0, #0 328; CHECK-O0-NEXT: mov sp, r7 329; CHECK-O0-NEXT: pop {r7, pc} 330; 331; CHECK-ANDROID-LABEL: foo_if: 332; CHECK-ANDROID: @ %bb.0: @ %entry 333; CHECK-ANDROID-NEXT: .save {r11, lr} 334; CHECK-ANDROID-NEXT: push {r11, lr} 335; CHECK-ANDROID-NEXT: cmp r0, #0 336; CHECK-ANDROID-NEXT: beq .LBB3_2 337; CHECK-ANDROID-NEXT: @ %bb.1: @ %gen_error 338; CHECK-ANDROID-NEXT: mov r0, #16 339; CHECK-ANDROID-NEXT: mov r1, #0 340; CHECK-ANDROID-NEXT: bl malloc 341; CHECK-ANDROID-NEXT: vmov.f32 s0, #1.000000e+00 342; CHECK-ANDROID-NEXT: mov r8, r0 343; CHECK-ANDROID-NEXT: mov r0, #1 344; CHECK-ANDROID-NEXT: strb r0, [r8, #8] 345; CHECK-ANDROID-NEXT: vmov r0, s0 346; CHECK-ANDROID-NEXT: pop {r11, pc} 347; CHECK-ANDROID-NEXT: .LBB3_2: 348; CHECK-ANDROID-NEXT: vldr s0, .LCPI3_0 349; CHECK-ANDROID-NEXT: vmov r0, s0 350; CHECK-ANDROID-NEXT: pop {r11, pc} 351; CHECK-ANDROID-NEXT: .p2align 2 352; CHECK-ANDROID-NEXT: @ %bb.3: 353; CHECK-ANDROID-NEXT: .LCPI3_0: 354; CHECK-ANDROID-NEXT: .long 0x00000000 @ float 0 355 356; spill to stack 357; reload from stack 358entry: 359 %cond = icmp ne i32 %cc, 0 360 br i1 %cond, label %gen_error, label %normal 361 362gen_error: 363 %call = call i8* @malloc(i64 16) 364 %call.0 = bitcast i8* %call to %swift_error* 365 store %swift_error* %call.0, %swift_error** %error_ptr_ref 366 %tmp = getelementptr inbounds i8, i8* %call, i64 8 367 store i8 1, i8* %tmp 368 ret float 1.0 369 370normal: 371 ret float 0.0 372} 373 374; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror 375; under a certain condition inside a loop. 376define float @foo_loop(%swift_error** swifterror %error_ptr_ref, i32 %cc, float %cc2) { 377; CHECK-APPLE-LABEL: foo_loop: 378; CHECK-APPLE: @ %bb.0: @ %entry 379; CHECK-APPLE-NEXT: push {r4, r5, lr} 380; CHECK-APPLE-NEXT: vpush {d8, d9} 381; CHECK-APPLE-NEXT: vmov.f32 s18, #1.000000e+00 382; CHECK-APPLE-NEXT: mov r4, r0 383; CHECK-APPLE-NEXT: vmov s16, r1 384; CHECK-APPLE-NEXT: mov r5, #1 385; CHECK-APPLE-NEXT: b LBB4_2 386; CHECK-APPLE-NEXT: LBB4_1: @ %bb_cont 387; CHECK-APPLE-NEXT: @ in Loop: Header=BB4_2 Depth=1 388; CHECK-APPLE-NEXT: vcmp.f32 s16, s18 389; CHECK-APPLE-NEXT: vmrs APSR_nzcv, fpscr 390; CHECK-APPLE-NEXT: bgt LBB4_4 391; CHECK-APPLE-NEXT: LBB4_2: @ %bb_loop 392; CHECK-APPLE-NEXT: @ =>This Inner Loop Header: Depth=1 393; CHECK-APPLE-NEXT: cmp r4, #0 394; CHECK-APPLE-NEXT: beq LBB4_1 395; CHECK-APPLE-NEXT: @ %bb.3: @ %gen_error 396; CHECK-APPLE-NEXT: @ in Loop: Header=BB4_2 Depth=1 397; CHECK-APPLE-NEXT: mov r0, #16 398; CHECK-APPLE-NEXT: mov r1, #0 399; CHECK-APPLE-NEXT: bl _malloc 400; CHECK-APPLE-NEXT: mov r8, r0 401; CHECK-APPLE-NEXT: strb r5, [r0, #8] 402; CHECK-APPLE-NEXT: b LBB4_1 403; CHECK-APPLE-NEXT: LBB4_4: @ %bb_end 404; CHECK-APPLE-NEXT: mov r0, #0 405; CHECK-APPLE-NEXT: vpop {d8, d9} 406; CHECK-APPLE-NEXT: pop {r4, r5, pc} 407; 408; CHECK-O0-LABEL: foo_loop: 409; CHECK-O0: @ %bb.0: @ %entry 410; CHECK-O0-NEXT: push {r7, lr} 411; CHECK-O0-NEXT: mov r7, sp 412; CHECK-O0-NEXT: sub sp, sp, #20 413; CHECK-O0-NEXT: str r0, [sp, #8] @ 4-byte Spill 414; CHECK-O0-NEXT: vmov s0, r1 415; CHECK-O0-NEXT: vstr s0, [r7, #-8] @ 4-byte Spill 416; CHECK-O0-NEXT: str r8, [r7, #-4] @ 4-byte Spill 417; CHECK-O0-NEXT: b LBB4_1 418; CHECK-O0-NEXT: LBB4_1: @ %bb_loop 419; CHECK-O0-NEXT: @ =>This Inner Loop Header: Depth=1 420; CHECK-O0-NEXT: ldr r1, [sp, #8] @ 4-byte Reload 421; CHECK-O0-NEXT: ldr r0, [r7, #-4] @ 4-byte Reload 422; CHECK-O0-NEXT: cmp r1, #0 423; CHECK-O0-NEXT: str r0, [sp, #4] @ 4-byte Spill 424; CHECK-O0-NEXT: beq LBB4_3 425; CHECK-O0-NEXT: @ %bb.2: @ %gen_error 426; CHECK-O0-NEXT: @ in Loop: Header=BB4_1 Depth=1 427; CHECK-O0-NEXT: mov r0, #16 428; CHECK-O0-NEXT: mov r1, #0 429; CHECK-O0-NEXT: bl _malloc 430; CHECK-O0-NEXT: mov r2, r0 431; CHECK-O0-NEXT: movw r1, #1 432; CHECK-O0-NEXT: strb r1, [r2, #8] 433; CHECK-O0-NEXT: str r0, [sp, #4] @ 4-byte Spill 434; CHECK-O0-NEXT: LBB4_3: @ %bb_cont 435; CHECK-O0-NEXT: @ in Loop: Header=BB4_1 Depth=1 436; CHECK-O0-NEXT: vldr s0, [r7, #-8] @ 4-byte Reload 437; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 438; CHECK-O0-NEXT: str r0, [sp] @ 4-byte Spill 439; CHECK-O0-NEXT: vmov.f32 s2, #1.000000e+00 440; CHECK-O0-NEXT: vcmp.f32 s0, s2 441; CHECK-O0-NEXT: vmrs APSR_nzcv, fpscr 442; CHECK-O0-NEXT: str r0, [r7, #-4] @ 4-byte Spill 443; CHECK-O0-NEXT: ble LBB4_1 444; CHECK-O0-NEXT: @ %bb.4: @ %bb_end 445; CHECK-O0-NEXT: ldr r8, [sp] @ 4-byte Reload 446; CHECK-O0-NEXT: mov r0, #0 447; CHECK-O0-NEXT: mov sp, r7 448; CHECK-O0-NEXT: pop {r7, pc} 449; 450; CHECK-ANDROID-LABEL: foo_loop: 451; CHECK-ANDROID: @ %bb.0: @ %entry 452; CHECK-ANDROID-NEXT: .save {r4, r5, r11, lr} 453; CHECK-ANDROID-NEXT: push {r4, r5, r11, lr} 454; CHECK-ANDROID-NEXT: .vsave {d8, d9} 455; CHECK-ANDROID-NEXT: vpush {d8, d9} 456; CHECK-ANDROID-NEXT: vmov.f32 s18, #1.000000e+00 457; CHECK-ANDROID-NEXT: mov r4, r0 458; CHECK-ANDROID-NEXT: vmov s16, r1 459; CHECK-ANDROID-NEXT: mov r5, #1 460; CHECK-ANDROID-NEXT: b .LBB4_2 461; CHECK-ANDROID-NEXT: .LBB4_1: @ %bb_cont 462; CHECK-ANDROID-NEXT: @ in Loop: Header=BB4_2 Depth=1 463; CHECK-ANDROID-NEXT: vcmp.f32 s16, s18 464; CHECK-ANDROID-NEXT: vmrs APSR_nzcv, fpscr 465; CHECK-ANDROID-NEXT: bgt .LBB4_4 466; CHECK-ANDROID-NEXT: .LBB4_2: @ %bb_loop 467; CHECK-ANDROID-NEXT: @ =>This Inner Loop Header: Depth=1 468; CHECK-ANDROID-NEXT: cmp r4, #0 469; CHECK-ANDROID-NEXT: beq .LBB4_1 470; CHECK-ANDROID-NEXT: @ %bb.3: @ %gen_error 471; CHECK-ANDROID-NEXT: @ in Loop: Header=BB4_2 Depth=1 472; CHECK-ANDROID-NEXT: mov r0, #16 473; CHECK-ANDROID-NEXT: mov r1, #0 474; CHECK-ANDROID-NEXT: bl malloc 475; CHECK-ANDROID-NEXT: mov r8, r0 476; CHECK-ANDROID-NEXT: strb r5, [r0, #8] 477; CHECK-ANDROID-NEXT: b .LBB4_1 478; CHECK-ANDROID-NEXT: .LBB4_4: @ %bb_end 479; CHECK-ANDROID-NEXT: mov r0, #0 480; CHECK-ANDROID-NEXT: vpop {d8, d9} 481; CHECK-ANDROID-NEXT: pop {r4, r5, r11, pc} 482; swifterror is kept in a register 483 484; spill r0 485; reload from stack 486entry: 487 br label %bb_loop 488 489bb_loop: 490 %cond = icmp ne i32 %cc, 0 491 br i1 %cond, label %gen_error, label %bb_cont 492 493gen_error: 494 %call = call i8* @malloc(i64 16) 495 %call.0 = bitcast i8* %call to %swift_error* 496 store %swift_error* %call.0, %swift_error** %error_ptr_ref 497 %tmp = getelementptr inbounds i8, i8* %call, i64 8 498 store i8 1, i8* %tmp 499 br label %bb_cont 500 501bb_cont: 502 %cmp = fcmp ogt float %cc2, 1.000000e+00 503 br i1 %cmp, label %bb_end, label %bb_loop 504bb_end: 505 ret float 0.0 506} 507 508; "foo_sret" is a function that takes a swifterror parameter, it also has a sret 509; parameter. 510define void @foo_sret(%struct.S* sret(%struct.S) %agg.result, i32 %val1, %swift_error** swifterror %error_ptr_ref) { 511; CHECK-APPLE-LABEL: foo_sret: 512; CHECK-APPLE: @ %bb.0: @ %entry 513; CHECK-APPLE-NEXT: push {r4, r5, lr} 514; CHECK-APPLE-NEXT: mov r4, r1 515; CHECK-APPLE-NEXT: mov r5, r0 516; CHECK-APPLE-NEXT: mov r0, #16 517; CHECK-APPLE-NEXT: mov r1, #0 518; CHECK-APPLE-NEXT: bl _malloc 519; CHECK-APPLE-NEXT: mov r1, #1 520; CHECK-APPLE-NEXT: mov r8, r0 521; CHECK-APPLE-NEXT: strb r1, [r0, #8] 522; CHECK-APPLE-NEXT: str r4, [r5, #4] 523; CHECK-APPLE-NEXT: pop {r4, r5, pc} 524; 525; CHECK-O0-LABEL: foo_sret: 526; CHECK-O0: @ %bb.0: @ %entry 527; CHECK-O0-NEXT: push {r7, lr} 528; CHECK-O0-NEXT: mov r7, sp 529; CHECK-O0-NEXT: sub sp, sp, #8 530; CHECK-O0-NEXT: str r1, [sp] @ 4-byte Spill 531; CHECK-O0-NEXT: str r0, [sp, #4] @ 4-byte Spill 532; CHECK-O0-NEXT: mov r0, #16 533; CHECK-O0-NEXT: mov r1, #0 534; CHECK-O0-NEXT: bl _malloc 535; CHECK-O0-NEXT: ldr r1, [sp] @ 4-byte Reload 536; CHECK-O0-NEXT: mov r3, r0 537; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 538; CHECK-O0-NEXT: mov r8, r3 539; CHECK-O0-NEXT: mov r2, #1 540; CHECK-O0-NEXT: strb r2, [r3, #8] 541; CHECK-O0-NEXT: str r1, [r0, #4] 542; CHECK-O0-NEXT: mov sp, r7 543; CHECK-O0-NEXT: pop {r7, pc} 544; 545; CHECK-ANDROID-LABEL: foo_sret: 546; CHECK-ANDROID: @ %bb.0: @ %entry 547; CHECK-ANDROID-NEXT: .save {r4, r5, r11, lr} 548; CHECK-ANDROID-NEXT: push {r4, r5, r11, lr} 549; CHECK-ANDROID-NEXT: mov r4, r1 550; CHECK-ANDROID-NEXT: mov r5, r0 551; CHECK-ANDROID-NEXT: mov r0, #16 552; CHECK-ANDROID-NEXT: mov r1, #0 553; CHECK-ANDROID-NEXT: bl malloc 554; CHECK-ANDROID-NEXT: mov r1, #1 555; CHECK-ANDROID-NEXT: mov r8, r0 556; CHECK-ANDROID-NEXT: strb r1, [r0, #8] 557; CHECK-ANDROID-NEXT: str r4, [r5, #4] 558; CHECK-ANDROID-NEXT: pop {r4, r5, r11, pc} 559 560; spill to stack: sret and val1 561; reload from stack: sret and val1 562entry: 563 %call = call i8* @malloc(i64 16) 564 %call.0 = bitcast i8* %call to %swift_error* 565 store %swift_error* %call.0, %swift_error** %error_ptr_ref 566 %tmp = getelementptr inbounds i8, i8* %call, i64 8 567 store i8 1, i8* %tmp 568 %v2 = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1 569 store i32 %val1, i32* %v2 570 ret void 571} 572 573; "caller3" calls "foo_sret" that takes a swifterror parameter. 574define float @caller3(i8* %error_ref) { 575; CHECK-APPLE-LABEL: caller3: 576; CHECK-APPLE: @ %bb.0: @ %entry 577; CHECK-APPLE-NEXT: push {r4, r7, r8, lr} 578; CHECK-APPLE-NEXT: add r7, sp, #8 579; CHECK-APPLE-NEXT: sub sp, sp, #32 580; CHECK-APPLE-NEXT: bfc sp, #0, #3 581; CHECK-APPLE-NEXT: mov r4, r0 582; CHECK-APPLE-NEXT: add r0, sp, #8 583; CHECK-APPLE-NEXT: mov r1, #1 584; CHECK-APPLE-NEXT: mov r8, #0 585; CHECK-APPLE-NEXT: bl _foo_sret 586; CHECK-APPLE-NEXT: mov r0, r8 587; CHECK-APPLE-NEXT: cmp r8, #0 588; CHECK-APPLE-NEXT: ldrbeq r1, [r0, #8] 589; CHECK-APPLE-NEXT: strbeq r1, [r4] 590; CHECK-APPLE-NEXT: bl _free 591; CHECK-APPLE-NEXT: mov r0, #1065353216 592; CHECK-APPLE-NEXT: sub sp, r7, #8 593; CHECK-APPLE-NEXT: pop {r4, r7, r8, pc} 594; 595; CHECK-O0-LABEL: caller3: 596; CHECK-O0: @ %bb.0: @ %entry 597; CHECK-O0-NEXT: push {r7, lr} 598; CHECK-O0-NEXT: mov r7, sp 599; CHECK-O0-NEXT: push {r8} 600; CHECK-O0-NEXT: sub sp, sp, #44 601; CHECK-O0-NEXT: bfc sp, #0, #3 602; CHECK-O0-NEXT: @ implicit-def: $r1 603; CHECK-O0-NEXT: str r0, [sp, #4] @ 4-byte Spill 604; CHECK-O0-NEXT: mov r8, #0 605; CHECK-O0-NEXT: add r0, sp, #16 606; CHECK-O0-NEXT: mov r1, #1 607; CHECK-O0-NEXT: bl _foo_sret 608; CHECK-O0-NEXT: str r8, [sp, #8] @ 4-byte Spill 609; CHECK-O0-NEXT: movw r0, #0 610; CHECK-O0-NEXT: cmp r8, r0 611; CHECK-O0-NEXT: bne LBB6_2 612; CHECK-O0-NEXT: @ %bb.1: @ %cont 613; CHECK-O0-NEXT: ldr r1, [sp, #4] @ 4-byte Reload 614; CHECK-O0-NEXT: ldr r0, [sp, #8] @ 4-byte Reload 615; CHECK-O0-NEXT: ldrb r0, [r0, #8] 616; CHECK-O0-NEXT: strb r0, [r1] 617; CHECK-O0-NEXT: LBB6_2: @ %handler 618; CHECK-O0-NEXT: ldr r0, [sp, #8] @ 4-byte Reload 619; CHECK-O0-NEXT: bl _free 620; CHECK-O0-NEXT: mov r0, #1065353216 621; CHECK-O0-NEXT: sub sp, r7, #4 622; CHECK-O0-NEXT: pop {r8} 623; CHECK-O0-NEXT: pop {r7, pc} 624; 625; CHECK-ANDROID-LABEL: caller3: 626; CHECK-ANDROID: @ %bb.0: @ %entry 627; CHECK-ANDROID-NEXT: .save {r4, r8, r11, lr} 628; CHECK-ANDROID-NEXT: push {r4, r8, r11, lr} 629; CHECK-ANDROID-NEXT: .pad #32 630; CHECK-ANDROID-NEXT: sub sp, sp, #32 631; CHECK-ANDROID-NEXT: mov r4, r0 632; CHECK-ANDROID-NEXT: add r0, sp, #8 633; CHECK-ANDROID-NEXT: mov r1, #1 634; CHECK-ANDROID-NEXT: mov r8, #0 635; CHECK-ANDROID-NEXT: bl foo_sret 636; CHECK-ANDROID-NEXT: mov r0, r8 637; CHECK-ANDROID-NEXT: cmp r8, #0 638; CHECK-ANDROID-NEXT: ldrbeq r1, [r0, #8] 639; CHECK-ANDROID-NEXT: strbeq r1, [r4] 640; CHECK-ANDROID-NEXT: bl free 641; CHECK-ANDROID-NEXT: mov r0, #1065353216 642; CHECK-ANDROID-NEXT: add sp, sp, #32 643; CHECK-ANDROID-NEXT: pop {r4, r8, r11, pc} 644; Access part of the error object and save it to error_ref 645 646; Access part of the error object and save it to error_ref 647entry: 648 %s = alloca %struct.S, align 8 649 %error_ptr_ref = alloca swifterror %swift_error* 650 store %swift_error* null, %swift_error** %error_ptr_ref 651 call void @foo_sret(%struct.S* sret(%struct.S) %s, i32 1, %swift_error** swifterror %error_ptr_ref) 652 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 653 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 654 %tmp = bitcast %swift_error* %error_from_foo to i8* 655 br i1 %had_error_from_foo, label %handler, label %cont 656cont: 657 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 658 %t = load i8, i8* %v1 659 store i8 %t, i8* %error_ref 660 br label %handler 661handler: 662 call void @free(i8* %tmp) 663 ret float 1.0 664} 665 666; "foo_vararg" is a function that takes a swifterror parameter, it also has 667; variable number of arguments. 668declare void @llvm.va_start(i8*) nounwind 669define float @foo_vararg(%swift_error** swifterror %error_ptr_ref, ...) { 670; CHECK-APPLE-LABEL: foo_vararg: 671; CHECK-APPLE: @ %bb.0: @ %entry 672; CHECK-APPLE-NEXT: sub sp, sp, #16 673; CHECK-APPLE-NEXT: push {r7, lr} 674; CHECK-APPLE-NEXT: mov r7, sp 675; CHECK-APPLE-NEXT: sub sp, sp, #24 676; CHECK-APPLE-NEXT: bfc sp, #0, #3 677; CHECK-APPLE-NEXT: add r8, r7, #8 678; CHECK-APPLE-NEXT: stm r8, {r0, r1, r2, r3} 679; CHECK-APPLE-NEXT: mov r0, #16 680; CHECK-APPLE-NEXT: mov r1, #0 681; CHECK-APPLE-NEXT: bl _malloc 682; CHECK-APPLE-NEXT: mov r8, r0 683; CHECK-APPLE-NEXT: mov r0, #1 684; CHECK-APPLE-NEXT: strb r0, [r8, #8] 685; CHECK-APPLE-NEXT: add r0, r7, #8 686; CHECK-APPLE-NEXT: add r0, r0, #4 687; CHECK-APPLE-NEXT: ldr r2, [r7, #8] 688; CHECK-APPLE-NEXT: ldr r1, [r0], #4 689; CHECK-APPLE-NEXT: ldr r3, [r0], #4 690; CHECK-APPLE-NEXT: str r0, [sp, #16] 691; CHECK-APPLE-NEXT: mov r0, #1065353216 692; CHECK-APPLE-NEXT: str r2, [sp, #12] 693; CHECK-APPLE-NEXT: str r1, [sp, #8] 694; CHECK-APPLE-NEXT: str r3, [sp, #4] 695; CHECK-APPLE-NEXT: mov sp, r7 696; CHECK-APPLE-NEXT: pop {r7, lr} 697; CHECK-APPLE-NEXT: add sp, sp, #16 698; CHECK-APPLE-NEXT: bx lr 699; 700; CHECK-O0-LABEL: foo_vararg: 701; CHECK-O0: @ %bb.0: @ %entry 702; CHECK-O0-NEXT: sub sp, sp, #16 703; CHECK-O0-NEXT: push {r7, lr} 704; CHECK-O0-NEXT: mov r7, sp 705; CHECK-O0-NEXT: sub sp, sp, #24 706; CHECK-O0-NEXT: bfc sp, #0, #3 707; CHECK-O0-NEXT: str r3, [r7, #20] 708; CHECK-O0-NEXT: str r2, [r7, #16] 709; CHECK-O0-NEXT: str r1, [r7, #12] 710; CHECK-O0-NEXT: str r0, [r7, #8] 711; CHECK-O0-NEXT: mov r0, #16 712; CHECK-O0-NEXT: mov r1, #0 713; CHECK-O0-NEXT: bl _malloc 714; CHECK-O0-NEXT: mov r1, r0 715; CHECK-O0-NEXT: mov r8, r1 716; CHECK-O0-NEXT: mov r0, #1 717; CHECK-O0-NEXT: strb r0, [r1, #8] 718; CHECK-O0-NEXT: add r0, r7, #8 719; CHECK-O0-NEXT: str r0, [sp, #16] 720; CHECK-O0-NEXT: ldr r0, [sp, #16] 721; CHECK-O0-NEXT: add r1, r0, #4 722; CHECK-O0-NEXT: str r1, [sp, #16] 723; CHECK-O0-NEXT: ldr r0, [r0] 724; CHECK-O0-NEXT: str r0, [sp, #12] 725; CHECK-O0-NEXT: ldr r0, [sp, #16] 726; CHECK-O0-NEXT: add r1, r0, #4 727; CHECK-O0-NEXT: str r1, [sp, #16] 728; CHECK-O0-NEXT: ldr r0, [r0] 729; CHECK-O0-NEXT: str r0, [sp, #8] 730; CHECK-O0-NEXT: ldr r0, [sp, #16] 731; CHECK-O0-NEXT: add r1, r0, #4 732; CHECK-O0-NEXT: str r1, [sp, #16] 733; CHECK-O0-NEXT: ldr r0, [r0] 734; CHECK-O0-NEXT: str r0, [sp, #4] 735; CHECK-O0-NEXT: mov r0, #1065353216 736; CHECK-O0-NEXT: mov sp, r7 737; CHECK-O0-NEXT: pop {r7, lr} 738; CHECK-O0-NEXT: add sp, sp, #16 739; CHECK-O0-NEXT: bx lr 740; 741; CHECK-ANDROID-LABEL: foo_vararg: 742; CHECK-ANDROID: @ %bb.0: @ %entry 743; CHECK-ANDROID-NEXT: .pad #16 744; CHECK-ANDROID-NEXT: sub sp, sp, #16 745; CHECK-ANDROID-NEXT: .save {r11, lr} 746; CHECK-ANDROID-NEXT: push {r11, lr} 747; CHECK-ANDROID-NEXT: .pad #24 748; CHECK-ANDROID-NEXT: sub sp, sp, #24 749; CHECK-ANDROID-NEXT: add r8, sp, #32 750; CHECK-ANDROID-NEXT: stm r8, {r0, r1, r2, r3} 751; CHECK-ANDROID-NEXT: mov r0, #16 752; CHECK-ANDROID-NEXT: mov r1, #0 753; CHECK-ANDROID-NEXT: bl malloc 754; CHECK-ANDROID-NEXT: mov r8, r0 755; CHECK-ANDROID-NEXT: mov r0, #1 756; CHECK-ANDROID-NEXT: strb r0, [r8, #8] 757; CHECK-ANDROID-NEXT: add r0, sp, #32 758; CHECK-ANDROID-NEXT: orr r0, r0, #4 759; CHECK-ANDROID-NEXT: ldr r2, [sp, #32] 760; CHECK-ANDROID-NEXT: ldr r1, [r0], #4 761; CHECK-ANDROID-NEXT: ldr r3, [r0], #4 762; CHECK-ANDROID-NEXT: str r0, [sp, #16] 763; CHECK-ANDROID-NEXT: mov r0, #1065353216 764; CHECK-ANDROID-NEXT: str r2, [sp, #12] 765; CHECK-ANDROID-NEXT: str r1, [sp, #8] 766; CHECK-ANDROID-NEXT: str r3, [sp, #4] 767; CHECK-ANDROID-NEXT: add sp, sp, #24 768; CHECK-ANDROID-NEXT: pop {r11, lr} 769; CHECK-ANDROID-NEXT: add sp, sp, #16 770; CHECK-ANDROID-NEXT: bx lr 771 772entry: 773 %call = call i8* @malloc(i64 16) 774 %call.0 = bitcast i8* %call to %swift_error* 775 store %swift_error* %call.0, %swift_error** %error_ptr_ref 776 %tmp = getelementptr inbounds i8, i8* %call, i64 8 777 store i8 1, i8* %tmp 778 779 %args = alloca i8*, align 8 780 %a10 = alloca i32, align 4 781 %a11 = alloca i32, align 4 782 %a12 = alloca i32, align 4 783 %v10 = bitcast i8** %args to i8* 784 call void @llvm.va_start(i8* %v10) 785 %v11 = va_arg i8** %args, i32 786 store i32 %v11, i32* %a10, align 4 787 %v12 = va_arg i8** %args, i32 788 store i32 %v12, i32* %a11, align 4 789 %v13 = va_arg i8** %args, i32 790 store i32 %v13, i32* %a12, align 4 791 792 ret float 1.0 793} 794 795; "caller4" calls "foo_vararg" that takes a swifterror parameter. 796define float @caller4(i8* %error_ref) { 797; CHECK-APPLE-LABEL: caller4: 798; CHECK-APPLE: @ %bb.0: @ %entry 799; CHECK-APPLE-NEXT: push {r4, r8, lr} 800; CHECK-APPLE-NEXT: sub sp, sp, #16 801; CHECK-APPLE-NEXT: mov r4, r0 802; CHECK-APPLE-NEXT: mov r0, #11 803; CHECK-APPLE-NEXT: str r0, [sp, #4] 804; CHECK-APPLE-NEXT: mov r0, #10 805; CHECK-APPLE-NEXT: str r0, [sp, #8] 806; CHECK-APPLE-NEXT: mov r0, #12 807; CHECK-APPLE-NEXT: str r0, [sp] 808; CHECK-APPLE-NEXT: mov r8, #0 809; CHECK-APPLE-NEXT: mov r0, #10 810; CHECK-APPLE-NEXT: mov r1, #11 811; CHECK-APPLE-NEXT: mov r2, #12 812; CHECK-APPLE-NEXT: bl _foo_vararg 813; CHECK-APPLE-NEXT: mov r0, r8 814; CHECK-APPLE-NEXT: cmp r8, #0 815; CHECK-APPLE-NEXT: ldrbeq r1, [r0, #8] 816; CHECK-APPLE-NEXT: strbeq r1, [r4] 817; CHECK-APPLE-NEXT: bl _free 818; CHECK-APPLE-NEXT: mov r0, #1065353216 819; CHECK-APPLE-NEXT: add sp, sp, #16 820; CHECK-APPLE-NEXT: pop {r4, r8, pc} 821; 822; CHECK-O0-LABEL: caller4: 823; CHECK-O0: @ %bb.0: @ %entry 824; CHECK-O0-NEXT: push {r7, lr} 825; CHECK-O0-NEXT: mov r7, sp 826; CHECK-O0-NEXT: push {r8} 827; CHECK-O0-NEXT: sub sp, sp, #24 828; CHECK-O0-NEXT: @ implicit-def: $r1 829; CHECK-O0-NEXT: str r0, [sp] @ 4-byte Spill 830; CHECK-O0-NEXT: mov r8, #0 831; CHECK-O0-NEXT: mov r0, #10 832; CHECK-O0-NEXT: str r0, [r7, #-12] 833; CHECK-O0-NEXT: mov r0, #11 834; CHECK-O0-NEXT: str r0, [sp, #12] 835; CHECK-O0-NEXT: mov r0, #12 836; CHECK-O0-NEXT: str r0, [sp, #8] 837; CHECK-O0-NEXT: ldr r0, [r7, #-12] 838; CHECK-O0-NEXT: ldr r1, [sp, #12] 839; CHECK-O0-NEXT: ldr r2, [sp, #8] 840; CHECK-O0-NEXT: bl _foo_vararg 841; CHECK-O0-NEXT: str r8, [sp, #4] @ 4-byte Spill 842; CHECK-O0-NEXT: movw r0, #0 843; CHECK-O0-NEXT: cmp r8, r0 844; CHECK-O0-NEXT: bne LBB8_2 845; CHECK-O0-NEXT: @ %bb.1: @ %cont 846; CHECK-O0-NEXT: ldr r1, [sp] @ 4-byte Reload 847; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 848; CHECK-O0-NEXT: ldrb r0, [r0, #8] 849; CHECK-O0-NEXT: strb r0, [r1] 850; CHECK-O0-NEXT: LBB8_2: @ %handler 851; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 852; CHECK-O0-NEXT: bl _free 853; CHECK-O0-NEXT: mov r0, #1065353216 854; CHECK-O0-NEXT: sub sp, r7, #4 855; CHECK-O0-NEXT: pop {r8} 856; CHECK-O0-NEXT: pop {r7, pc} 857; 858; CHECK-ANDROID-LABEL: caller4: 859; CHECK-ANDROID: @ %bb.0: @ %entry 860; CHECK-ANDROID-NEXT: .save {r4, r8, r11, lr} 861; CHECK-ANDROID-NEXT: push {r4, r8, r11, lr} 862; CHECK-ANDROID-NEXT: .pad #16 863; CHECK-ANDROID-NEXT: sub sp, sp, #16 864; CHECK-ANDROID-NEXT: mov r4, r0 865; CHECK-ANDROID-NEXT: mov r0, #11 866; CHECK-ANDROID-NEXT: str r0, [sp, #4] 867; CHECK-ANDROID-NEXT: mov r0, #10 868; CHECK-ANDROID-NEXT: str r0, [sp, #8] 869; CHECK-ANDROID-NEXT: mov r0, #12 870; CHECK-ANDROID-NEXT: str r0, [sp] 871; CHECK-ANDROID-NEXT: mov r8, #0 872; CHECK-ANDROID-NEXT: mov r0, #10 873; CHECK-ANDROID-NEXT: mov r1, #11 874; CHECK-ANDROID-NEXT: mov r2, #12 875; CHECK-ANDROID-NEXT: bl foo_vararg 876; CHECK-ANDROID-NEXT: mov r0, r8 877; CHECK-ANDROID-NEXT: cmp r8, #0 878; CHECK-ANDROID-NEXT: ldrbeq r1, [r0, #8] 879; CHECK-ANDROID-NEXT: strbeq r1, [r4] 880; CHECK-ANDROID-NEXT: bl free 881; CHECK-ANDROID-NEXT: mov r0, #1065353216 882; CHECK-ANDROID-NEXT: add sp, sp, #16 883; CHECK-ANDROID-NEXT: pop {r4, r8, r11, pc} 884; Access part of the error object and save it to error_ref 885entry: 886 %error_ptr_ref = alloca swifterror %swift_error* 887 store %swift_error* null, %swift_error** %error_ptr_ref 888 889 %a10 = alloca i32, align 4 890 %a11 = alloca i32, align 4 891 %a12 = alloca i32, align 4 892 store i32 10, i32* %a10, align 4 893 store i32 11, i32* %a11, align 4 894 store i32 12, i32* %a12, align 4 895 %v10 = load i32, i32* %a10, align 4 896 %v11 = load i32, i32* %a11, align 4 897 %v12 = load i32, i32* %a12, align 4 898 899 %call = call float (%swift_error**, ...) @foo_vararg(%swift_error** swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12) 900 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref 901 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null 902 %tmp = bitcast %swift_error* %error_from_foo to i8* 903 br i1 %had_error_from_foo, label %handler, label %cont 904 905cont: 906 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1 907 %t = load i8, i8* %v1 908 store i8 %t, i8* %error_ref 909 br label %handler 910handler: 911 call void @free(i8* %tmp) 912 ret float 1.0 913} 914 915; Check that we don't blow up on tail calling swifterror argument functions. 916define float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref) { 917; CHECK-APPLE-LABEL: tailcallswifterror: 918; CHECK-APPLE: @ %bb.0: @ %entry 919; CHECK-APPLE-NEXT: push {lr} 920; CHECK-APPLE-NEXT: bl _tailcallswifterror 921; CHECK-APPLE-NEXT: pop {lr} 922; CHECK-APPLE-NEXT: bx lr 923; 924; CHECK-O0-LABEL: tailcallswifterror: 925; CHECK-O0: @ %bb.0: @ %entry 926; CHECK-O0-NEXT: push {r7, lr} 927; CHECK-O0-NEXT: mov r7, sp 928; CHECK-O0-NEXT: bl _tailcallswifterror 929; CHECK-O0-NEXT: pop {r7, pc} 930; 931; CHECK-ANDROID-LABEL: tailcallswifterror: 932; CHECK-ANDROID: @ %bb.0: @ %entry 933; CHECK-ANDROID-NEXT: .save {r11, lr} 934; CHECK-ANDROID-NEXT: push {r11, lr} 935; CHECK-ANDROID-NEXT: bl tailcallswifterror 936; CHECK-ANDROID-NEXT: pop {r11, pc} 937entry: 938 %0 = tail call float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref) 939 ret float %0 940} 941define swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref) { 942; CHECK-APPLE-LABEL: tailcallswifterror_swiftcc: 943; CHECK-APPLE: @ %bb.0: @ %entry 944; CHECK-APPLE-NEXT: push {lr} 945; CHECK-APPLE-NEXT: bl _tailcallswifterror_swiftcc 946; CHECK-APPLE-NEXT: pop {lr} 947; CHECK-APPLE-NEXT: bx lr 948; 949; CHECK-O0-LABEL: tailcallswifterror_swiftcc: 950; CHECK-O0: @ %bb.0: @ %entry 951; CHECK-O0-NEXT: push {r7, lr} 952; CHECK-O0-NEXT: mov r7, sp 953; CHECK-O0-NEXT: bl _tailcallswifterror_swiftcc 954; CHECK-O0-NEXT: pop {r7, pc} 955; 956; CHECK-ANDROID-LABEL: tailcallswifterror_swiftcc: 957; CHECK-ANDROID: @ %bb.0: @ %entry 958; CHECK-ANDROID-NEXT: .save {r11, lr} 959; CHECK-ANDROID-NEXT: push {r11, lr} 960; CHECK-ANDROID-NEXT: bl tailcallswifterror_swiftcc 961; CHECK-ANDROID-NEXT: pop {r11, pc} 962entry: 963 %0 = tail call swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref) 964 ret float %0 965} 966 967define swiftcc void @swifterror_clobber(%swift_error** nocapture swifterror %err) { 968; CHECK-APPLE-LABEL: swifterror_clobber: 969; CHECK-APPLE: @ %bb.0: 970; CHECK-APPLE-NEXT: mov r0, r8 971; CHECK-APPLE-NEXT: @ InlineAsm Start 972; CHECK-APPLE-NEXT: nop 973; CHECK-APPLE-NEXT: @ InlineAsm End 974; CHECK-APPLE-NEXT: mov r8, r0 975; CHECK-APPLE-NEXT: bx lr 976; 977; CHECK-O0-LABEL: swifterror_clobber: 978; CHECK-O0: @ %bb.0: 979; CHECK-O0-NEXT: sub sp, sp, #4 980; CHECK-O0-NEXT: str r8, [sp] @ 4-byte Spill 981; CHECK-O0-NEXT: @ InlineAsm Start 982; CHECK-O0-NEXT: nop 983; CHECK-O0-NEXT: @ InlineAsm End 984; CHECK-O0-NEXT: ldr r8, [sp] @ 4-byte Reload 985; CHECK-O0-NEXT: add sp, sp, #4 986; CHECK-O0-NEXT: bx lr 987; 988; CHECK-ANDROID-LABEL: swifterror_clobber: 989; CHECK-ANDROID: @ %bb.0: 990; CHECK-ANDROID-NEXT: mov r0, r8 991; CHECK-ANDROID-NEXT: @APP 992; CHECK-ANDROID-NEXT: nop 993; CHECK-ANDROID-NEXT: @NO_APP 994; CHECK-ANDROID-NEXT: mov r8, r0 995; CHECK-ANDROID-NEXT: bx lr 996 call void asm sideeffect "nop", "~{r8}"() 997 ret void 998} 999 1000define swiftcc void @swifterror_reg_clobber(%swift_error** nocapture %err) { 1001; CHECK-APPLE-LABEL: swifterror_reg_clobber: 1002; CHECK-APPLE: @ %bb.0: 1003; CHECK-APPLE-NEXT: push {r8, lr} 1004; CHECK-APPLE-NEXT: @ InlineAsm Start 1005; CHECK-APPLE-NEXT: nop 1006; CHECK-APPLE-NEXT: @ InlineAsm End 1007; CHECK-APPLE-NEXT: pop {r8, pc} 1008; 1009; CHECK-O0-LABEL: swifterror_reg_clobber: 1010; CHECK-O0: @ %bb.0: 1011; CHECK-O0-NEXT: push {r7, lr} 1012; CHECK-O0-NEXT: mov r7, sp 1013; CHECK-O0-NEXT: push {r8} 1014; CHECK-O0-NEXT: @ InlineAsm Start 1015; CHECK-O0-NEXT: nop 1016; CHECK-O0-NEXT: @ InlineAsm End 1017; CHECK-O0-NEXT: pop {r8} 1018; CHECK-O0-NEXT: pop {r7, pc} 1019; 1020; CHECK-ANDROID-LABEL: swifterror_reg_clobber: 1021; CHECK-ANDROID: @ %bb.0: 1022; CHECK-ANDROID-NEXT: .save {r8, lr} 1023; CHECK-ANDROID-NEXT: push {r8, lr} 1024; CHECK-ANDROID-NEXT: @APP 1025; CHECK-ANDROID-NEXT: nop 1026; CHECK-ANDROID-NEXT: @NO_APP 1027; CHECK-ANDROID-NEXT: pop {r8, pc} 1028 call void asm sideeffect "nop", "~{r8}"() 1029 ret void 1030} 1031 1032define swiftcc void @params_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) { 1033; CHECK-APPLE-LABEL: params_in_reg: 1034; CHECK-APPLE: @ %bb.0: 1035; CHECK-APPLE-NEXT: push {r4, r5, r6, r7, r10, r11, lr} 1036; CHECK-APPLE-NEXT: add r7, sp, #20 1037; CHECK-APPLE-NEXT: sub sp, sp, #12 1038; CHECK-APPLE-NEXT: bfc sp, #0, #3 1039; CHECK-APPLE-NEXT: str r8, [sp, #4] @ 4-byte Spill 1040; CHECK-APPLE-NEXT: mov r6, r3 1041; CHECK-APPLE-NEXT: str r10, [sp] @ 4-byte Spill 1042; CHECK-APPLE-NEXT: mov r4, r2 1043; CHECK-APPLE-NEXT: mov r11, r1 1044; CHECK-APPLE-NEXT: mov r5, r0 1045; CHECK-APPLE-NEXT: mov r0, #1 1046; CHECK-APPLE-NEXT: mov r1, #2 1047; CHECK-APPLE-NEXT: mov r2, #3 1048; CHECK-APPLE-NEXT: mov r3, #4 1049; CHECK-APPLE-NEXT: mov r10, #0 1050; CHECK-APPLE-NEXT: mov r8, #0 1051; CHECK-APPLE-NEXT: bl _params_in_reg2 1052; CHECK-APPLE-NEXT: ldr r10, [sp] @ 4-byte Reload 1053; CHECK-APPLE-NEXT: mov r0, r5 1054; CHECK-APPLE-NEXT: ldr r8, [sp, #4] @ 4-byte Reload 1055; CHECK-APPLE-NEXT: mov r1, r11 1056; CHECK-APPLE-NEXT: mov r2, r4 1057; CHECK-APPLE-NEXT: mov r3, r6 1058; CHECK-APPLE-NEXT: bl _params_in_reg2 1059; CHECK-APPLE-NEXT: sub sp, r7, #20 1060; CHECK-APPLE-NEXT: pop {r4, r5, r6, r7, r10, r11, pc} 1061; 1062; CHECK-O0-LABEL: params_in_reg: 1063; CHECK-O0: @ %bb.0: 1064; CHECK-O0-NEXT: push {r7, lr} 1065; CHECK-O0-NEXT: mov r7, sp 1066; CHECK-O0-NEXT: push {r10} 1067; CHECK-O0-NEXT: sub sp, sp, #28 1068; CHECK-O0-NEXT: bfc sp, #0, #3 1069; CHECK-O0-NEXT: str r8, [sp, #20] @ 4-byte Spill 1070; CHECK-O0-NEXT: str r10, [sp] @ 4-byte Spill 1071; CHECK-O0-NEXT: str r3, [sp, #16] @ 4-byte Spill 1072; CHECK-O0-NEXT: str r2, [sp, #12] @ 4-byte Spill 1073; CHECK-O0-NEXT: str r1, [sp, #8] @ 4-byte Spill 1074; CHECK-O0-NEXT: str r0, [sp, #4] @ 4-byte Spill 1075; CHECK-O0-NEXT: @ implicit-def: $r0 1076; CHECK-O0-NEXT: mov r8, #0 1077; CHECK-O0-NEXT: mov r0, #1 1078; CHECK-O0-NEXT: mov r1, #2 1079; CHECK-O0-NEXT: mov r2, #3 1080; CHECK-O0-NEXT: mov r3, #4 1081; CHECK-O0-NEXT: mov r10, r8 1082; CHECK-O0-NEXT: bl _params_in_reg2 1083; CHECK-O0-NEXT: ldr r10, [sp] @ 4-byte Reload 1084; CHECK-O0-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 1085; CHECK-O0-NEXT: ldr r1, [sp, #8] @ 4-byte Reload 1086; CHECK-O0-NEXT: ldr r2, [sp, #12] @ 4-byte Reload 1087; CHECK-O0-NEXT: ldr r3, [sp, #16] @ 4-byte Reload 1088; CHECK-O0-NEXT: mov r9, r8 1089; CHECK-O0-NEXT: ldr r8, [sp, #20] @ 4-byte Reload 1090; CHECK-O0-NEXT: bl _params_in_reg2 1091; CHECK-O0-NEXT: sub sp, r7, #4 1092; CHECK-O0-NEXT: pop {r10} 1093; CHECK-O0-NEXT: pop {r7, pc} 1094; 1095; CHECK-ANDROID-LABEL: params_in_reg: 1096; CHECK-ANDROID: @ %bb.0: 1097; CHECK-ANDROID-NEXT: .save {r4, r5, r6, r7, r9, r10, r11, lr} 1098; CHECK-ANDROID-NEXT: push {r4, r5, r6, r7, r9, r10, r11, lr} 1099; CHECK-ANDROID-NEXT: .pad #8 1100; CHECK-ANDROID-NEXT: sub sp, sp, #8 1101; CHECK-ANDROID-NEXT: mov r9, r8 1102; CHECK-ANDROID-NEXT: mov r11, r10 1103; CHECK-ANDROID-NEXT: mov r6, r3 1104; CHECK-ANDROID-NEXT: mov r7, r2 1105; CHECK-ANDROID-NEXT: mov r4, r1 1106; CHECK-ANDROID-NEXT: mov r5, r0 1107; CHECK-ANDROID-NEXT: mov r0, #1 1108; CHECK-ANDROID-NEXT: mov r1, #2 1109; CHECK-ANDROID-NEXT: mov r2, #3 1110; CHECK-ANDROID-NEXT: mov r3, #4 1111; CHECK-ANDROID-NEXT: mov r10, #0 1112; CHECK-ANDROID-NEXT: mov r8, #0 1113; CHECK-ANDROID-NEXT: bl params_in_reg2 1114; CHECK-ANDROID-NEXT: mov r0, r5 1115; CHECK-ANDROID-NEXT: mov r1, r4 1116; CHECK-ANDROID-NEXT: mov r2, r7 1117; CHECK-ANDROID-NEXT: mov r3, r6 1118; CHECK-ANDROID-NEXT: mov r10, r11 1119; CHECK-ANDROID-NEXT: mov r8, r9 1120; CHECK-ANDROID-NEXT: bl params_in_reg2 1121; CHECK-ANDROID-NEXT: add sp, sp, #8 1122; CHECK-ANDROID-NEXT: pop {r4, r5, r6, r7, r9, r10, r11, pc} 1123 %error_ptr_ref = alloca swifterror %swift_error*, align 8 1124 store %swift_error* null, %swift_error** %error_ptr_ref 1125 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref) 1126 call swiftcc void @params_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err) 1127 ret void 1128} 1129declare swiftcc void @params_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) 1130 1131define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) { 1132; CHECK-APPLE-LABEL: params_and_return_in_reg: 1133; CHECK-APPLE: @ %bb.0: 1134; CHECK-APPLE-NEXT: push {r4, r5, r6, r7, r10, r11, lr} 1135; CHECK-APPLE-NEXT: add r7, sp, #20 1136; CHECK-APPLE-NEXT: sub sp, sp, #20 1137; CHECK-APPLE-NEXT: bfc sp, #0, #3 1138; CHECK-APPLE-NEXT: mov r6, r8 1139; CHECK-APPLE-NEXT: str r10, [sp, #12] @ 4-byte Spill 1140; CHECK-APPLE-NEXT: str r3, [sp, #8] @ 4-byte Spill 1141; CHECK-APPLE-NEXT: mov r4, r2 1142; CHECK-APPLE-NEXT: mov r11, r1 1143; CHECK-APPLE-NEXT: mov r5, r0 1144; CHECK-APPLE-NEXT: mov r0, #1 1145; CHECK-APPLE-NEXT: mov r1, #2 1146; CHECK-APPLE-NEXT: mov r2, #3 1147; CHECK-APPLE-NEXT: mov r3, #4 1148; CHECK-APPLE-NEXT: mov r10, #0 1149; CHECK-APPLE-NEXT: mov r8, #0 1150; CHECK-APPLE-NEXT: bl _params_in_reg2 1151; CHECK-APPLE-NEXT: ldr r3, [sp, #8] @ 4-byte Reload 1152; CHECK-APPLE-NEXT: mov r0, r5 1153; CHECK-APPLE-NEXT: ldr r10, [sp, #12] @ 4-byte Reload 1154; CHECK-APPLE-NEXT: mov r1, r11 1155; CHECK-APPLE-NEXT: str r8, [sp, #4] @ 4-byte Spill 1156; CHECK-APPLE-NEXT: mov r2, r4 1157; CHECK-APPLE-NEXT: mov r8, r6 1158; CHECK-APPLE-NEXT: bl _params_and_return_in_reg2 1159; CHECK-APPLE-NEXT: str r8, [sp, #12] @ 4-byte Spill 1160; CHECK-APPLE-NEXT: mov r4, r0 1161; CHECK-APPLE-NEXT: ldr r8, [sp, #4] @ 4-byte Reload 1162; CHECK-APPLE-NEXT: mov r5, r1 1163; CHECK-APPLE-NEXT: mov r6, r2 1164; CHECK-APPLE-NEXT: mov r11, r3 1165; CHECK-APPLE-NEXT: mov r0, #1 1166; CHECK-APPLE-NEXT: mov r1, #2 1167; CHECK-APPLE-NEXT: mov r2, #3 1168; CHECK-APPLE-NEXT: mov r3, #4 1169; CHECK-APPLE-NEXT: mov r10, #0 1170; CHECK-APPLE-NEXT: bl _params_in_reg2 1171; CHECK-APPLE-NEXT: mov r0, r4 1172; CHECK-APPLE-NEXT: mov r1, r5 1173; CHECK-APPLE-NEXT: mov r2, r6 1174; CHECK-APPLE-NEXT: mov r3, r11 1175; CHECK-APPLE-NEXT: ldr r8, [sp, #12] @ 4-byte Reload 1176; CHECK-APPLE-NEXT: sub sp, r7, #20 1177; CHECK-APPLE-NEXT: pop {r4, r5, r6, r7, r10, r11, pc} 1178; 1179; CHECK-O0-LABEL: params_and_return_in_reg: 1180; CHECK-O0: @ %bb.0: 1181; CHECK-O0-NEXT: push {r7, lr} 1182; CHECK-O0-NEXT: mov r7, sp 1183; CHECK-O0-NEXT: push {r10} 1184; CHECK-O0-NEXT: sub sp, sp, #76 1185; CHECK-O0-NEXT: bfc sp, #0, #3 1186; CHECK-O0-NEXT: str r8, [sp, #24] @ 4-byte Spill 1187; CHECK-O0-NEXT: str r10, [sp, #4] @ 4-byte Spill 1188; CHECK-O0-NEXT: str r3, [sp, #20] @ 4-byte Spill 1189; CHECK-O0-NEXT: str r2, [sp, #16] @ 4-byte Spill 1190; CHECK-O0-NEXT: str r1, [sp, #12] @ 4-byte Spill 1191; CHECK-O0-NEXT: str r0, [sp, #8] @ 4-byte Spill 1192; CHECK-O0-NEXT: @ implicit-def: $r0 1193; CHECK-O0-NEXT: mov r8, #0 1194; CHECK-O0-NEXT: str r8, [sp, #28] @ 4-byte Spill 1195; CHECK-O0-NEXT: mov r0, #1 1196; CHECK-O0-NEXT: str r0, [sp, #32] @ 4-byte Spill 1197; CHECK-O0-NEXT: mov r1, #2 1198; CHECK-O0-NEXT: str r1, [sp, #36] @ 4-byte Spill 1199; CHECK-O0-NEXT: mov r2, #3 1200; CHECK-O0-NEXT: str r2, [sp, #40] @ 4-byte Spill 1201; CHECK-O0-NEXT: mov r3, #4 1202; CHECK-O0-NEXT: str r3, [sp, #44] @ 4-byte Spill 1203; CHECK-O0-NEXT: mov r10, r8 1204; CHECK-O0-NEXT: bl _params_in_reg2 1205; CHECK-O0-NEXT: ldr r10, [sp, #4] @ 4-byte Reload 1206; CHECK-O0-NEXT: ldr r0, [sp, #8] @ 4-byte Reload 1207; CHECK-O0-NEXT: ldr r1, [sp, #12] @ 4-byte Reload 1208; CHECK-O0-NEXT: ldr r2, [sp, #16] @ 4-byte Reload 1209; CHECK-O0-NEXT: ldr r3, [sp, #20] @ 4-byte Reload 1210; CHECK-O0-NEXT: mov r9, r8 1211; CHECK-O0-NEXT: ldr r8, [sp, #24] @ 4-byte Reload 1212; CHECK-O0-NEXT: str r9, [sp, #48] @ 4-byte Spill 1213; CHECK-O0-NEXT: bl _params_and_return_in_reg2 1214; CHECK-O0-NEXT: ldr r10, [sp, #28] @ 4-byte Reload 1215; CHECK-O0-NEXT: mov r9, r0 1216; CHECK-O0-NEXT: ldr r0, [sp, #32] @ 4-byte Reload 1217; CHECK-O0-NEXT: str r9, [sp, #52] @ 4-byte Spill 1218; CHECK-O0-NEXT: mov r9, r1 1219; CHECK-O0-NEXT: ldr r1, [sp, #36] @ 4-byte Reload 1220; CHECK-O0-NEXT: str r9, [sp, #56] @ 4-byte Spill 1221; CHECK-O0-NEXT: mov r9, r2 1222; CHECK-O0-NEXT: ldr r2, [sp, #40] @ 4-byte Reload 1223; CHECK-O0-NEXT: str r9, [sp, #60] @ 4-byte Spill 1224; CHECK-O0-NEXT: mov r9, r3 1225; CHECK-O0-NEXT: ldr r3, [sp, #44] @ 4-byte Reload 1226; CHECK-O0-NEXT: str r9, [sp, #64] @ 4-byte Spill 1227; CHECK-O0-NEXT: mov r9, r8 1228; CHECK-O0-NEXT: ldr r8, [sp, #48] @ 4-byte Reload 1229; CHECK-O0-NEXT: str r9, [sp, #68] @ 4-byte Spill 1230; CHECK-O0-NEXT: bl _params_in_reg2 1231; CHECK-O0-NEXT: ldr r0, [sp, #52] @ 4-byte Reload 1232; CHECK-O0-NEXT: ldr r1, [sp, #56] @ 4-byte Reload 1233; CHECK-O0-NEXT: ldr r2, [sp, #60] @ 4-byte Reload 1234; CHECK-O0-NEXT: ldr r3, [sp, #64] @ 4-byte Reload 1235; CHECK-O0-NEXT: mov r9, r8 1236; CHECK-O0-NEXT: ldr r8, [sp, #68] @ 4-byte Reload 1237; CHECK-O0-NEXT: sub sp, r7, #4 1238; CHECK-O0-NEXT: pop {r10} 1239; CHECK-O0-NEXT: pop {r7, pc} 1240; 1241; CHECK-ANDROID-LABEL: params_and_return_in_reg: 1242; CHECK-ANDROID: @ %bb.0: 1243; CHECK-ANDROID-NEXT: .save {r4, r5, r6, r7, r9, r10, r11, lr} 1244; CHECK-ANDROID-NEXT: push {r4, r5, r6, r7, r9, r10, r11, lr} 1245; CHECK-ANDROID-NEXT: .pad #16 1246; CHECK-ANDROID-NEXT: sub sp, sp, #16 1247; CHECK-ANDROID-NEXT: str r8, [sp, #4] @ 4-byte Spill 1248; CHECK-ANDROID-NEXT: mov r11, r10 1249; CHECK-ANDROID-NEXT: mov r6, r3 1250; CHECK-ANDROID-NEXT: mov r7, r2 1251; CHECK-ANDROID-NEXT: mov r4, r1 1252; CHECK-ANDROID-NEXT: mov r5, r0 1253; CHECK-ANDROID-NEXT: mov r0, #1 1254; CHECK-ANDROID-NEXT: mov r1, #2 1255; CHECK-ANDROID-NEXT: mov r2, #3 1256; CHECK-ANDROID-NEXT: mov r3, #4 1257; CHECK-ANDROID-NEXT: mov r10, #0 1258; CHECK-ANDROID-NEXT: mov r8, #0 1259; CHECK-ANDROID-NEXT: bl params_in_reg2 1260; CHECK-ANDROID-NEXT: mov r9, r8 1261; CHECK-ANDROID-NEXT: ldr r8, [sp, #4] @ 4-byte Reload 1262; CHECK-ANDROID-NEXT: mov r0, r5 1263; CHECK-ANDROID-NEXT: mov r1, r4 1264; CHECK-ANDROID-NEXT: mov r2, r7 1265; CHECK-ANDROID-NEXT: mov r3, r6 1266; CHECK-ANDROID-NEXT: mov r10, r11 1267; CHECK-ANDROID-NEXT: bl params_and_return_in_reg2 1268; CHECK-ANDROID-NEXT: mov r4, r0 1269; CHECK-ANDROID-NEXT: mov r5, r1 1270; CHECK-ANDROID-NEXT: mov r6, r2 1271; CHECK-ANDROID-NEXT: mov r7, r3 1272; CHECK-ANDROID-NEXT: mov r11, r8 1273; CHECK-ANDROID-NEXT: mov r0, #1 1274; CHECK-ANDROID-NEXT: mov r1, #2 1275; CHECK-ANDROID-NEXT: mov r2, #3 1276; CHECK-ANDROID-NEXT: mov r3, #4 1277; CHECK-ANDROID-NEXT: mov r10, #0 1278; CHECK-ANDROID-NEXT: mov r8, r9 1279; CHECK-ANDROID-NEXT: bl params_in_reg2 1280; CHECK-ANDROID-NEXT: mov r0, r4 1281; CHECK-ANDROID-NEXT: mov r1, r5 1282; CHECK-ANDROID-NEXT: mov r2, r6 1283; CHECK-ANDROID-NEXT: mov r3, r7 1284; CHECK-ANDROID-NEXT: mov r8, r11 1285; CHECK-ANDROID-NEXT: add sp, sp, #16 1286; CHECK-ANDROID-NEXT: pop {r4, r5, r6, r7, r9, r10, r11, pc} 1287 %error_ptr_ref = alloca swifterror %swift_error*, align 8 1288 store %swift_error* null, %swift_error** %error_ptr_ref 1289 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref) 1290 %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) 1291 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref) 1292 ret { i32, i32, i32, i32 }%val 1293} 1294 1295declare swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) 1296 1297 1298declare void @acallee(i8*) 1299 1300; Make sure we don't tail call if the caller returns a swifterror value. We 1301; would have to move into the swifterror register before the tail call. 1302define swiftcc void @tailcall_from_swifterror(%swift_error** swifterror %error_ptr_ref) { 1303; CHECK-APPLE-LABEL: tailcall_from_swifterror: 1304; CHECK-APPLE: @ %bb.0: @ %entry 1305; CHECK-APPLE-NEXT: push {r4, lr} 1306; CHECK-APPLE-NEXT: mov r0, #0 1307; CHECK-APPLE-NEXT: mov r4, r8 1308; CHECK-APPLE-NEXT: bl _acallee 1309; CHECK-APPLE-NEXT: mov r8, r4 1310; CHECK-APPLE-NEXT: pop {r4, pc} 1311; 1312; CHECK-O0-LABEL: tailcall_from_swifterror: 1313; CHECK-O0: @ %bb.0: @ %entry 1314; CHECK-O0-NEXT: push {r7, lr} 1315; CHECK-O0-NEXT: mov r7, sp 1316; CHECK-O0-NEXT: sub sp, sp, #4 1317; CHECK-O0-NEXT: str r8, [sp] @ 4-byte Spill 1318; CHECK-O0-NEXT: mov r0, #0 1319; CHECK-O0-NEXT: bl _acallee 1320; CHECK-O0-NEXT: ldr r8, [sp] @ 4-byte Reload 1321; CHECK-O0-NEXT: mov sp, r7 1322; CHECK-O0-NEXT: pop {r7, pc} 1323; 1324; CHECK-ANDROID-LABEL: tailcall_from_swifterror: 1325; CHECK-ANDROID: @ %bb.0: @ %entry 1326; CHECK-ANDROID-NEXT: .save {r4, lr} 1327; CHECK-ANDROID-NEXT: push {r4, lr} 1328; CHECK-ANDROID-NEXT: mov r0, #0 1329; CHECK-ANDROID-NEXT: mov r4, r8 1330; CHECK-ANDROID-NEXT: bl acallee 1331; CHECK-ANDROID-NEXT: mov r8, r4 1332; CHECK-ANDROID-NEXT: pop {r4, pc} 1333entry: 1334 tail call void @acallee(i8* null) 1335 ret void 1336} 1337 1338 1339declare swiftcc void @foo2(%swift_error** swifterror) 1340 1341; Make sure we properly assign registers during fast-isel. 1342define swiftcc %swift_error* @testAssign(i8* %error_ref) { 1343; CHECK-APPLE-LABEL: testAssign: 1344; CHECK-APPLE: @ %bb.0: @ %entry 1345; CHECK-APPLE-NEXT: push {r8, lr} 1346; CHECK-APPLE-NEXT: sub sp, sp, #4 1347; CHECK-APPLE-NEXT: mov r8, #0 1348; CHECK-APPLE-NEXT: bl _foo2 1349; CHECK-APPLE-NEXT: mov r0, r8 1350; CHECK-APPLE-NEXT: add sp, sp, #4 1351; CHECK-APPLE-NEXT: pop {r8, pc} 1352; 1353; CHECK-O0-LABEL: testAssign: 1354; CHECK-O0: @ %bb.0: @ %entry 1355; CHECK-O0-NEXT: push {r7, lr} 1356; CHECK-O0-NEXT: mov r7, sp 1357; CHECK-O0-NEXT: push {r8} 1358; CHECK-O0-NEXT: sub sp, sp, #8 1359; CHECK-O0-NEXT: @ implicit-def: $r1 1360; CHECK-O0-NEXT: mov r8, #0 1361; CHECK-O0-NEXT: bl _foo2 1362; CHECK-O0-NEXT: str r8, [sp] @ 4-byte Spill 1363; CHECK-O0-NEXT: @ %bb.1: @ %a 1364; CHECK-O0-NEXT: ldr r0, [sp] @ 4-byte Reload 1365; CHECK-O0-NEXT: sub sp, r7, #4 1366; CHECK-O0-NEXT: pop {r8} 1367; CHECK-O0-NEXT: pop {r7, pc} 1368; 1369; CHECK-ANDROID-LABEL: testAssign: 1370; CHECK-ANDROID: @ %bb.0: @ %entry 1371; CHECK-ANDROID-NEXT: .save {r8, lr} 1372; CHECK-ANDROID-NEXT: push {r8, lr} 1373; CHECK-ANDROID-NEXT: .pad #8 1374; CHECK-ANDROID-NEXT: sub sp, sp, #8 1375; CHECK-ANDROID-NEXT: mov r8, #0 1376; CHECK-ANDROID-NEXT: bl foo2 1377; CHECK-ANDROID-NEXT: mov r0, r8 1378; CHECK-ANDROID-NEXT: add sp, sp, #8 1379; CHECK-ANDROID-NEXT: pop {r8, pc} 1380entry: 1381 %error_ptr = alloca swifterror %swift_error* 1382 store %swift_error* null, %swift_error** %error_ptr 1383 call swiftcc void @foo2(%swift_error** swifterror %error_ptr) 1384 br label %a 1385 1386a: 1387 %error = load %swift_error*, %swift_error** %error_ptr 1388 ret %swift_error* %error 1389} 1390