561 lines · plain
1; RUN: llc -mtriple arm64e-apple-darwin -o - %s -asm-verbose=0 \2; RUN: | FileCheck %s --check-prefixes=CHECK,DARWIN3 4; RUN: llc -mtriple aarch64 -mattr=+pauth -o - %s -asm-verbose=0 \5; RUN: | FileCheck %s --check-prefixes=CHECK,ELF6 7; RUN: llc -mtriple arm64e-apple-darwin -o - %s -asm-verbose=0 \8; RUN: -global-isel -global-isel-abort=1 -verify-machineinstrs \9; RUN: | FileCheck %s --check-prefixes=CHECK,DARWIN10 11; RUN: llc -mtriple aarch64 -mattr=+pauth -o - %s -asm-verbose=0 \12; RUN: -global-isel -global-isel-abort=1 -verify-machineinstrs \13; RUN: | FileCheck %s --check-prefixes=CHECK,ELF14 15 16define i32 @test_call_ia_0(ptr %arg0) #0 {17; DARWIN-LABEL: test_call_ia_0:18; DARWIN-NEXT: stp x29, x30, [sp, #-16]!19; DARWIN-NEXT: blraaz x020; DARWIN-NEXT: ldp x29, x30, [sp], #1621; DARWIN-NEXT: ret22;23; ELF-LABEL: test_call_ia_0:24; ELF-NEXT: str x30, [sp, #-16]!25; ELF-NEXT: blraaz x026; ELF-NEXT: ldr x30, [sp], #1627; ELF-NEXT: ret28 %tmp0 = call i32 %arg0() [ "ptrauth"(i32 0, i64 0) ]29 ret i32 %tmp030}31 32define i32 @test_call_ib_0(ptr %arg0) #0 {33; DARWIN-LABEL: test_call_ib_0:34; DARWIN-NEXT: stp x29, x30, [sp, #-16]!35; DARWIN-NEXT: blrabz x036; DARWIN-NEXT: ldp x29, x30, [sp], #1637; DARWIN-NEXT: ret38;39; ELF-LABEL: test_call_ib_0:40; ELF-NEXT: str x30, [sp, #-16]!41; ELF-NEXT: blrabz x042; ELF-NEXT: ldr x30, [sp], #1643; ELF-NEXT: ret44 %tmp0 = call i32 %arg0() [ "ptrauth"(i32 1, i64 0) ]45 ret i32 %tmp046}47 48define i32 @test_tailcall_ia_0(ptr %arg0) #0 {49; CHECK-LABEL: test_tailcall_ia_0:50; CHECK-NEXT: braaz x051 %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 0) ]52 ret i32 %tmp053}54 55define i32 @test_tailcall_ib_0(ptr %arg0) #0 {56; CHECK-LABEL: test_tailcall_ib_0:57; CHECK-NEXT: brabz x058 %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 0) ]59 ret i32 %tmp060}61 62define i32 @test_call_ia_imm(ptr %arg0) #0 {63; DARWIN-LABEL: test_call_ia_imm:64; DARWIN-NEXT: stp x29, x30, [sp, #-16]!65; DARWIN-NEXT: mov x17, #4266; DARWIN-NEXT: blraa x0, x1767; DARWIN-NEXT: ldp x29, x30, [sp], #1668; DARWIN-NEXT: ret69;70; ELF-LABEL: test_call_ia_imm:71; ELF-NEXT: str x30, [sp, #-16]!72; ELF-NEXT: mov x17, #4273; ELF-NEXT: blraa x0, x1774; ELF-NEXT: ldr x30, [sp], #1675; ELF-NEXT: ret76 %tmp0 = call i32 %arg0() [ "ptrauth"(i32 0, i64 42) ]77 ret i32 %tmp078}79 80define i32 @test_call_ib_imm(ptr %arg0) #0 {81; DARWIN-LABEL: test_call_ib_imm:82; DARWIN-NEXT: stp x29, x30, [sp, #-16]!83; DARWIN-NEXT: mov x17, #4284; DARWIN-NEXT: blrab x0, x1785; DARWIN-NEXT: ldp x29, x30, [sp], #1686; DARWIN-NEXT: ret87;88; ELF-LABEL: test_call_ib_imm:89; ELF-NEXT: str x30, [sp, #-16]!90; ELF-NEXT: mov x17, #4291; ELF-NEXT: blrab x0, x1792; ELF-NEXT: ldr x30, [sp], #1693; ELF-NEXT: ret94 %tmp0 = call i32 %arg0() [ "ptrauth"(i32 1, i64 42) ]95 ret i32 %tmp096}97 98define i32 @test_tailcall_ia_imm(ptr %arg0) #0 {99; CHECK-LABEL: test_tailcall_ia_imm:100; CHECK-NEXT: mov x16, #42101; CHECK-NEXT: braa x0, x16102 %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 42) ]103 ret i32 %tmp0104}105 106define i32 @test_tailcall_ib_imm(ptr %arg0) #0 {107; CHECK-LABEL: test_tailcall_ib_imm:108; CHECK-NEXT: mov x16, #42109; CHECK-NEXT: brab x0, x16110 %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 42) ]111 ret i32 %tmp0112}113 114define i32 @test_call_ia_var(ptr %arg0, ptr %arg1) #0 {115; DARWIN-LABEL: test_call_ia_var:116; DARWIN-NEXT: stp x29, x30, [sp, #-16]!117; DARWIN-NEXT: ldr x8, [x1]118; DARWIN-NEXT: blraa x0, x8119; DARWIN-NEXT: ldp x29, x30, [sp], #16120; DARWIN-NEXT: ret121;122; ELF-LABEL: test_call_ia_var:123; ELF-NEXT: str x30, [sp, #-16]!124; ELF-NEXT: ldr x8, [x1]125; ELF-NEXT: blraa x0, x8126; ELF-NEXT: ldr x30, [sp], #16127; ELF-NEXT: ret128 %tmp0 = load i64, ptr %arg1129 %tmp1 = call i32 %arg0() [ "ptrauth"(i32 0, i64 %tmp0) ]130 ret i32 %tmp1131}132 133define i32 @test_call_ib_var(ptr %arg0, ptr %arg1) #0 {134; DARWIN-LABEL: test_call_ib_var:135; DARWIN-NEXT: stp x29, x30, [sp, #-16]!136; DARWIN-NEXT: ldr x8, [x1]137; DARWIN-NEXT: blrab x0, x8138; DARWIN-NEXT: ldp x29, x30, [sp], #16139; DARWIN-NEXT: ret140;141; ELF-LABEL: test_call_ib_var:142; ELF-NEXT: str x30, [sp, #-16]!143; ELF-NEXT: ldr x8, [x1]144; ELF-NEXT: blrab x0, x8145; ELF-NEXT: ldr x30, [sp], #16146; ELF-NEXT: ret147 %tmp0 = load i64, ptr %arg1148 %tmp1 = call i32 %arg0() [ "ptrauth"(i32 1, i64 %tmp0) ]149 ret i32 %tmp1150}151 152define i32 @test_tailcall_ia_var(ptr %arg0, ptr %arg1) #0 {153; CHECK-LABEL: test_tailcall_ia_var:154; CHECK: ldr x1, [x1]155; CHECK: braa x0, x1156 %tmp0 = load i64, ptr %arg1157 %tmp1 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 %tmp0) ]158 ret i32 %tmp1159}160 161define i32 @test_tailcall_ib_var(ptr %arg0, ptr %arg1) #0 {162; CHECK-LABEL: test_tailcall_ib_var:163; CHECK: ldr x1, [x1]164; CHECK: brab x0, x1165 %tmp0 = load i64, ptr %arg1166 %tmp1 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 %tmp0) ]167 ret i32 %tmp1168}169 170define void @test_tailcall_omit_mov_x16_x16(ptr %objptr) #0 {171; CHECK-LABEL: test_tailcall_omit_mov_x16_x16:172; DARWIN-NEXT: ldr x16, [x0]173; DARWIN-NEXT: mov x17, x0174; DARWIN-NEXT: movk x17, #6503, lsl #48175; DARWIN-NEXT: autda x16, x17176; DARWIN-NEXT: ldr x1, [x16]177; DARWIN-NEXT: movk x16, #54167, lsl #48178; DARWIN-NEXT: braa x1, x16179; ELF-NEXT: ldr x1, [x0]180; ELF-NEXT: mov x8, x0181; ELF-NEXT: movk x8, #6503, lsl #48182; ELF-NEXT: autda x1, x8183; ELF-NEXT: ldr x2, [x1]184; ELF-NEXT: mov x16, x1185; ELF-NEXT: movk x16, #54167, lsl #48186; ELF-NEXT: braa x2, x16187 %vtable.signed = load ptr, ptr %objptr, align 8188 %objptr.int = ptrtoint ptr %objptr to i64189 %vtable.discr = tail call i64 @llvm.ptrauth.blend(i64 %objptr.int, i64 6503)190 %vtable.signed.int = ptrtoint ptr %vtable.signed to i64191 %vtable.unsigned.int = tail call i64 @llvm.ptrauth.auth(i64 %vtable.signed.int, i32 2, i64 %vtable.discr)192 %vtable.unsigned = inttoptr i64 %vtable.unsigned.int to ptr193 %virt.func.signed = load ptr, ptr %vtable.unsigned, align 8194 %virt.func.discr = tail call i64 @llvm.ptrauth.blend(i64 %vtable.unsigned.int, i64 54167)195 tail call void %virt.func.signed(ptr %objptr) [ "ptrauth"(i32 0, i64 %virt.func.discr) ]196 ret void197}198 199define i32 @test_call_omit_extra_moves(ptr %objptr) #0 {200; CHECK-LABEL: test_call_omit_extra_moves:201; DARWIN-NEXT: stp x29, x30, [sp, #-16]!202; DARWIN-NEXT: ldr x16, [x0]203; DARWIN-NEXT: mov x17, x0204; DARWIN-NEXT: movk x17, #6503, lsl #48205; DARWIN-NEXT: autda x16, x17206; DARWIN-NEXT: ldr x8, [x16]207; DARWIN-NEXT: movk x16, #34646, lsl #48208; DARWIN-NEXT: blraa x8, x16209; DARWIN-NEXT: mov w0, #42210; DARWIN-NEXT: ldp x29, x30, [sp], #16211; ELF-NEXT: str x30, [sp, #-16]!212; ELF-NEXT: ldr x8, [x0]213; ELF-NEXT: mov x9, x0214; ELF-NEXT: movk x9, #6503, lsl #48215; ELF-NEXT: autda x8, x9216; ELF-NEXT: ldr x9, [x8]217; ELF-NEXT: mov x17, x8218; ELF-NEXT: movk x17, #34646, lsl #48219; ELF-NEXT: blraa x9, x17220; ELF-NEXT: mov w0, #42221; ELF-NEXT: ldr x30, [sp], #16222; CHECK-NEXT: ret223 %vtable.signed = load ptr, ptr %objptr224 %objptr.int = ptrtoint ptr %objptr to i64225 %vtable.discr = tail call i64 @llvm.ptrauth.blend(i64 %objptr.int, i64 6503)226 %vtable.signed.int = ptrtoint ptr %vtable.signed to i64227 %vtable.int = tail call i64 @llvm.ptrauth.auth(i64 %vtable.signed.int, i32 2, i64 %vtable.discr)228 %vtable = inttoptr i64 %vtable.int to ptr229 %callee.signed = load ptr, ptr %vtable230 %callee.discr = tail call i64 @llvm.ptrauth.blend(i64 %vtable.int, i64 34646)231 %call.result = tail call i32 %callee.signed(ptr %objptr) [ "ptrauth"(i32 0, i64 %callee.discr) ]232 ret i32 42233}234 235; The second BLRA instruction should not reuse its AddrDisc operand as a scratch register (returned later).236define i64 @test_call_discr_csr_live(ptr %fnptr, i64 %addr.discr) #0 {237; ELF-LABEL: test_call_discr_csr_live:238; ELF-NEXT: str x30, [sp, #-32]!239; ELF-NEXT: stp x20, x19, [sp, #16]240; ELF-DAG: mov x[[FNPTR:[0-9]+]], x0241; ELF-DAG: mov x[[ADDR_DISC:[0-9]+]], x1242; ELF-DAG: mov x17, x1243; ELF-NEXT: movk x17, #6503, lsl #48244; ELF-NEXT: blraa x0, x17245; ELF-NEXT: mov x17, x[[ADDR_DISC]]246; ELF-NEXT: movk x17, #6503, lsl #48247; ELF-NEXT: blraa x[[FNPTR]], x17248; ELF-NEXT: mov x0, x[[ADDR_DISC]]249; ELF-NEXT: ldp x20, x19, [sp, #16]250; ELF-NEXT: ldr x30, [sp], #32251; ELF-NEXT: ret252 %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503)253 tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ]254 tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ]255 ret i64 %addr.discr256}257 258; The second BLRA instruction may reuse its AddrDisc operand as a scratch register.259define i64 @test_call_discr_csr_killed(ptr %fnptr, i64 %addr.discr) #0 {260; ELF-LABEL: test_call_discr_csr_killed:261; ELF-NEXT: str x30, [sp, #-32]!262; ELF-NEXT: stp x20, x19, [sp, #16]263; ELF-DAG: mov x[[FNPTR:[0-9]+]], x0264; ELF-DAG: mov x[[ADDR_DISC:[0-9]+]], x1265; ELF-DAG: mov x17, x1266; ELF-NEXT: movk x17, #6503, lsl #48267; ELF-NEXT: blraa x0, x17268; ELF-DAG: mov x17, x[[ADDR_DISC]]269; ELF-NEXT: movk x17, #6503, lsl #48270; ELF-NEXT: blraa x[[FNPTR]], x17271; ELF-NEXT: ldp x20, x19, [sp, #16]272; ELF-NEXT: mov w0, #42273; ELF-NEXT: ldr x30, [sp], #32274; ELF-NEXT: ret275 %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503)276 tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ]277 tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ]278 ret i64 42279}280 281; BLRA instruction should not reuse its AddrDisc operand as a scratch register (function argument).282define i64 @test_call_discr_arg(ptr %fnptr, i64 %addr.discr) #0 {283; ELF-LABEL: test_call_discr_arg:284; ELF-NEXT: str x30, [sp, #-16]!285; ELF-NEXT: mov x8, x0286; ELF-NEXT: mov x0, xzr287; ELF-NEXT: mov x17, x1288; ELF-NEXT: movk x17, #6503, lsl #48289; ELF-NEXT: blraa x8, x17290; ELF-NEXT: mov w0, #42291; ELF-NEXT: ldr x30, [sp], #16292; ELF-NEXT: ret293 %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503)294 tail call void %fnptr(ptr null, i64 %addr.discr) [ "ptrauth"(i32 0, i64 %discr) ]295 ret i64 42296}297 298; BLRA instruction may reuse its AddrDisc operand as a scratch register.299define i64 @test_call_discr_non_arg(ptr %fnptr, i64 %addr.discr) #0 {300; ELF-LABEL: test_call_discr_non_arg:301; ELF-NEXT: str x30, [sp, #-16]!302; ELF-NEXT: mov x17, x1303; ELF-NEXT: movk x17, #6503, lsl #48304; ELF-NEXT: blraa x0, x17305; ELF-NEXT: mov w0, #42306; ELF-NEXT: ldr x30, [sp], #16307; ELF-NEXT: ret308 %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503)309 tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ]310 ret i64 42311}312 313; AUTH_TCRETURN instruction should not reuse its AddrDisc operand as a scratch register (function argument).314define i64 @test_tailcall_discr_arg(ptr %fnptr, i64 %addr.discr) #0 {315; ELF-LABEL: test_tailcall_discr_arg:316; ELF-NEXT: mov x2, x0317; ELF-NEXT: mov x0, xzr318; ELF-NEXT: mov x16, x1319; ELF-NEXT: movk x16, #6503, lsl #48320; ELF-NEXT: braa x2, x16321 %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503)322 %result = tail call i64 %fnptr(ptr null, i64 %addr.discr) [ "ptrauth"(i32 0, i64 %discr) ]323 ret i64 %result324}325 326define i32 @test_call_ia_arg(ptr %arg0, i64 %arg1) #0 {327; DARWIN-LABEL: test_call_ia_arg:328; DARWIN-NEXT: stp x29, x30, [sp, #-16]!329; DARWIN-NEXT: blraa x0, x1330; DARWIN-NEXT: ldp x29, x30, [sp], #16331; DARWIN-NEXT: ret332;333; ELF-LABEL: test_call_ia_arg:334; ELF-NEXT: str x30, [sp, #-16]!335; ELF-NEXT: blraa x0, x1336; ELF-NEXT: ldr x30, [sp], #16337; ELF-NEXT: ret338 %tmp0 = call i32 %arg0() [ "ptrauth"(i32 0, i64 %arg1) ]339 ret i32 %tmp0340}341 342define i32 @test_call_ib_arg(ptr %arg0, i64 %arg1) #0 {343; DARWIN-LABEL: test_call_ib_arg:344; DARWIN-NEXT: stp x29, x30, [sp, #-16]!345; DARWIN-NEXT: blrab x0, x1346; DARWIN-NEXT: ldp x29, x30, [sp], #16347; DARWIN-NEXT: ret348;349; ELF-LABEL: test_call_ib_arg:350; ELF-NEXT: str x30, [sp, #-16]!351; ELF-NEXT: blrab x0, x1352; ELF-NEXT: ldr x30, [sp], #16353; ELF-NEXT: ret354 %tmp0 = call i32 %arg0() [ "ptrauth"(i32 1, i64 %arg1) ]355 ret i32 %tmp0356}357 358define i32 @test_tailcall_ia_arg(ptr %arg0, i64 %arg1) #0 {359; CHECK-LABEL: test_tailcall_ia_arg:360; CHECK: braa x0, x1361 %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 %arg1) ]362 ret i32 %tmp0363}364 365define i32 @test_tailcall_ib_arg(ptr %arg0, i64 %arg1) #0 {366; CHECK-LABEL: test_tailcall_ib_arg:367; CHECK: brab x0, x1368 %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 %arg1) ]369 ret i32 %tmp0370}371 372define i32 @test_call_ia_arg_ind(ptr %arg0, i64 %arg1) #0 {373; DARWIN-LABEL: test_call_ia_arg_ind:374; DARWIN-NEXT: stp x29, x30, [sp, #-16]!375; DARWIN-NEXT: ldr x8, [x0]376; DARWIN-NEXT: blraa x8, x1377; DARWIN-NEXT: ldp x29, x30, [sp], #16378; DARWIN-NEXT: ret379;380; ELF-LABEL: test_call_ia_arg_ind:381; ELF-NEXT: str x30, [sp, #-16]!382; ELF-NEXT: ldr x8, [x0]383; ELF-NEXT: blraa x8, x1384; ELF-NEXT: ldr x30, [sp], #16385; ELF-NEXT: ret386 %tmp0 = load ptr, ptr %arg0387 %tmp1 = call i32 %tmp0() [ "ptrauth"(i32 0, i64 %arg1) ]388 ret i32 %tmp1389}390 391define i32 @test_call_ib_arg_ind(ptr %arg0, i64 %arg1) #0 {392; DARWIN-LABEL: test_call_ib_arg_ind:393; DARWIN-NEXT: stp x29, x30, [sp, #-16]!394; DARWIN-NEXT: ldr x8, [x0]395; DARWIN-NEXT: blrab x8, x1396; DARWIN-NEXT: ldp x29, x30, [sp], #16397; DARWIN-NEXT: ret398;399; ELF-LABEL: test_call_ib_arg_ind:400; ELF-NEXT: str x30, [sp, #-16]!401; ELF-NEXT: ldr x8, [x0]402; ELF-NEXT: blrab x8, x1403; ELF-NEXT: ldr x30, [sp], #16404; ELF-NEXT: ret405 %tmp0 = load ptr, ptr %arg0406 %tmp1 = call i32 %tmp0() [ "ptrauth"(i32 1, i64 %arg1) ]407 ret i32 %tmp1408}409 410define i32 @test_tailcall_ia_arg_ind(ptr %arg0, i64 %arg1) #0 {411; CHECK-LABEL: test_tailcall_ia_arg_ind:412; CHECK: ldr x0, [x0]413; CHECK: braa x0, x1414 %tmp0 = load ptr, ptr %arg0415 %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i32 0, i64 %arg1) ]416 ret i32 %tmp1417}418 419define i32 @test_tailcall_ib_arg_ind(ptr %arg0, i64 %arg1) #0 {420; CHECK-LABEL: test_tailcall_ib_arg_ind:421; CHECK: ldr x0, [x0]422; CHECK: brab x0, x1423 %tmp0 = load ptr, ptr %arg0424 %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i32 1, i64 %arg1) ]425 ret i32 %tmp1426}427 428; Test direct calls429 430define i32 @test_direct_call() #0 {431; DARWIN-LABEL: test_direct_call:432; DARWIN-NEXT: stp x29, x30, [sp, #-16]!433; DARWIN-NEXT: bl _f434; DARWIN-NEXT: ldp x29, x30, [sp], #16435; DARWIN-NEXT: ret436;437; ELF-LABEL: test_direct_call:438; ELF-NEXT: str x30, [sp, #-16]!439; ELF-NEXT: bl f440; ELF-NEXT: ldr x30, [sp], #16441; ELF-NEXT: ret442 %tmp0 = call i32 ptrauth(ptr @f, i32 0, i64 42)() [ "ptrauth"(i32 0, i64 42) ]443 ret i32 %tmp0444}445 446define i32 @test_direct_tailcall(ptr %arg0) #0 {447; DARWIN-LABEL: test_direct_tailcall:448; DARWIN: b _f449;450; ELF-LABEL: test_direct_tailcall:451; ELF-NEXT: b f452 %tmp0 = tail call i32 ptrauth(ptr @f, i32 0, i64 42)() [ "ptrauth"(i32 0, i64 42) ]453 ret i32 %tmp0454}455 456define i32 @test_direct_call_mismatch() #0 {457; DARWIN-LABEL: test_direct_call_mismatch:458; DARWIN-NEXT: stp x29, x30, [sp, #-16]!459; DARWIN-NEXT: adrp x16, _f@GOTPAGE460; DARWIN-NEXT: ldr x16, [x16, _f@GOTPAGEOFF]461; DARWIN-NEXT: mov x17, #42462; DARWIN-NEXT: pacia x16, x17463; DARWIN-NEXT: mov x8, x16464; DARWIN-NEXT: mov x17, #42465; DARWIN-NEXT: blrab x8, x17466; DARWIN-NEXT: ldp x29, x30, [sp], #16467; DARWIN-NEXT: ret468;469; ELF-LABEL: test_direct_call_mismatch:470; ELF-NEXT: str x30, [sp, #-16]!471; ELF-NEXT: adrp x16, :got:f472; ELF-NEXT: ldr x16, [x16, :got_lo12:f]473; ELF-NEXT: mov x17, #42474; ELF-NEXT: pacia x16, x17475; ELF-NEXT: mov x8, x16476; ELF-NEXT: mov x17, #42477; ELF-NEXT: blrab x8, x17478; ELF-NEXT: ldr x30, [sp], #16479; ELF-NEXT: ret480 %tmp0 = call i32 ptrauth(ptr @f, i32 0, i64 42)() [ "ptrauth"(i32 1, i64 42) ]481 ret i32 %tmp0482}483 484define i32 @test_direct_call_addr() #0 {485; DARWIN-LABEL: test_direct_call_addr:486; DARWIN-NEXT: stp x29, x30, [sp, #-16]!487; DARWIN-NEXT: bl _f488; DARWIN-NEXT: ldp x29, x30, [sp], #16489; DARWIN-NEXT: ret490;491; ELF-LABEL: test_direct_call_addr:492; ELF-NEXT: str x30, [sp, #-16]!493; ELF-NEXT: bl f494; ELF-NEXT: ldr x30, [sp], #16495; ELF-NEXT: ret496 %tmp0 = call i32 ptrauth(ptr @f, i32 1, i64 0, ptr @f.ref.ib.0.addr)() [ "ptrauth"(i32 1, i64 ptrtoint (ptr @f.ref.ib.0.addr to i64)) ]497 ret i32 %tmp0498}499 500define i32 @test_direct_call_addr_blend() #0 {501; DARWIN-LABEL: test_direct_call_addr_blend:502; DARWIN-NEXT: stp x29, x30, [sp, #-16]!503; DARWIN-NEXT: bl _f504; DARWIN-NEXT: ldp x29, x30, [sp], #16505; DARWIN-NEXT: ret506;507; ELF-LABEL: test_direct_call_addr_blend:508; ELF-NEXT: str x30, [sp, #-16]!509; ELF-NEXT: bl f510; ELF-NEXT: ldr x30, [sp], #16511; ELF-NEXT: ret512 %tmp0 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f.ref.ib.42.addr to i64), i64 42)513 %tmp1 = call i32 ptrauth(ptr @f, i32 1, i64 42, ptr @f.ref.ib.42.addr)() [ "ptrauth"(i32 1, i64 %tmp0) ]514 ret i32 %tmp1515}516 517define i32 @test_direct_call_addr_gep_different_index_types() #0 {518; DARWIN-LABEL: test_direct_call_addr_gep_different_index_types:519; DARWIN-NEXT: stp x29, x30, [sp, #-16]!520; DARWIN-NEXT: bl _f521; DARWIN-NEXT: ldp x29, x30, [sp], #16522; DARWIN-NEXT: ret523;524; ELF-LABEL: test_direct_call_addr_gep_different_index_types:525; ELF-NEXT: str x30, [sp, #-16]!526; ELF-NEXT: bl f527; ELF-NEXT: ldr x30, [sp], #16528; ELF-NEXT: ret529 %tmp0 = call i32 ptrauth(ptr @f, i32 1, i64 0, ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.0.addr, i64 0, i32 0))() [ "ptrauth"(i32 1, i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.0.addr, i32 0, i32 0) to i64)) ]530 ret i32 %tmp0531}532 533define i32 @test_direct_call_addr_blend_gep_different_index_types() #0 {534; DARWIN-LABEL: test_direct_call_addr_blend_gep_different_index_types:535; DARWIN-NEXT: stp x29, x30, [sp, #-16]!536; DARWIN-NEXT: bl _f537; DARWIN-NEXT: ldp x29, x30, [sp], #16538; DARWIN-NEXT: ret539;540; ELF-LABEL: test_direct_call_addr_blend_gep_different_index_types:541; ELF-NEXT: str x30, [sp, #-16]!542; ELF-NEXT: bl f543; ELF-NEXT: ldr x30, [sp], #16544; ELF-NEXT: ret545 %tmp0 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.123.addr, i32 0, i32 0) to i64), i64 123)546 %tmp1 = call i32 ptrauth(ptr @f, i32 1, i64 123, ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.123.addr, i64 0, i32 0))() [ "ptrauth"(i32 1, i64 %tmp0) ]547 ret i32 %tmp1548}549 550@f.ref.ib.42.addr = external global ptr551@f.ref.ib.0.addr = external global ptr552@f_struct.ref.ib.0.addr = external global ptr553@f_struct.ref.ib.123.addr = external global ptr554 555declare void @f()556 557declare i64 @llvm.ptrauth.auth(i64, i32, i64)558declare i64 @llvm.ptrauth.blend(i64, i64)559 560attributes #0 = { nounwind }561