[llvm] db284df - [Analysis] use forward DFS in `isEphemeralValueOf` (#196232)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 08:59:01 PDT 2026
Author: Iris Shi
Date: 2026-05-07T23:50:31+08:00
New Revision: db284dfe4ff0edfc9335a1f631f47c5428d34936
URL: https://github.com/llvm/llvm-project/commit/db284dfe4ff0edfc9335a1f631f47c5428d34936
DIFF: https://github.com/llvm/llvm-project/commit/db284dfe4ff0edfc9335a1f631f47c5428d34936.diff
LOG: [Analysis] use forward DFS in `isEphemeralValueOf` (#196232)
Resolves #128152.
The old algorithm runs a backward DFS from `I` and marks `E` as
ephemeral iff every user of `E` has already been visited. This fails
when `E` has a user that the backward walk never reaches. Switch to a
forward DFS from `E` so that ephemeral values are identified when the
condition has other uses off the assume chain.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5635c435417dd..91ad517f194a6 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -608,40 +608,39 @@ void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
}
static bool isEphemeralValueOf(const Instruction *I, const Value *E) {
- SmallVector<const Instruction *, 16> WorkSet(1, I);
- SmallPtrSet<const Instruction *, 32> Visited;
- SmallPtrSet<const Instruction *, 16> EphValues;
-
// The instruction defining an assumption's condition itself is always
// considered ephemeral to that assumption (even if it has other
// non-ephemeral users). See r246696's test case for an example.
if (is_contained(I->operands(), E))
return true;
- while (!WorkSet.empty()) {
- const Instruction *V = WorkSet.pop_back_val();
- if (!Visited.insert(V).second)
- continue;
-
- // If all uses of this value are ephemeral, then so is this value.
- if (all_of(V->users(), [&](const User *U) {
- return EphValues.count(cast<Instruction>(U));
- })) {
- if (V == E)
- return true;
+ const auto *EI = dyn_cast<Instruction>(E);
+ if (!EI)
+ return false;
- if (V == I || (!V->mayHaveSideEffects() && !V->isTerminator())) {
- EphValues.insert(V);
+ if (EI == I)
+ return true;
- for (const Use &U : V->operands()) {
- if (const auto *I = dyn_cast<Instruction>(U.get()))
- WorkSet.push_back(I);
- }
+ SmallPtrSet<const Instruction *, 16> Visited;
+ SmallVector<const Instruction *, 16> WorkList;
+ Visited.insert(EI);
+ WorkList.push_back(EI);
+ bool ReachesI = false;
+ while (!WorkList.empty()) {
+ const Instruction *V = WorkList.pop_back_val();
+ for (const User *U : V->users()) {
+ const auto *UI = cast<Instruction>(U);
+ if (UI == I) {
+ ReachesI = true;
+ continue;
}
+ if (UI->mayHaveSideEffects() || UI->isTerminator())
+ return false;
+ if (Visited.insert(UI).second)
+ WorkList.push_back(UI);
}
}
-
- return false;
+ return ReachesI;
}
// Is this an intrinsic that cannot be speculated but also cannot trap?
diff --git a/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll b/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
index 92e43654806a4..fce04ec862321 100644
--- a/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
+++ b/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
@@ -119,6 +119,23 @@ define i64 @ctpop_x_and_negx_nz(i64 %x) {
ret i64 %cnt
}
+; issue #128152
+define i1 @ctpop_assume_eq_1_extra_use(i32 %x) {
+; CHECK-LABEL: @ctpop_assume_eq_1_extra_use(
+; CHECK-NEXT: [[CTPOP:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]])
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[CTPOP]], 1
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT: ret i1 [[RES]]
+;
+ %ctpop = call i32 @llvm.ctpop.i32(i32 %x)
+ %cond = icmp eq i32 %ctpop, 1
+ %ext = zext i1 %cond to i8
+ call void @llvm.assume(i1 %cond)
+ %res = icmp eq i32 %x, 0
+ ret i1 %res
+}
+
define <2 x i32> @ctpop_shl1_vec(<2 x i32> %x) {
; CHECK-LABEL: @ctpop_shl1_vec(
; CHECK-NEXT: ret <2 x i32> splat (i32 1)
More information about the llvm-commits
mailing list