brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.9 KiB · db259ed Raw
746 lines · c
1// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s  -o - | FileCheck %s2// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s  -o - | FileCheck %s3 4#define IQ __ptrauth(1,0,50)5#define AQ __ptrauth(1,1,50)6#define DIFF_IQ __ptrauth(1,0,100)7#define DIFF_AQ __ptrauth(1,1,100)8#define ZERO_IQ __ptrauth(1,0,0)9#define ZERO_AQ __ptrauth(1,1,0)10 11extern int external_int;12extern int * global_upi;13extern int * IQ global_iqpi;14extern int * AQ global_aqpi;15extern void use_upi(int *ptr);16 17typedef void func_t(void);18extern void external_func(void);19extern func_t *global_upf;20extern func_t * IQ global_iqpf;21extern func_t * AQ global_aqpf;22extern void use_upf(func_t *ptr);23 24// Data with address-independent qualifiers.25 26// CHECK-LABEL: define {{.*}}void @test_store_data_i_constant()27void test_store_data_i_constant() {28// CHECK:         [[V:%.*]] = alloca ptr,29// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 50)30// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr31// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],32  int * IQ iqpi = &external_int;33// CHECK-NEXT:    [[T0:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 50)34// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T0]] to ptr35// CHECK-NEXT:    store ptr [[SIGNED]], ptr [[V]],36// CHECK-NEXT:    ret void37  iqpi = &external_int;38}39 40// CHECK-LABEL: define {{.*}}void @test_store_data_iu()41void test_store_data_iu() {42// CHECK:         [[V:%.*]] = alloca ptr,43// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upi,44// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null45// CHECK-NEXT:    br i1 [[T0]],46// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6447// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 50)48// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr49// CHECK-NEXT:    br label50// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]51// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],52  int * IQ iqpi = global_upi;53// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upi,54// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null55// CHECK-NEXT:    br i1 [[T0]],56// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6457// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 50)58// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr59// CHECK-NEXT:    br label60// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]61// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],62  iqpi = global_upi;63}64 65// CHECK-LABEL: define {{.*}}void @test_store_data_ia()66void test_store_data_ia() {67// CHECK:         [[V:%.*]] = alloca ptr,68// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,69// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)70// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null71// CHECK-NEXT:    br i1 [[T0]],72// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6473// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50)74// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr75// CHECK-NEXT:    br label76// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]77// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],78  int * IQ iqpi = global_aqpi;79// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,80// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)81// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null82// CHECK-NEXT:    br i1 [[T0]],83// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6484// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50)85// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr86// CHECK-NEXT:    br label87// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]88// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],89  iqpi = global_aqpi;90// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,91// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)92// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null93// CHECK-NEXT:    br i1 [[T0]],94// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6495// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50)96// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr97// CHECK-NEXT:    br label98// CHECK:         [[RESULT:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]99// CHECK-NEXT:    store ptr [[RESULT]], ptr [[V]],100// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[RESULT]], null101// CHECK-NEXT:    br i1 [[T0]],102// CHECK:         [[T0:%.*]] = ptrtoint ptr [[RESULT]] to i64103// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50)104// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr105// CHECK-NEXT:    br label106// CHECK:         [[RESULT:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]107// CHECK-NEXT:    call void @use_upi(ptr noundef [[RESULT]])108  use_upi(iqpi = global_aqpi);109}110 111// CHECK-LABEL: define {{.*}}void @test_store_data_ii_same()112void test_store_data_ii_same() {113// CHECK:         [[V:%.*]] = alloca ptr,114// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,115// CHECK-NEXT:    store ptr [[LOAD]], ptr [[V]],116  int * IQ iqpi = global_iqpi;117// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,118// CHECK-NEXT:    store ptr [[LOAD]], ptr [[V]],119  iqpi = global_iqpi;120}121 122// CHECK-LABEL: define {{.*}}void @test_store_data_ii_different()123void test_store_data_ii_different() {124// CHECK:         [[V:%.*]] = alloca ptr,125// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,126// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null127// CHECK-NEXT:    br i1 [[T0]],128// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64129// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100)130// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr131// CHECK-NEXT:    br label132// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]133// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],134  int * DIFF_IQ iqpi = global_iqpi;135// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,136// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null137// CHECK-NEXT:    br i1 [[T0]],138// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64139// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100)140// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr141// CHECK-NEXT:    br label142// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]143// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],144  iqpi = global_iqpi;145}146 147// CHECK-LABEL: define {{.*}}void @test_store_data_ii_zero()148void test_store_data_ii_zero() {149// CHECK:         [[V:%.*]] = alloca ptr,150// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,151// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null152// CHECK-NEXT:    br i1 [[T0]],153// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64154// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 0)155// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr156// CHECK-NEXT:    br label157// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]158// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],159  int * ZERO_IQ iqpi = global_iqpi;160// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr [[V]]161// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null162// CHECK-NEXT:    br i1 [[T0]],163// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64164// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 0, i32 1, i64 50)165// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr166// CHECK-NEXT:    br label167// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]168// CHECK-NEXT:    store ptr [[T0]], ptr @global_iqpi,169  global_iqpi = iqpi;170}171 172// CHECK-LABEL: define {{.*}}void @test_load_data_i()173void test_load_data_i() {174// CHECK:         [[V:%.*]] = alloca ptr,175// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,176// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null177// CHECK-NEXT:    br i1 [[T0]],178// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64179// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50)180// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr181// CHECK-NEXT:    br label182// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]183// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],184  int *upi = global_iqpi;185// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,186// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null187// CHECK-NEXT:    br i1 [[T0]],188// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64189// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50)190// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr191// CHECK-NEXT:    br label192// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]193// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],194  upi = global_iqpi;195// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,196// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null197// CHECK-NEXT:    br i1 [[T0]],198// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64199// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50)200// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr201// CHECK-NEXT:    br label202// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]203// CHECK-NEXT:    call void @use_upi(ptr noundef [[T0]])204  use_upi(global_iqpi);205}206 207// Data with address-discriminated qualifiers.208 209// CHECK-LABEL: define {{.*}}void @test_store_data_a_constant()210void test_store_data_a_constant() {211// CHECK:         [[V:%.*]] = alloca ptr,212// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64213// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)214// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 [[NEWDISC]])215// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr216// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],217  int * AQ aqpi = &external_int;218// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64219// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)220// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 [[NEWDISC]])221// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr222// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],223  aqpi = &external_int;224}225 226// CHECK-LABEL: define {{.*}}void @test_store_data_au()227void test_store_data_au() {228// CHECK:         [[V:%.*]] = alloca ptr,229// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upi,230// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64231// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)232// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null233// CHECK-NEXT:    br i1 [[T0]],234// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64235// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 [[NEWDISC]])236// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr237// CHECK-NEXT:    br label238// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]239// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],240  int * AQ aqpi = global_upi;241// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upi,242// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64243// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)244// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null245// CHECK-NEXT:    br i1 [[T0]],246// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64247// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 [[NEWDISC]])248// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr249// CHECK-NEXT:    br label250// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]251// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],252  aqpi = global_upi;253}254 255// CHECK-LABEL: define {{.*}}void @test_store_data_ai()256void test_store_data_ai() {257// CHECK:         [[V:%.*]] = alloca ptr,258// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,259// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64260// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)261// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null262// CHECK-NEXT:    br i1 [[T0]],263// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64264// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]])265// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr266// CHECK-NEXT:    br label267// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]268// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],269  int * AQ aqpi = global_iqpi;270// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpi,271// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64272// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)273// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null274// CHECK-NEXT:    br i1 [[T0]],275// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64276// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]])277// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr278// CHECK-NEXT:    br label279// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]280// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],281  aqpi = global_iqpi;282}283 284// CHECK-LABEL: define {{.*}}void @test_store_data_aa_same()285void test_store_data_aa_same() {286// CHECK:         [[V:%.*]] = alloca ptr,287// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,288// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)289// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64290// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)291// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null292// CHECK-NEXT:    br i1 [[T0]],293// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64294// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])295// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr296// CHECK-NEXT:    br label297// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]298// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],299  int * AQ aqpi = global_aqpi;300// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,301// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)302// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64303// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)304// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null305// CHECK-NEXT:    br i1 [[T0]],306// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64307// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])308// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr309// CHECK-NEXT:    br label310// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]311// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],312  aqpi = global_aqpi;313}314 315// CHECK-LABEL: define {{.*}}void @test_store_data_aa_different()316void test_store_data_aa_different() {317// CHECK:         [[V:%.*]] = alloca ptr,318// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,319// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)320// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64321// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100)322// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null323// CHECK-NEXT:    br i1 [[T0]],324// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64325// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])326// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr327// CHECK-NEXT:    br label328// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]329// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],330  int * DIFF_AQ aqpi = global_aqpi;331// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,332// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)333// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64334// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100)335// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null336// CHECK-NEXT:    br i1 [[T0]],337// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64338// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])339// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr340// CHECK-NEXT:    br label341// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]342// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],343  aqpi = global_aqpi;344}345 346// CHECK-LABEL: define {{.*}}void @test_store_data_aa_zero()347void test_store_data_aa_zero() {348// CHECK:         [[V:%.*]] = alloca ptr,349// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,350// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)351// CHECK-NEXT:    [[NEWDISC:%.*]] = ptrtoint ptr [[V]] to i64352// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null353// CHECK-NEXT:    br i1 [[T0]],354// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64355// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])356// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr357// CHECK-NEXT:    br label358// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]359// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],360  int * ZERO_AQ aqpi = global_aqpi;361// CHECK:         [[LOAD:%.*]] = load ptr, ptr [[V]],362// CHECK-NEXT:    [[OLDDISC:%.*]] = ptrtoint ptr [[V]] to i64363// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)364// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null365// CHECK-NEXT:    br i1 [[T0]],366// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64367// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])368// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr369// CHECK-NEXT:    br label370// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]371// CHECK-NEXT:    store ptr [[T0]], ptr @global_aqpi,372  global_aqpi = aqpi;373}374 375// CHECK-LABEL: define {{.*}}void @test_load_data_a()376void test_load_data_a() {377// CHECK:         [[V:%.*]] = alloca ptr,378// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,379// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)380// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null381// CHECK-NEXT:    br i1 [[T0]],382// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64383// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 [[OLDDISC]])384// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr385// CHECK-NEXT:    br label386// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]387// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],388  int *upi = global_aqpi;389// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,390// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)391// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null392// CHECK-NEXT:    br i1 [[T0]],393// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64394// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 [[OLDDISC]])395// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr396// CHECK-NEXT:    br label397// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]398// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],399  upi = global_aqpi;400// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpi,401// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50)402// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null403// CHECK-NEXT:    br i1 [[T0]],404// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64405// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 [[OLDDISC]])406// CHECK-NEXT:    [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr407// CHECK-NEXT:    br label408// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ]409// CHECK-NEXT:    call void @use_upi(ptr noundef [[T0]])410  use_upi(global_aqpi);411}412 413// Function with address-independent qualifiers.414 415// CHECK-LABEL: define {{.*}}void @test_store_function_i_constant()416void test_store_function_i_constant() {417// CHECK:         [[V:%.*]] = alloca ptr,418// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 50)419// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr420// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],421  func_t * IQ iqpf = &external_func;422// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 50)423// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr424// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],425  iqpf = &external_func;426}427 428// CHECK-LABEL: define {{.*}}void @test_store_function_iu()429void test_store_function_iu() {430// CHECK:         [[V:%.*]] = alloca ptr,431// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upf,432// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null433// CHECK-NEXT:    br i1 [[T0]],434// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64435// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 50)436// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr437// CHECK-NEXT:    br label438// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]439// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],440  func_t * IQ iqpf = global_upf;441// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upf,442// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null443// CHECK-NEXT:    br i1 [[T0]],444// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64445// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 50)446// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr447// CHECK-NEXT:    br label448// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]449// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],450  iqpf = global_upf;451}452 453// CHECK-LABEL: define {{.*}}void @test_store_function_ia()454void test_store_function_ia() {455// CHECK:         [[V:%.*]] = alloca ptr,456// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,457// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)458// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null459// CHECK-NEXT:    br i1 [[T0]],460// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64461// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50)462// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr463// CHECK-NEXT:    br label464// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]465// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],466  func_t * IQ iqpf = global_aqpf;467// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,468// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)469// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null470// CHECK-NEXT:    br i1 [[T0]],471// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64472// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50)473// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr474// CHECK-NEXT:    br label475// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]476// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],477  iqpf = global_aqpf;478// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,479// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)480// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null481// CHECK-NEXT:    br i1 [[T0]],482// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64483// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50)484// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr485// CHECK-NEXT:    br label486// CHECK:         [[RESULT:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]487// CHECK-NEXT:    store ptr [[RESULT]], ptr [[V]],488// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[RESULT]], null489// CHECK-NEXT:    br i1 [[T0]],490// CHECK:         [[T0:%.*]] = ptrtoint ptr [[RESULT]] to i64491// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983)492// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr493// CHECK-NEXT:    br label494// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]495// CHECK-NEXT:    call void @use_upf(ptr noundef [[T0]])496  use_upf(iqpf = global_aqpf);497}498 499// CHECK-LABEL: define {{.*}}void @test_store_function_ii_same()500void test_store_function_ii_same() {501// CHECK:         [[V:%.*]] = alloca ptr,502// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,503// CHECK-NEXT:    store ptr [[LOAD]], ptr [[V]],504  func_t * IQ iqpf = global_iqpf;505// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,506// CHECK-NEXT:    store ptr [[LOAD]], ptr [[V]],507  iqpf = global_iqpf;508}509 510// CHECK-LABEL: define {{.*}}void @test_store_function_ii_different()511void test_store_function_ii_different() {512// CHECK:         [[V:%.*]] = alloca ptr,513// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,514// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null515// CHECK-NEXT:    br i1 [[T0]],516// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64517// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100)518// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr519// CHECK-NEXT:    br label520// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]521// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],522  func_t * DIFF_IQ iqpf = global_iqpf;523// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,524// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null525// CHECK-NEXT:    br i1 [[T0]],526// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64527// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100)528// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr529// CHECK-NEXT:    br label530// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]531// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],532  iqpf = global_iqpf;533}534 535// CHECK-LABEL: define {{.*}}void @test_load_function_i()536void test_load_function_i() {537// CHECK:         [[V:%.*]] = alloca ptr,538// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,539// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null540// CHECK-NEXT:    br i1 [[T0]],541// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64542// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983)543// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr544// CHECK-NEXT:    br label545// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]546// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],547  func_t *upf = global_iqpf;548// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,549// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null550// CHECK-NEXT:    br i1 [[T0]],551// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64552// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983)553// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr554// CHECK-NEXT:    br label555// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]556// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],557  upf = global_iqpf;558// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,559// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null560// CHECK-NEXT:    br i1 [[T0]],561// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64562// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983)563// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr564// CHECK-NEXT:    br label565// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]566// CHECK-NEXT:    call void @use_upf(ptr noundef [[T0]])567  use_upf(global_iqpf);568}569 570// Function with address-discriminated qualifiers.571 572// CHECK-LABEL: define {{.*}}void @test_store_function_a_constant()573void test_store_function_a_constant() {574// CHECK:         [[V:%.*]] = alloca ptr,575// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64576// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)577// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 [[NEWDISC]])578// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr579// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],580  func_t * AQ aqpf = &external_func;581// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64582// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)583// CHECK-NEXT:    [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 [[NEWDISC]])584// CHECK-NEXT:    [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr585// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],586  aqpf = &external_func;587}588 589// CHECK-LABEL: define {{.*}}void @test_store_function_au()590void test_store_function_au() {591// CHECK:         [[V:%.*]] = alloca ptr,592// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upf,593// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64594// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)595// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null596// CHECK-NEXT:    br i1 [[T0]],597// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64598// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 [[NEWDISC]])599// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr600// CHECK-NEXT:    br label601// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]602// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],603  func_t * AQ aqpf = global_upf;604// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_upf,605// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64606// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)607// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null608// CHECK-NEXT:    br i1 [[T0]],609// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64610// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 [[NEWDISC]])611// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr612// CHECK-NEXT:    br label613// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]614// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],615  aqpf = global_upf;616}617 618// CHECK-LABEL: define {{.*}}void @test_store_function_ai()619void test_store_function_ai() {620// CHECK:         [[V:%.*]] = alloca ptr,621// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,622// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64623// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)624// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null625// CHECK-NEXT:    br i1 [[T0]],626// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64627// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]])628// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr629// CHECK-NEXT:    br label630// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]631// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],632  func_t * AQ aqpf = global_iqpf;633// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_iqpf,634// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64635// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)636// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null637// CHECK-NEXT:    br i1 [[T0]],638// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64639// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]])640// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr641// CHECK-NEXT:    br label642// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]643// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],644  aqpf = global_iqpf;645}646 647// CHECK-LABEL: define {{.*}}void @test_store_function_aa_same()648void test_store_function_aa_same() {649// CHECK:         [[V:%.*]] = alloca ptr,650// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,651// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)652// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64653// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)654// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null655// CHECK-NEXT:    br i1 [[T0]],656// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64657// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])658// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr659// CHECK-NEXT:    br label660// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]661// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],662  func_t * AQ aqpf = global_aqpf;663// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,664// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)665// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64666// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50)667// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null668// CHECK-NEXT:    br i1 [[T0]],669// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64670// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])671// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr672// CHECK-NEXT:    br label673// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]674// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],675  aqpf = global_aqpf;676}677 678// CHECK-LABEL: define {{.*}}void @test_store_function_aa_different()679void test_store_function_aa_different() {680// CHECK:         [[V:%.*]] = alloca ptr,681// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,682// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)683// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64684// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100)685// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null686// CHECK-NEXT:    br i1 [[T0]],687// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64688// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])689// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr690// CHECK-NEXT:    br label691// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]692// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],693  func_t * DIFF_AQ aqpf = global_aqpf;694// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,695// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)696// CHECK-NEXT:    [[T0:%.*]] = ptrtoint ptr [[V]] to i64697// CHECK-NEXT:    [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100)698// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null699// CHECK-NEXT:    br i1 [[T0]],700// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64701// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])702// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr703// CHECK-NEXT:    br label704// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]705// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],706  aqpf = global_aqpf;707}708 709// CHECK-LABEL: define {{.*}}void @test_load_function_a()710void test_load_function_a() {711// CHECK:         [[V:%.*]] = alloca ptr,712// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,713// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)714// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null715// CHECK-NEXT:    br i1 [[T0]],716// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64717// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 0, i64 18983)718// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr719// CHECK-NEXT:    br label720// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]721// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],722  func_t *upf = global_aqpf;723// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,724// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)725// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null726// CHECK-NEXT:    br i1 [[T0]],727// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64728// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 0, i64 18983)729// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr730// CHECK-NEXT:    br label731// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]732// CHECK-NEXT:    store ptr [[T0]], ptr [[V]],733  upf = global_aqpf;734// CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr @global_aqpf,735// CHECK-NEXT:    [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50)736// CHECK-NEXT:    [[T0:%.*]] = icmp ne ptr [[LOAD]], null737// CHECK-NEXT:    br i1 [[T0]],738// CHECK:         [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64739// CHECK-NEXT:    [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 0, i64 18983)740// CHECK-NEXT:    [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr741// CHECK-NEXT:    br label742// CHECK:         [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ]743// CHECK-NEXT:    call void @use_upf(ptr noundef [[T0]])744  use_upf(global_aqpf);745}746