brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.4 KiB · 78fc6cc Raw
566 lines · plain
1; RUN: llc -verify-machineinstrs -frame-pointer=all -global-isel < %s -mtriple=aarch64-apple-ios | FileCheck %s2 3declare ptr @malloc(i64)4declare void @free(ptr)5%swift_error = type {i64, i8}6 7; This tests the basic usage of a swifterror parameter. "foo" is the function8; that takes a swifterror parameter and "caller" is the caller of "foo".9define float @foo(ptr swifterror %error_ptr_ref) {10; CHECK-LABEL: foo:11; CHECK: mov w0, #1612; CHECK: malloc13; CHECK: mov [[ID:w[0-9]+]], #114; CHECK: mov x21, x015; CHECK: strb [[ID]], [x0, #8]16; CHECK-NOT: x2117 18entry:19  %call = call ptr @malloc(i64 16)20  store ptr %call, ptr %error_ptr_ref21  %tmp = getelementptr inbounds i8, ptr %call, i64 822  store i8 1, ptr %tmp23  ret float 1.024}25 26; "caller" calls "foo" that takes a swifterror parameter.27define float @caller(ptr %error_ref) {28; CHECK-LABEL: caller:29; CHECK: mov [[ID:x[0-9]+]], x030; CHECK: bl {{.*}}foo31; CHECK: mov x0, x2132; CHECK: cbnz x2133; Access part of the error object and save it to error_ref34; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]35; CHECK: strb [[CODE]], [{{.*}}[[ID]]]36; CHECK: bl {{.*}}free37 38entry:39  %error_ptr_ref = alloca swifterror ptr40  store ptr null, ptr %error_ptr_ref41  %call = call float @foo(ptr swifterror %error_ptr_ref)42  %error_from_foo = load ptr, ptr %error_ptr_ref43  %had_error_from_foo = icmp ne ptr %error_from_foo, null44  br i1 %had_error_from_foo, label %handler, label %cont45cont:46  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 147  %t = load i8, ptr %v148  store i8 %t, ptr %error_ref49  br label %handler50handler:51  call void @free(ptr %error_from_foo)52  ret float 1.053}54 55; "caller2" is the caller of "foo", it calls "foo" inside a loop.56define float @caller2(ptr %error_ref) {57; CHECK-LABEL: caller2:58; CHECK: fmov [[CMP:s[0-9]+]], #1.059; CHECK: mov [[ID:x[0-9]+]], x060; CHECK: mov x21, xzr61; CHECK: bl {{.*}}foo62; CHECK: cbnz x2163; CHECK: fcmp s0, [[CMP]]64; CHECK: b.le65; Access part of the error object and save it to error_ref66; CHECK: ldrb [[CODE:w[0-9]+]], [x21, #8]67; CHECK: strb [[CODE]], [{{.*}}[[ID]]]68; CHECK: mov x0, x2169; CHECK: bl {{.*}}free70 71entry:72  %error_ptr_ref = alloca swifterror ptr73  br label %bb_loop74bb_loop:75  store ptr null, ptr %error_ptr_ref76  %call = call float @foo(ptr swifterror %error_ptr_ref)77  %error_from_foo = load ptr, ptr %error_ptr_ref78  %had_error_from_foo = icmp ne ptr %error_from_foo, null79  br i1 %had_error_from_foo, label %handler, label %cont80cont:81  %cmp = fcmp ogt float %call, 1.000000e+0082  br i1 %cmp, label %bb_end, label %bb_loop83bb_end:84  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 185  %t = load i8, ptr %v186  store i8 %t, ptr %error_ref87  br label %handler88handler:89  call void @free(ptr %error_from_foo)90  ret float 1.091}92 93; "foo_if" is a function that takes a swifterror parameter, it sets swifterror94; under a certain condition.95define float @foo_if(ptr swifterror %error_ptr_ref, i32 %cc) {96; CHECK-LABEL: foo_if:97; CHECK: cbz w098; CHECK: mov w0, #1699; CHECK: malloc100; CHECK-DAG: mov x21, x0101; CHECK-DAG: mov [[ID:w[0-9]+]], #1102; CHECK: strb [[ID]], [x0, #8]103; CHECK-NOT: x21104; CHECK: ret105 106entry:107  %cond = icmp ne i32 %cc, 0108  br i1 %cond, label %gen_error, label %normal109 110gen_error:111  %call = call ptr @malloc(i64 16)112  store ptr %call, ptr %error_ptr_ref113  %tmp = getelementptr inbounds i8, ptr %call, i64 8114  store i8 1, ptr %tmp115  ret float 1.0116 117normal:118  ret float 0.0119}120 121; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror122; under a certain condition inside a loop.123define float @foo_loop(ptr swifterror %error_ptr_ref, i32 %cc, float %cc2) {124; CHECK-LABEL: foo_loop:125; CHECK: cbz126; CHECK: mov w0, #16127; CHECK: malloc128; CHECK: mov x21, x0129; CHECK: strb w{{.*}}, [x0, #8]130; CHECK: ret131 132entry:133  br label %bb_loop134 135bb_loop:136  %cond = icmp ne i32 %cc, 0137  br i1 %cond, label %gen_error, label %bb_cont138 139gen_error:140  %call = call ptr @malloc(i64 16)141  store ptr %call, ptr %error_ptr_ref142  %tmp = getelementptr inbounds i8, ptr %call, i64 8143  store i8 1, ptr %tmp144  br label %bb_cont145 146bb_cont:147  %cmp = fcmp ogt float %cc2, 1.000000e+00148  br i1 %cmp, label %bb_end, label %bb_loop149bb_end:150  ret float 0.0151}152 153%struct.S = type { i32, i32, i32, i32, i32, i32 }154 155; "foo_sret" is a function that takes a swifterror parameter, it also has a sret156; parameter.157define void @foo_sret(ptr sret(%struct.S) %agg.result, i32 %val1, ptr swifterror %error_ptr_ref) {158; CHECK-LABEL: foo_sret:159; CHECK-DAG: mov [[SRET:x[0-9]+]], x8160; CHECK-DAG: mov w0, #16161; CHECK: malloc162; CHECK: mov [[ID:w[0-9]+]], #1163; CHECK: strb [[ID]], [x0, #8]164; CHECK: mov x21, x0165; CHECK: str w{{.*}}, [{{.*}}[[SRET]], #4]166; CHECK-NOT: x21167 168entry:169  %call = call ptr @malloc(i64 16)170  store ptr %call, ptr %error_ptr_ref171  %tmp = getelementptr inbounds i8, ptr %call, i64 8172  store i8 1, ptr %tmp173  %v2 = getelementptr inbounds %struct.S, ptr %agg.result, i32 0, i32 1174  store i32 %val1, ptr %v2175  ret void176}177 178; "caller3" calls "foo_sret" that takes a swifterror parameter.179define float @caller3(ptr %error_ref) {180; CHECK-LABEL: caller3:181; CHECK: mov [[ID:x[0-9]+]], x0182; CHECK: mov [[ZERO:x[0-9]+]], xzr183; CHECK: bl {{.*}}foo_sret184; CHECK: mov x0, x21185; CHECK: cbnz x21186; Access part of the error object and save it to error_ref187; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]188; CHECK: strb [[CODE]], [{{.*}}[[ID]]]189; CHECK: bl {{.*}}free190 191entry:192  %s = alloca %struct.S, align 8193  %error_ptr_ref = alloca swifterror ptr194  store ptr null, ptr %error_ptr_ref195  call void @foo_sret(ptr sret(%struct.S) %s, i32 1, ptr swifterror %error_ptr_ref)196  %error_from_foo = load ptr, ptr %error_ptr_ref197  %had_error_from_foo = icmp ne ptr %error_from_foo, null198  br i1 %had_error_from_foo, label %handler, label %cont199cont:200  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1201  %t = load i8, ptr %v1202  store i8 %t, ptr %error_ref203  br label %handler204handler:205  call void @free(ptr %error_from_foo)206  ret float 1.0207}208 209; "foo_vararg" is a function that takes a swifterror parameter, it also has210; variable number of arguments.211declare void @llvm.va_start(ptr) nounwind212define float @foo_vararg(ptr swifterror %error_ptr_ref, ...) {213; CHECK-LABEL: foo_vararg:214; CHECK: mov w0, #16215; CHECK: malloc216; CHECK: mov [[ID:w[0-9]+]], #1217; CHECK: strb [[ID]], [x0, #8]218; CHECK: mov x21, x0219; CHECK-NOT: x21220 221; First vararg222; CHECK: ldr {{w[0-9]+}}, [x[[ARG1:[0-9]+]]]223; CHECK-NOT: x21224; Second vararg225; CHECK: ldr {{w[0-9]+}}, [x[[ARG1]]]226; CHECK-NOT: x21227; Third vararg228; CHECK: ldr {{w[0-9]+}}, [x[[ARG1]]]229; CHECK-NOT: x21230entry:231  %call = call ptr @malloc(i64 16)232  store ptr %call, ptr %error_ptr_ref233  %tmp = getelementptr inbounds i8, ptr %call, i64 8234  store i8 1, ptr %tmp235 236  %args = alloca ptr, align 8237  %a10 = alloca i32, align 4238  %a11 = alloca i32, align 4239  %a12 = alloca i32, align 4240  call void @llvm.va_start(ptr %args)241  %v11 = va_arg ptr %args, i32242  store i32 %v11, ptr %a10, align 4243  %v12 = va_arg ptr %args, i32244  store i32 %v12, ptr %a11, align 4245  %v13 = va_arg ptr %args, i32246  store i32 %v13, ptr %a12, align 4247 248  ret float 1.0249}250 251; "caller4" calls "foo_vararg" that takes a swifterror parameter.252define float @caller4(ptr %error_ref) {253; CHECK-LABEL: caller4:254 255; CHECK: mov x21, xzr256; CHECK: mov [[ID:x[0-9]+]], x0257; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp]258; CHECK: str {{x[0-9]+}}, [sp, #16]259 260; CHECK: bl {{.*}}foo_vararg261; CHECK: mov x0, x21262; CHECK: cbnz x21263; Access part of the error object and save it to error_ref264; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]265; CHECK: strb [[CODE]], [{{.*}}[[ID]]]266; CHECK: bl {{.*}}free267entry:268  %error_ptr_ref = alloca swifterror ptr269  store ptr null, ptr %error_ptr_ref270 271  %a10 = alloca i32, align 4272  %a11 = alloca i32, align 4273  %a12 = alloca i32, align 4274  store i32 10, ptr %a10, align 4275  store i32 11, ptr %a11, align 4276  store i32 12, ptr %a12, align 4277  %v10 = load i32, ptr %a10, align 4278  %v11 = load i32, ptr %a11, align 4279  %v12 = load i32, ptr %a12, align 4280 281  %call = call float (ptr, ...) @foo_vararg(ptr swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12)282  %error_from_foo = load ptr, ptr %error_ptr_ref283  %had_error_from_foo = icmp ne ptr %error_from_foo, null284  br i1 %had_error_from_foo, label %handler, label %cont285 286cont:287  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1288  %t = load i8, ptr %v1289  store i8 %t, ptr %error_ref290  br label %handler291handler:292  call void @free(ptr %error_from_foo)293  ret float 1.0294}295 296; Check that we don't blow up on tail calling swifterror argument functions.297define float @tailcallswifterror(ptr swifterror %error_ptr_ref) {298entry:299  %0 = tail call float @tailcallswifterror(ptr swifterror %error_ptr_ref)300  ret float %0301}302define swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref) {303entry:304  %0 = tail call swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref)305  ret float %0306}307 308; CHECK-LABEL: params_in_reg309; Save callee saved registers and swifterror since it will be clobbered by the first call to params_in_reg2.310; CHECK:  str     x28, [sp311; CHECK:  stp     x27, x26, [sp312; CHECK:  stp     x25, x24, [sp313; CHECK:  stp     x23, x22, [sp314; CHECK:  stp     x20, x19, [sp315; CHECK:  stp     x29, x30, [sp316; Store argument registers.317; CHECK:  mov      x20, x1318; CHECK:  mov      x22, x2319; CHECK:  mov      x23, x3320; CHECK:  mov      x24, x4321; CHECK:  mov      x25, x5322; CHECK:  mov      x26, x6323; CHECK:  mov      x27, x7324; CHECK:  mov      x28, x21325; Setup call.326; CHECK:  mov     w0, #1327; CHECK:  mov     w1, #2328; CHECK:  mov     w2, #3329; CHECK:  mov     w3, #4330; CHECK:  mov     w4, #5331; CHECK:  mov     w5, #6332; CHECK:  mov     w6, #7333; CHECK:  mov     w7, #8334; CHECK:  mov      x21, xzr335; CHECK:  str     xzr, [sp]336; CHECK:  bl      _params_in_reg2337; Restore original arguments for next call.338; CHECK:  ldr     x8, [sp, #24]339; CHECK:  mov      x1, x20340; CHECK:  mov      x2, x22341; CHECK:  mov      x3, x23342; CHECK:  mov      x4, x24343; CHECK:  mov      x5, x25344; CHECK:  mov      x6, x26345; CHECK:  mov      x7, x27346; Restore original swiftself argument and swifterror %err.347; CHECK:  mov      x21, x28348; CHECK:  bl      _params_in_reg2349; Restore calle save registers but don't clober swifterror x21.350; CHECK-NOT: x21351; CHECK:  ldp     x29, x30, [sp352; CHECK-NOT: x21353; CHECK:  ldr     x28, [sp354; CHECK-NOT: x21355; CHECK:  ldp     x20, x19, [sp356; CHECK-NOT: x21357; CHECK:  ldp     x23, x22, [sp358; CHECK-NOT: x21359; CHECK:  ldp     x25, x24, [sp360; CHECK-NOT: x21361; CHECK:  ldp     x27, x26, [sp362; CHECK-NOT: x21363; CHECK:  ret364define swiftcc void @params_in_reg(i64, i64, i64, i64, i64, i64, i64, i64, ptr, ptr nocapture swifterror %err) {365  %error_ptr_ref = alloca swifterror ptr, align 8366  store ptr null, ptr %error_ptr_ref367  call swiftcc void @params_in_reg2(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, ptr  null, ptr nocapture swifterror %error_ptr_ref)368  call swiftcc void @params_in_reg2(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, i64 %7, ptr  %8, ptr nocapture swifterror %err)369  ret void370}371declare swiftcc void @params_in_reg2(i64, i64, i64, i64, i64, i64, i64, i64, ptr , ptr nocapture swifterror %err)372 373; CHECK-LABEL: params_and_return_in_reg374; Store callee saved registers.375; CHECK:  stp     x28, x0, [sp, #16376; CHECK:  stp     x27, x26, [sp377; CHECK:  stp     x25, x24, [sp378; CHECK:  stp     x23, x22, [sp379; CHECK:  stp     x20, x19, [sp380; CHECK:  stp     x29, x30, [sp381; Save original arguments.382; CHECK:  mov      x20, x1383; CHECK:  mov      x22, x2384; CHECK:  mov      x23, x3385; CHECK:  mov      x24, x4386; CHECK:  mov      x25, x5387; CHECK:  mov      x26, x6388; CHECK:  mov      x27, x7389; Setup call arguments.390; CHECK:  mov     w0, #1391; CHECK:  mov     w1, #2392; CHECK:  mov     w2, #3393; CHECK:  mov     w3, #4394; CHECK:  mov     w4, #5395; CHECK:  mov     w5, #6396; CHECK:  mov     w6, #7397; CHECK:  mov     w7, #8398; CHECK:  mov      x21, xzr399; CHECK:  bl      _params_in_reg2400; Store swifterror %error_ptr_ref.401; CHECK:  ldr     x0, [sp, #24]402; CHECK:  stp     {{x[0-9]+}}, x21, [sp]403; Setup call arguments from original arguments.404; CHECK:  mov      x1, x20405; CHECK:  mov      x2, x22406; CHECK:  mov      x3, x23407; CHECK:  mov      x4, x24408; CHECK:  mov      x5, x25409; CHECK:  mov      x6, x26410; CHECK:  mov      x7, x27411; CHECK:  mov      x21, x28412; CHECK:  bl      _params_and_return_in_reg2413; CHECK:  mov      x19, x21414; CHECK:  ldr      x21, [sp, #8415; Store return values.416; CHECK:  mov     x20, x0417; CHECK:  mov     x22, x1418; CHECK:  mov     x23, x2419; CHECK:  mov     x24, x3420; CHECK:  mov     x25, x4421; CHECK:  mov     x26, x5422; CHECK:  mov     x27, x6423; CHECK:  mov     x28, x7424; Setup call.425; CHECK:  mov     w0, #1426; CHECK:  mov     w1, #2427; CHECK:  mov     w2, #3428; CHECK:  mov     w3, #4429; CHECK:  mov     w4, #5430; CHECK:  mov     w5, #6431; CHECK:  mov     w6, #7432; CHECK:  mov     w7, #8433; CHECK:  str     xzr, [sp]434; CHECK:  bl      _params_in_reg2435; Restore return values for return from this function.436; CHECK:  mov     x0, x20437; CHECK:  mov     x1, x22438; CHECK:  mov     x2, x23439; CHECK:  mov     x3, x24440; CHECK:  mov     x4, x25441; CHECK:  mov     x5, x26442; CHECK:  mov     x6, x27443; CHECK:  mov     x21, x19444; CHECK:  mov     x7, x28445; CHECK:  ldp     x29, x30, [sp, #96]             ; 16-byte Folded Reload446; CHECK:  ldr     x28, [sp, #16]                  ; 8-byte Reload447; CHECK:  ldp     x20, x19, [sp, #80]             ; 16-byte Folded Reload448; CHECK:  ldp     x23, x22, [sp, #64]             ; 16-byte Folded Reload449; CHECK:  ldp     x25, x24, [sp, #48]             ; 16-byte Folded Reload450; CHECK:  ldp     x27, x26, [sp, #32]             ; 16-byte Folded Reload451; CHECK:  add     sp, sp, #112452; CHECK:  ret453define swiftcc { i64, i64, i64, i64, i64, i64, i64, i64 } @params_and_return_in_reg(i64, i64, i64, i64, i64, i64, i64, i64, ptr , ptr nocapture swifterror %err) {454  %error_ptr_ref = alloca swifterror ptr, align 8455  store ptr null, ptr %error_ptr_ref456  call swiftcc void @params_in_reg2(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, ptr  null, ptr nocapture swifterror %error_ptr_ref)457  %val = call swiftcc  { i64, i64, i64, i64, i64, i64, i64, i64 } @params_and_return_in_reg2(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, i64 %7, ptr  %8, ptr nocapture swifterror %err)458  call swiftcc void @params_in_reg2(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, ptr  null, ptr nocapture swifterror %error_ptr_ref)459  ret { i64, i64, i64, i64, i64, i64, i64, i64 } %val460}461 462declare swiftcc { i64, i64, i64, i64, i64, i64, i64, i64 } @params_and_return_in_reg2(i64, i64, i64, i64, i64, i64, i64, i64, ptr , ptr nocapture swifterror %err)463 464declare void @acallee(ptr)465 466; Make sure we don't tail call if the caller returns a swifterror value. We467; would have to move into the swifterror register before the tail call.468; CHECK-LABEL: tailcall_from_swifterror:469; CHECK-NOT: b _acallee470; CHECK: bl _acallee471 472define swiftcc void @tailcall_from_swifterror(ptr swifterror %error_ptr_ref) {473entry:474  tail call void @acallee(ptr null)475  ret void476}477 478; CHECK: tailcall_from_swifterror2479; CHECK-NOT: b _simple_fn480; CHECK: bl _simple_fn481declare void @simple_fn()482define swiftcc void @tailcall_from_swifterror2(ptr swifterror %error_ptr_ref) {483  tail call void @simple_fn()484  ret void485}486 487declare swiftcc void @foo2(ptr swifterror)488; CHECK-LABEL: testAssign489; CHECK: mov      x21, xzr490; CHECK: bl      _foo2491; CHECK: mov      x0, x21492 493define swiftcc ptr @testAssign(ptr %error_ref) {494entry:495  %error_ptr = alloca swifterror ptr496  store ptr null, ptr %error_ptr497  call swiftcc void @foo2(ptr swifterror %error_ptr)498  br label %a499 500a:501  %error = load ptr, ptr %error_ptr502  ret ptr %error503}504 505; foo takes a swifterror parameter. We should be able to see that even when506; it isn't explicitly on the call.507define float @swifterror_param_not_on_call(ptr %error_ref) {508; CHECK-LABEL: swifterror_param_not_on_call:509; CHECK: mov [[ID:x[0-9]+]], x0510; CHECK: bl {{.*}}foo511; CHECK: mov x0, x21512; CHECK: cbnz x21513; Access part of the error object and save it to error_ref514; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]515; CHECK: strb [[CODE]], [{{.*}}[[ID]]]516; CHECK: bl {{.*}}free517 518entry:519  %error_ptr_ref = alloca swifterror ptr520  store ptr null, ptr %error_ptr_ref521  %call = call float @foo(ptr %error_ptr_ref)522  %error_from_foo = load ptr, ptr %error_ptr_ref523  %had_error_from_foo = icmp ne ptr %error_from_foo, null524  br i1 %had_error_from_foo, label %handler, label %cont525cont:526  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1527  %t = load i8, ptr %v1528  store i8 %t, ptr %error_ref529  br label %handler530handler:531  call void @free(ptr %error_from_foo)532  ret float 1.0533}534 535; foo_sret takes an sret parameter and a swifterror parameter. We should be536; able to see that, even if it's not explicitly on the call.537define float @swifterror_param_not_on_call2(ptr %error_ref) {538; CHECK-LABEL: swifterror_param_not_on_call2:539; CHECK: mov [[ID:x[0-9]+]], x0540; CHECK: mov [[ZERO:x[0-9]+]], xzr541; CHECK: bl {{.*}}foo_sret542; CHECK: mov x0, x21543; CHECK: cbnz x21544; Access part of the error object and save it to error_ref545; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]546; CHECK: strb [[CODE]], [{{.*}}[[ID]]]547; CHECK: bl {{.*}}free548 549entry:550  %s = alloca %struct.S, align 8551  %error_ptr_ref = alloca swifterror ptr552  store ptr null, ptr %error_ptr_ref553  call void @foo_sret(ptr %s, i32 1, ptr %error_ptr_ref)554  %error_from_foo = load ptr, ptr %error_ptr_ref555  %had_error_from_foo = icmp ne ptr %error_from_foo, null556  br i1 %had_error_from_foo, label %handler, label %cont557cont:558  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1559  %t = load i8, ptr %v1560  store i8 %t, ptr %error_ref561  br label %handler562handler:563  call void @free(ptr %error_from_foo)564  ret float 1.0565}566