[llvm] bddd9b6 - [InstCombine] Combine ptrauth sign/resign + auth/resign intrinsics.

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 24 08:03:36 PDT 2022


Author: Ahmed Bougacha
Date: 2022-10-24T08:03:14-07:00
New Revision: bddd9b6b91ae4f042d12b083f1ab4e42f9f910b3

URL: https://github.com/llvm/llvm-project/commit/bddd9b6b91ae4f042d12b083f1ab4e42f9f910b3
DIFF: https://github.com/llvm/llvm-project/commit/bddd9b6b91ae4f042d12b083f1ab4e42f9f910b3.diff

LOG: [InstCombine] Combine ptrauth sign/resign + auth/resign intrinsics.

(sign|resign) + (auth|resign) can be folded by omitting the middle
sign+auth component if the key and discriminator match.

Differential Revision: https://reviews.llvm.org/D132383

Added: 
    llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index c347645969070..5adb898f26075 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2038,7 +2038,64 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     }
     break;
   }
+  case Intrinsic::ptrauth_auth:
+  case Intrinsic::ptrauth_resign: {
+    // (sign|resign) + (auth|resign) can be folded by omitting the middle
+    // sign+auth component if the key and discriminator match.
+    bool NeedSign = II->getIntrinsicID() == Intrinsic::ptrauth_resign;
+    Value *Key = II->getArgOperand(1);
+    Value *Disc = II->getArgOperand(2);
+
+    // AuthKey will be the key we need to end up authenticating against in
+    // whatever we replace this sequence with.
+    Value *AuthKey = nullptr, *AuthDisc = nullptr, *BasePtr;
+    if (auto CI = dyn_cast<CallBase>(II->getArgOperand(0))) {
+      BasePtr = CI->getArgOperand(0);
+      if (CI->getIntrinsicID() == Intrinsic::ptrauth_sign) {
+        if (CI->getArgOperand(1) != Key || CI->getArgOperand(2) != Disc)
+          break;
+      } else if (CI->getIntrinsicID() == Intrinsic::ptrauth_resign) {
+        if (CI->getArgOperand(3) != Key || CI->getArgOperand(4) != Disc)
+          break;
+        AuthKey = CI->getArgOperand(1);
+        AuthDisc = CI->getArgOperand(2);
+      } else
+        break;
+    } else
+      break;
 
+    unsigned NewIntrin;
+    if (AuthKey && NeedSign) {
+      // resign(0,1) + resign(1,2) = resign(0, 2)
+      NewIntrin = Intrinsic::ptrauth_resign;
+    } else if (AuthKey) {
+      // resign(0,1) + auth(1) = auth(0)
+      NewIntrin = Intrinsic::ptrauth_auth;
+    } else if (NeedSign) {
+      // sign(0) + resign(0, 1) = sign(1)
+      NewIntrin = Intrinsic::ptrauth_sign;
+    } else {
+      // sign(0) + auth(0) = nop
+      replaceInstUsesWith(*II, BasePtr);
+      eraseInstFromFunction(*II);
+      return nullptr;
+    }
+
+    SmallVector<Value *, 4> CallArgs;
+    CallArgs.push_back(BasePtr);
+    if (AuthKey) {
+      CallArgs.push_back(AuthKey);
+      CallArgs.push_back(AuthDisc);
+    }
+
+    if (NeedSign) {
+      CallArgs.push_back(II->getArgOperand(3));
+      CallArgs.push_back(II->getArgOperand(4));
+    }
+
+    Function *NewFn = Intrinsic::getDeclaration(II->getModule(), NewIntrin);
+    return CallInst::Create(NewFn, CallArgs);
+  }
   case Intrinsic::arm_neon_vtbl1:
   case Intrinsic::aarch64_neon_tbl1:
     if (Value *V = simplifyNeonTbl1(*II, Builder))

diff  --git a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll
new file mode 100644
index 0000000000000..ded5123acd63e
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll
@@ -0,0 +1,92 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define i64 @test_ptrauth_nop(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_nop(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    ret i64 [[TMP0]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234)
+  %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_nop_mismatch(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_nop_mismatch(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 1, i64 1234)
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 10)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234)
+  %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 10)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_nop_mismatch_keys(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_nop_mismatch_keys(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 0, i64 1234)
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 1234)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 0, i64 1234)
+  %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_sign_resign(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_sign_resign(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 0, i64 42)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234)
+  %authed = call i64 @llvm.ptrauth.resign(i64 %signed, i32 1, i64 1234, i32 0, i64 42)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_resign_resign(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_resign_resign(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TMP0]], i32 1, i64 1234, i32 1, i64 3141)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 42)
+  %authed = call i64 @llvm.ptrauth.resign(i64 %signed, i32 0, i64 42, i32 1, i64 3141)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_resign_auth(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_resign_auth(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP0]], i32 1, i64 1234)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 42)
+  %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 0, i64 42)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_resign_auth_mismatch(i8* %p) {
+; CHECK-LABEL: @test_ptrauth_resign_auth_mismatch(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[P:%.*]] to i64
+; CHECK-NEXT:    [[SIGNED:%.*]] = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 10)
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 %signed, i32 0, i64 42)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint i8* %p to i64
+  %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 10)
+  %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 0, i64 42)
+  ret i64 %authed
+}
+
+declare i64 @llvm.ptrauth.auth(i64, i32, i64)
+declare i64 @llvm.ptrauth.sign(i64, i32, i64)
+declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64)
\ No newline at end of file


        


More information about the llvm-commits mailing list