[llvm-branch-commits] [llvm] Add IR and codegen support for deactivation symbols. (PR #133536)

Peter Collingbourne via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Sep 11 12:39:48 PDT 2025


https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133536

>From f4c61b403c8a2c649741bae983196922143db44e Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <pcc at google.com>
Date: Wed, 10 Sep 2025 18:02:38 -0700
Subject: [PATCH 1/2] Tweak LangRef

Created using spr 1.3.6-beta.1
---
 llvm/docs/LangRef.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 10586f03cff8e..5380413aec892 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3098,7 +3098,8 @@ Deactivation Symbol Operand Bundles
 A ``"deactivation-symbol"`` operand bundle is valid on the following
 instructions (AArch64 only):
 
-- Call to a normal function with ``notail`` attribute.
+- Call to a normal function with ``notail`` attribute and a first argument and
+  return value of type ``ptr``.
 - Call to ``llvm.ptrauth.sign`` or ``llvm.ptrauth.auth`` intrinsics.
 
 This operand bundle specifies that if the deactivation symbol is defined

>From 0c2d97be43360d18f6e674bde048298a450a4bda Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <pcc at google.com>
Date: Thu, 11 Sep 2025 12:39:33 -0700
Subject: [PATCH 2/2] Add combine check

Created using spr 1.3.6-beta.1
---
 .../InstCombine/InstCombineCalls.cpp          | 10 +++++++
 .../InstCombine/ptrauth-intrinsics.ll         | 28 +++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 42b65dde67255..6550c6213dee5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3052,6 +3052,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
   }
   case Intrinsic::ptrauth_auth:
   case Intrinsic::ptrauth_resign: {
+    // We don't support this optimization on intrinsic calls with deactivation
+    // symbols, which are represented using operand bundles.
+    if (II->hasOperandBundles())
+      break;
+
     // (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;
@@ -3063,6 +3068,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     // whatever we replace this sequence with.
     Value *AuthKey = nullptr, *AuthDisc = nullptr, *BasePtr;
     if (const auto *CI = dyn_cast<CallBase>(Ptr)) {
+      // We don't support this optimization on intrinsic calls with deactivation
+      // symbols, which are represented using operand bundles.
+      if (CI->hasOperandBundles())
+        break;
+
       BasePtr = CI->getArgOperand(0);
       if (CI->getIntrinsicID() == Intrinsic::ptrauth_sign) {
         if (CI->getArgOperand(1) != Key || CI->getArgOperand(2) != Disc)
diff --git a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll
index 208e162ac9416..09d9649b09cc1 100644
--- a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll
@@ -160,6 +160,34 @@ define i64 @test_ptrauth_resign_ptrauth_constant(ptr %p) {
   ret i64 %authed
 }
 
+ at ds = external global i8
+
+define i64 @test_ptrauth_nop_ds1(ptr %p) {
+; CHECK-LABEL: @test_ptrauth_nop_ds1(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64
+; CHECK-NEXT:    [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 1, i64 1234) [ "deactivation-symbol"(ptr @ds) ]
+; CHECK-NEXT:    [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 1234)
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint ptr %p to i64
+  %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234) [ "deactivation-symbol"(ptr @ds) ]
+  %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234)
+  ret i64 %authed
+}
+
+define i64 @test_ptrauth_nop_ds2(ptr %p) {
+; CHECK-LABEL: @test_ptrauth_nop_ds2(
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[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 1234) [ "deactivation-symbol"(ptr @ds) ]
+; CHECK-NEXT:    ret i64 [[AUTHED]]
+;
+  %tmp0 = ptrtoint ptr %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) [ "deactivation-symbol"(ptr @ds) ]
+  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)



More information about the llvm-branch-commits mailing list