[llvm] [ObjcARCContract] Do not replace llvm.lifetime argument. (PR #216991)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 04:23:26 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

Only alloca or poison is allowed as arguments for lifetime intrinsics. Before replacing, check if the operand can be replaced with a variable and skip replacement if it is not valid.

Fixes a verifier crash in the added test case.

---
Full diff: https://github.com/llvm/llvm-project/pull/216991.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp (+5) 
- (modified) llvm/test/Transforms/ObjCARC/contract-replace-arg-use.ll (+23) 


``````````diff
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 95a9bcb839ee4..43b2bec86bdce 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -44,6 +44,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/Utils/Local.h"
 
 using namespace llvm;
 using namespace llvm::objcarc;
@@ -651,6 +652,10 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
         Use &U = *UI++;
         unsigned OperandNo = U.getOperandNo();
 
+        if (!canReplaceOperandWithVariable(cast<Instruction>(U.getUser()),
+                                           OperandNo))
+          continue;
+
         // If the call's return value dominates a use of the call's argument
         // value, rewrite the use to use the return value. We check for
         // reachability here because an unreachable call is considered to
diff --git a/llvm/test/Transforms/ObjCARC/contract-replace-arg-use.ll b/llvm/test/Transforms/ObjCARC/contract-replace-arg-use.ll
index 47a88925bdb33..557c05aadbd16 100644
--- a/llvm/test/Transforms/ObjCARC/contract-replace-arg-use.ll
+++ b/llvm/test/Transforms/ObjCARC/contract-replace-arg-use.ll
@@ -39,3 +39,26 @@ bb3:
   %v4 = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr %phival)
   ret ptr %retval
 }
+
+declare ptr @llvm.objc.retain(ptr)
+declare void @use_pointer(ptr)
+
+; The pointer operand of a lifetime intrinsic has to be an alloca, so it must
+; not be replaced by the value returned by @llvm.objc.retain.
+
+; CHECK-LABEL: define void @lifetimeOfRetainedAlloca(
+; CHECK: %[[BLOCK:.*]] = alloca ptr, align 8
+; CHECK: call void @llvm.lifetime.start.p0(ptr %[[BLOCK]])
+; CHECK: %[[V0:.*]] = call ptr @llvm.objc.retain(ptr %[[BLOCK]])
+; CHECK: call void @use_pointer(ptr %[[V0]])
+; CHECK: call void @llvm.lifetime.end.p0(ptr %[[BLOCK]])
+
+define void @lifetimeOfRetainedAlloca() {
+entry:
+  %block = alloca ptr, align 8
+  call void @llvm.lifetime.start.p0(ptr %block)
+  %v0 = call ptr @llvm.objc.retain(ptr %block)
+  call void @use_pointer(ptr %block)
+  call void @llvm.lifetime.end.p0(ptr %block)
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/216991


More information about the llvm-commits mailing list