From de0d4747fefa249c26ff46ccac85e15fde354683 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 3 Apr 2025 23:44:32 +0700 Subject: [PATCH 1/2] ObjCARCContract: Use stripPointerCastsAndAliases --- .../Transforms/ObjCARC/ObjCARCContract.cpp | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index e11748b2c9dbb..ed7a235f5e2e3 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -661,30 +661,16 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { Value *Arg = cast(Inst)->getArgOperand(0); - // TODO: Change this to a do-while. - for (;;) { - ReplaceArgUses(Arg); - - // If Arg is a no-op casted pointer, strip one level of casts and iterate. - if (const BitCastInst *BI = dyn_cast(Arg)) - Arg = BI->getOperand(0); - else if (isa(Arg) && - cast(Arg)->hasAllZeroIndices()) - Arg = cast(Arg)->getPointerOperand(); - else if (isa(Arg) && - !cast(Arg)->isInterposable()) - Arg = cast(Arg)->getAliasee(); - else { - // If Arg is a PHI node, get PHIs that are equivalent to it and replace - // their uses. - if (PHINode *PN = dyn_cast(Arg)) { - SmallVector PHIList; - getEquivalentPHIs(*PN, PHIList); - for (Value *PHI : PHIList) - ReplaceArgUses(PHI); - } - break; - } + ReplaceArgUses(Arg); + + Arg = Arg->stripPointerCastsAndAliases(); + // If Arg is a PHI node, get PHIs that are equivalent to it and replace + // their uses. + if (PHINode *PN = dyn_cast(Arg)) { + SmallVector PHIList; + getEquivalentPHIs(*PN, PHIList); + for (Value *PHI : PHIList) + ReplaceArgUses(PHI); } } From cfd252525aa84e2f8c6f9f7a1daf66ad21f65bd9 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sat, 12 Apr 2025 09:09:04 +0200 Subject: [PATCH 2/2] Fix new test --- llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp | 8 +++++--- llvm/test/Transforms/ObjCARC/contract.ll | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index ed7a235f5e2e3..79d04bfa57d74 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -660,13 +660,15 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { }; Value *Arg = cast(Inst)->getArgOperand(0); - ReplaceArgUses(Arg); - Arg = Arg->stripPointerCastsAndAliases(); + Value *Stripped = Arg->stripPointerCastsAndAliases(); + if (Stripped != Arg) + ReplaceArgUses(Stripped); + // If Arg is a PHI node, get PHIs that are equivalent to it and replace // their uses. - if (PHINode *PN = dyn_cast(Arg)) { + if (PHINode *PN = dyn_cast(Stripped)) { SmallVector PHIList; getEquivalentPHIs(*PN, PHIList); for (Value *PHI : PHIList) diff --git a/llvm/test/Transforms/ObjCARC/contract.ll b/llvm/test/Transforms/ObjCARC/contract.ll index 70bd57a0c719a..24f9a712ccd0a 100644 --- a/llvm/test/Transforms/ObjCARC/contract.ll +++ b/llvm/test/Transforms/ObjCARC/contract.ll @@ -234,6 +234,22 @@ define void @test14(ptr %a, ptr %b) { ret void } +define void @test15(ptr %x) { +; CHECK-LABEL: define void @test15( +; CHECK-SAME: ptr [[X:%.*]]) { +; CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds ptr, ptr [[X]], i32 0 +; CHECK-NEXT: [[V0:%.*]] = call ptr @llvm.objc.retain(ptr [[Y]]) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: call void @use_pointer(ptr [[V0]]) +; CHECK-NEXT: call void @use_pointer(ptr [[V0]]) +; CHECK-NEXT: ret void +; + %y = getelementptr inbounds ptr, ptr %x, i32 0 + %v0 = call ptr @llvm.objc.retain(ptr %y) nounwind + call void @use_pointer(ptr %x) + call void @use_pointer(ptr %y) + ret void +} + declare void @llvm.objc.clang.arc.use(...) nounwind declare void @llvm.objc.clang.arc.noop.use(...) nounwind