Skip to content

Commit bce1917

Browse files
committed
[InstCombine] Combine ptrauth intrin. callee into diff. key bundle.
Try to optimize a call to the result of a ptrauth intrinsic, potentially into the ptrauth call bundle: - call(ptrauth.resign(p)), ["ptrauth"()] -> call p, ["ptrauth"()] - call(ptrauth.sign(p)), ["ptrauth"()] -> call p - call(ptrauth.auth(p)) -> call p, ["ptrauth"()] as long as the key/discriminator are the same in sign and auth-bundle. This relaxes the existing combine in one major way: it can generate calls with ptrauth bundles with a different key from the existing call. Without knowledge of the target keys, this may be unsound. That also allows folding ptrauth.auth into the call bundle: we can't generally do that if we don't know whether the auth key is valid for calls.
1 parent 903f149 commit bce1917

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3681,10 +3681,6 @@ Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) {
36813681
II->getOperand(4) != PtrAuthBundleOrNone->Inputs[1])
36823682
return nullptr;
36833683

3684-
// Don't change the key used in the call; we don't know what's valid.
3685-
if (II->getOperand(1) != PtrAuthBundleOrNone->Inputs[0])
3686-
return nullptr;
3687-
36883684
Value *NewBundleOps[] = {II->getOperand(1), II->getOperand(2)};
36893685
NewBundles.emplace_back("ptrauth", NewBundleOps);
36903686
NewCallee = II->getOperand(0);
@@ -3702,6 +3698,16 @@ Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) {
37023698
NewCallee = II->getOperand(0);
37033699
break;
37043700
}
3701+
3702+
// call(ptrauth.auth(p)) -> call p, ["ptrauth"()]
3703+
case Intrinsic::ptrauth_auth: {
3704+
if (PtrAuthBundleOrNone)
3705+
return nullptr;
3706+
Value *NewBundleOps[] = {II->getOperand(1), II->getOperand(2)};
3707+
NewBundles.emplace_back("ptrauth", NewBundleOps);
3708+
NewCallee = II->getOperand(0);
3709+
break;
3710+
}
37053711
}
37063712

37073713
if (!NewCallee)

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
286286
/// into the ptrauth call bundle:
287287
/// - call(ptrauth.resign(p)), ["ptrauth"()] -> call p, ["ptrauth"()]
288288
/// - call(ptrauth.sign(p)), ["ptrauth"()] -> call p
289-
/// as long as the key/discriminator are the same in sign and auth-bundle,
290-
/// and we don't change the key in the bundle (to a potentially-invalid key.)
289+
/// - call(ptrauth.auth(p)) -> call p, ["ptrauth"()]
290+
/// as long as the key/discriminator are the same in sign and auth-bundle.
291291
Instruction *foldPtrAuthIntrinsicCallee(CallBase &Call);
292292

293293
// Return (a, b) if (LHS, RHS) is known to be (a, b) or (b, a).

llvm/test/Transforms/InstCombine/ptrauth-intrinsics-call.ll

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,27 @@
33

44
define i32 @test_ptrauth_call_resign(ptr %p) {
55
; CHECK-LABEL: @test_ptrauth_call_resign(
6-
; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i32 1, i64 1234) ]
6+
; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i32 0, i64 1234) ]
77
; CHECK-NEXT: ret i32 [[V3]]
88
;
99
%v0 = ptrtoint ptr %p to i64
10-
%v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 1, i64 5678)
10+
%v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 0, i64 1234, i32 2, i64 5678)
1111
%v2 = inttoptr i64 %v1 to i32()*
12-
%v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ]
12+
%v3 = call i32 %v2() [ "ptrauth"(i32 2, i64 5678) ]
1313
ret i32 %v3
1414
}
1515

1616
define i32 @test_ptrauth_call_resign_blend(ptr %pp) {
1717
; CHECK-LABEL: @test_ptrauth_call_resign_blend(
1818
; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8
19-
; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 1, i64 1234) ]
19+
; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 0, i64 1234) ]
2020
; CHECK-NEXT: ret i32 [[V6]]
2121
;
2222
%v0 = load ptr, ptr %pp, align 8
2323
%v1 = ptrtoint ptr %pp to i64
2424
%v2 = ptrtoint ptr %v0 to i64
2525
%v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678)
26-
%v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 1, i64 1234, i32 1, i64 %v3)
26+
%v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 0, i64 1234, i32 1, i64 %v3)
2727
%v5 = inttoptr i64 %v4 to i32()*
2828
%v6 = call i32 %v5() [ "ptrauth"(i32 1, i64 %v3) ]
2929
ret i32 %v6
@@ -34,19 +34,31 @@ define i32 @test_ptrauth_call_resign_blend_2(ptr %pp) {
3434
; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8
3535
; CHECK-NEXT: [[V1:%.*]] = ptrtoint ptr [[PP]] to i64
3636
; CHECK-NEXT: [[V3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[V1]], i64 5678)
37-
; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 0, i64 [[V3]]) ]
37+
; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 1, i64 [[V3]]) ]
3838
; CHECK-NEXT: ret i32 [[V6]]
3939
;
4040
%v0 = load ptr, ptr %pp, align 8
4141
%v1 = ptrtoint ptr %pp to i64
4242
%v2 = ptrtoint ptr %v0 to i64
4343
%v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678)
44-
%v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 0, i64 %v3, i32 0, i64 1234)
44+
%v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 1, i64 %v3, i32 0, i64 1234)
4545
%v5 = inttoptr i64 %v4 to i32()*
4646
%v6 = call i32 %v5() [ "ptrauth"(i32 0, i64 1234) ]
4747
ret i32 %v6
4848
}
4949

50+
define i32 @test_ptrauth_call_auth(ptr %p) {
51+
; CHECK-LABEL: @test_ptrauth_call_auth(
52+
; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i32 2, i64 5678) ]
53+
; CHECK-NEXT: ret i32 [[V3]]
54+
;
55+
%v0 = ptrtoint ptr %p to i64
56+
%v1 = call i64 @llvm.ptrauth.auth(i64 %v0, i32 2, i64 5678)
57+
%v2 = inttoptr i64 %v1 to i32()*
58+
%v3 = call i32 %v2()
59+
ret i32 %v3
60+
}
61+
5062
define i32 @test_ptrauth_call_sign(ptr %p) {
5163
; CHECK-LABEL: @test_ptrauth_call_sign(
5264
; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]()

0 commit comments

Comments
 (0)