https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/173694
>From ba9d3c13c2efe720833d62f1c6cbc150eb399ceb Mon Sep 17 00:00:00 2001 From: Aiden Grossman <[email protected]> Date: Sat, 27 Dec 2025 02:05:36 +0000 Subject: [PATCH 1/3] formatting Created using spr 1.3.7 --- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 25d473b5beb72..78734beac4bbe 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1214,7 +1214,8 @@ struct DSEState { return OW_None; } - bool isInvisibleToCallerAfterRet(const Value *V, const Value *Ptr, const LocationSize StoreSize) { + bool isInvisibleToCallerAfterRet(const Value *V, const Value *Ptr, + const LocationSize StoreSize) { if (isa<AllocaInst>(V)) return true; @@ -1774,7 +1775,8 @@ struct DSEState { BasicBlock *MaybeKillingBlock = UseInst->getParent(); if (PostOrderNumbers.find(MaybeKillingBlock)->second < PostOrderNumbers.find(MaybeDeadAccess->getBlock())->second) { - if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr, KillingLoc.Size)) { + if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr, + KillingLoc.Size)) { LLVM_DEBUG(dbgs() << " ... found killing def " << *UseInst << "\n"); KillingDefs.insert(UseInst); @@ -1792,7 +1794,8 @@ struct DSEState { // For accesses to locations visible after the function returns, make sure // that the location is dead (=overwritten) along all paths from // MaybeDeadAccess to the exit. - if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr, KillingLoc.Size)) { + if (!isInvisibleToCallerAfterRet(KillingUndObj, KillingLoc.Ptr, + KillingLoc.Size)) { SmallPtrSet<BasicBlock *, 16> KillingBlocks; for (Instruction *KD : KillingDefs) KillingBlocks.insert(KD->getParent()); >From 805d7b8f4c1bb9d394a6d0760bc7de2a274fda30 Mon Sep 17 00:00:00 2001 From: Aiden Grossman <[email protected]> Date: Wed, 14 Jan 2026 17:22:23 +0000 Subject: [PATCH 2/3] feedback Created using spr 1.3.7 --- .../Scalar/DeadStoreElimination.cpp | 27 ++++++++++------ .../Transforms/DeadStoreElimination/simple.ll | 31 +++++++++++++++++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 78734beac4bbe..20436b92412f9 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1018,16 +1018,19 @@ struct DSEState { // Treat byval, inalloca or dead on return arguments the same as Allocas, // stores to them are dead at the end of the function. for (Argument &AI : F.args()) { - if (AI.hasPassPointeeByValueCopyAttr() || - (AI.getType()->isPointerTy() && - AI.getDeadOnReturnInfo().coversAllReachableMemory())) + if (AI.hasPassPointeeByValueCopyAttr()) { InvisibleToCallerAfterRet.insert({&AI, true}); - if (AI.getType()->isPointerTy() && - !AI.getDeadOnReturnInfo().coversAllReachableMemory()) { - if (uint64_t DeadOnReturnBytes = - AI.getDeadOnReturnInfo().getNumberOfDeadBytes()) - InvisibleToCallerAfterRetBounded.insert({&AI, DeadOnReturnBytes}); + continue; } + + if (!AI.getType()->isPointerTy()) + continue; + + const DeadOnReturnInfo &Info = AI.getDeadOnReturnInfo(); + if (Info.coversAllReachableMemory()) + InvisibleToCallerAfterRet.insert({&AI, true}); + else if (uint64_t DeadBytes = Info.getNumberOfDeadBytes()) + InvisibleToCallerAfterRetBounded.insert({&AI, DeadBytes}); } // Collect whether there is any irreducible control flow in the function. @@ -1225,8 +1228,11 @@ struct DSEState { const Value *BaseValue = GetPointerBaseWithConstantOffset(Ptr, ValueOffset, DL); assert(BaseValue == V); - if (ValueOffset + StoreSize.toRaw() < - InvisibleToCallerAfterRetBounded[BaseValue]) + // This store is only invisible after return if we are in bounds of the + // range marked dead. + if (ValueOffset + StoreSize.getValue() <= + InvisibleToCallerAfterRetBounded[BaseValue] && + ValueOffset >= 0) return true; } if (I.second && isInvisibleToCallerOnUnwind(V) && isNoAliasCall(V)) @@ -1899,6 +1905,7 @@ struct DSEState { if (CapturedBeforeReturn.erase(UO)) ShouldIterateEndOfFunctionDSE = true; InvisibleToCallerAfterRet.erase(UO); + InvisibleToCallerAfterRetBounded.erase(UO); } } } diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index 7619842ea18cf..855cae3f70259 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -901,6 +901,18 @@ define void @test_dead_on_return_oob(ptr dead_on_return(4) %p) { ret void } +define void @test_dead_on_return_zero_offset(ptr dead_on_return(8) %p) { +; CHECK-LABEL: @test_dead_on_return_zero_offset( +; CHECK-NEXT: [[LOCAL_VAR:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: call void @opaque(ptr [[LOCAL_VAR]]) +; CHECK-NEXT: ret void +; + %local.var = alloca ptr + call void @opaque(ptr %local.var) + store ptr %local.var, ptr %p + ret void +} + define void @test_dead_on_return_inbounds(ptr dead_on_return(16) %p) { ; CHECK-LABEL: @test_dead_on_return_inbounds( ; CHECK-NEXT: [[LOCAL_VAR:%.*]] = alloca ptr, align 8 @@ -914,8 +926,8 @@ define void @test_dead_on_return_inbounds(ptr dead_on_return(16) %p) { ret void } -define void @test_on_return_overlapping_oob(ptr dead_on_return(8) %p) { -; CHECK-LABEL: @test_on_return_overlapping_oob( +define void @test_dead_on_return_overlapping_oob(ptr dead_on_return(8) %p) { +; CHECK-LABEL: @test_dead_on_return_overlapping_oob( ; CHECK-NEXT: [[LOCAL_VAR:%.*]] = alloca ptr, align 8 ; CHECK-NEXT: call void @opaque(ptr [[LOCAL_VAR]]) ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 4 @@ -929,5 +941,20 @@ define void @test_on_return_overlapping_oob(ptr dead_on_return(8) %p) { ret void } +define void @test_dead_on_return_negative_oob(ptr dead_on_return(8) %p) { +; CHECK-LABEL: @test_dead_on_return_negative_oob( +; CHECK-NEXT: [[LOCAL_VAR:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: call void @opaque(ptr [[LOCAL_VAR]]) +; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 -4 +; CHECK-NEXT: store ptr [[LOCAL_VAR]], ptr [[P1]], align 8 +; CHECK-NEXT: ret void +; + %local.var = alloca ptr + call void @opaque(ptr %local.var) + %p1 = getelementptr inbounds i8, ptr %p, i64 -4 + store ptr %local.var, ptr %p1 + ret void +} + declare void @opaque(ptr) declare void @maythrow() memory(none) >From f7ac1841ce7dacff0fdc64d9a99ef228ce0d9145 Mon Sep 17 00:00:00 2001 From: Aiden Grossman <[email protected]> Date: Thu, 15 Jan 2026 01:57:11 +0000 Subject: [PATCH 3/3] feedback Created using spr 1.3.7 --- .../lib/Transforms/Scalar/DeadStoreElimination.cpp | 4 ++-- .../test/Transforms/DeadStoreElimination/simple.ll | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 20436b92412f9..4a313230c2003 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1222,8 +1222,7 @@ struct DSEState { if (isa<AllocaInst>(V)) return true; - auto I = InvisibleToCallerAfterRet.insert({V, false}); - if (I.second && InvisibleToCallerAfterRetBounded.contains(V)) { + if (InvisibleToCallerAfterRetBounded.contains(V)) { int64_t ValueOffset; const Value *BaseValue = GetPointerBaseWithConstantOffset(Ptr, ValueOffset, DL); @@ -1235,6 +1234,7 @@ struct DSEState { ValueOffset >= 0) return true; } + auto I = InvisibleToCallerAfterRet.insert({V, false}); if (I.second && isInvisibleToCallerOnUnwind(V) && isNoAliasCall(V)) I.first->second = capturesNothing(PointerMayBeCaptured( V, /*ReturnCaptures=*/true, CaptureComponents::Provenance)); diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index 855cae3f70259..cf3d9ad4bd316 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -956,5 +956,19 @@ define void @test_dead_on_return_negative_oob(ptr dead_on_return(8) %p) { ret void } +define void @test_dead_on_return_two_stores(ptr dead_on_return(16) %p) { +; CHECK-LABEL: @test_dead_on_return_two_stores( +; CHECK-NEXT: [[LOCAL_VAR:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: call void @opaque(ptr [[LOCAL_VAR]]) +; CHECK-NEXT: ret void +; + %local.var = alloca ptr + call void @opaque(ptr %local.var) + store ptr %local.var, ptr %p + %p1 = getelementptr inbounds i8, ptr %p, i64 8 + store ptr %local.var, ptr %p1 + ret void +} + declare void @opaque(ptr) declare void @maythrow() memory(none) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
