[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