; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s define i32 @test_ptrauth_call_sign(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_sign( ; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 %v1 = call i64 @llvm.ptrauth.sign(i64 %v0, i32 2, i64 5678) %v2 = inttoptr i64 %v1 to ptr %v3 = call i32 %v2() [ "ptrauth"(i32 2, i64 5678) ] ret i32 %v3 } define i32 @test_ptrauth_call_sign_otherbundle(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_sign_otherbundle( ; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "somebundle"(ptr null), "otherbundle"(i64 0) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 %v1 = call i64 @llvm.ptrauth.sign(i64 %v0, i32 2, i64 5678) %v2 = inttoptr i64 %v1 to ptr %v3 = call i32 %v2() [ "somebundle"(ptr null), "ptrauth"(i32 2, i64 5678), "otherbundle"(i64 0) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign( ; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i32 1, i64 1234) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 1, i64 5678) %v2 = inttoptr i64 %v1 to ptr %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign_blend(ptr %pp) { ; CHECK-LABEL: @test_ptrauth_call_resign_blend( ; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8 ; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 1, i64 1234) ] ; CHECK-NEXT: ret i32 [[V6]] ; %v0 = load ptr, ptr %pp, align 8 %v1 = ptrtoint ptr %pp to i64 %v2 = ptrtoint ptr %v0 to i64 %v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678) %v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 1, i64 1234, i32 1, i64 %v3) %v5 = inttoptr i64 %v4 to ptr %v6 = call i32 %v5() [ "ptrauth"(i32 1, i64 %v3) ] ret i32 %v6 } define i32 @test_ptrauth_call_resign_blend_2(ptr %pp) { ; CHECK-LABEL: @test_ptrauth_call_resign_blend_2( ; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8 ; CHECK-NEXT: [[V1:%.*]] = ptrtoint ptr [[PP]] to i64 ; CHECK-NEXT: [[V3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[V1]], i64 5678) ; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 0, i64 [[V3]]) ] ; CHECK-NEXT: ret i32 [[V6]] ; %v0 = load ptr, ptr %pp, align 8 %v1 = ptrtoint ptr %pp to i64 %v2 = ptrtoint ptr %v0 to i64 %v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678) %v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 0, i64 %v3, i32 0, i64 1234) %v5 = inttoptr i64 %v4 to ptr %v6 = call i32 %v5() [ "ptrauth"(i32 0, i64 1234) ] ret i32 %v6 } define i32 @test_ptrauth_call_resign_mismatch_key(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign_mismatch_key( ; CHECK-NEXT: [[V0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 ; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]], i32 1, i64 1234, i32 0, i64 5678) ; CHECK-NEXT: [[V2:%.*]] = inttoptr i64 [[V1]] to ptr ; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i32 1, i64 5678) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 0, i64 5678) %v2 = inttoptr i64 %v1 to ptr %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign_mismatch_disc(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign_mismatch_disc( ; CHECK-NEXT: [[V0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 ; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]], i32 1, i64 1234, i32 0, i64 9900) ; CHECK-NEXT: [[V2:%.*]] = inttoptr i64 [[V1]] to ptr ; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i32 1, i64 5678) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 0, i64 9900) %v2 = inttoptr i64 %v1 to ptr %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign_mismatch_blend(ptr %pp) { ; CHECK-LABEL: @test_ptrauth_call_resign_mismatch_blend( ; CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[PP:%.*]], align 8 ; CHECK-NEXT: [[V1:%.*]] = ptrtoint ptr [[PP]] to i64 ; CHECK-NEXT: [[V2:%.*]] = ptrtoint ptr [[V0]] to i64 ; CHECK-NEXT: [[V6:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[V1]], i64 5678) ; CHECK-NEXT: [[V4:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V2]], i32 1, i64 1234, i32 1, i64 [[V6]]) ; CHECK-NEXT: [[V5:%.*]] = inttoptr i64 [[V4]] to ptr ; CHECK-NEXT: [[V3:%.*]] = call i32 [[V5]]() [ "ptrauth"(i32 1, i64 [[V1]]) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = load ptr, ptr %pp, align 8 %v1 = ptrtoint ptr %pp to i64 %v2 = ptrtoint ptr %v0 to i64 %v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678) %v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 1, i64 1234, i32 1, i64 %v3) %v5 = inttoptr i64 %v4 to ptr %v6 = call i32 %v5() [ "ptrauth"(i32 1, i64 %v1) ] ret i32 %v6 } define i32 @test_ptrauth_call_resign_changing_call_key(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign_changing_call_key( ; CHECK-NEXT: [[V0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 ; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]], i32 2, i64 1234, i32 1, i64 5678) ; CHECK-NEXT: [[V2:%.*]] = inttoptr i64 [[V1]] to ptr ; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i32 1, i64 5678) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 2, i64 1234, i32 1, i64 5678) %v2 = inttoptr i64 %v1 to ptr %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] ret i32 %v3 } declare i64 @llvm.ptrauth.sign(i64, i32, i64) declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64) declare i64 @llvm.ptrauth.blend(i64, i64)