[llvm] [VPlan] Strip erroneous poisonGuaranteesUB (PR #189374)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 06:10:30 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
A mysterious poisonGuaranteesUB was introduced in 2f7e218 ([VPlan] Add missing sext(sub) SCEV fold to getSCEVExprForVPValue) as part of a bugfix for handling of sext(sub nsw) in getSCEVExprForVPValue. Although the associated comment claims that the code mirrors SCEV's handling, the corresponding code in SCEV has no such poison-guarantees-UB checking. Moreover, poisonGuaranteesUB matches GEPs and casts non-exhaustively, and hence incorrectly. The added test case sext_sub_nsw_for_address only incidentally satisfies poisonGuaranteesUB, and stripping the routine has no impact on the test. Hence, strip the erroneous routine altogether.
---
Full diff: https://github.com/llvm/llvm-project/pull/189374.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/VPlanUtils.cpp (+1-56)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/induction-costs.ll (+1-2)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 60f931a524cbb..c9919c017fc62 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -83,61 +83,6 @@ bool vputils::isHeaderMask(const VPValue *V, const VPlan &Plan) {
B == Plan.getBackedgeTakenCount();
}
-/// Returns true if \p R propagates poison from any operand to its result.
-static bool propagatesPoisonFromRecipeOp(const VPRecipeBase *R) {
- return TypeSwitch<const VPRecipeBase *, bool>(R)
- .Case<VPWidenGEPRecipe, VPWidenCastRecipe>(
- [](const VPRecipeBase *) { return true; })
- .Case([](const VPReplicateRecipe *Rep) {
- // GEP and casts propagate poison from all operands.
- unsigned Opcode = Rep->getOpcode();
- return Opcode == Instruction::GetElementPtr ||
- Instruction::isCast(Opcode);
- })
- .Default([](const VPRecipeBase *) { return false; });
-}
-
-/// Returns true if \p V being poison is guaranteed to trigger UB because it
-/// propagates to the address of a memory recipe.
-static bool poisonGuaranteesUB(const VPValue *V) {
- SmallPtrSet<const VPValue *, 8> Visited;
- SmallVector<const VPValue *, 16> Worklist;
-
- Worklist.push_back(V);
-
- while (!Worklist.empty()) {
- const VPValue *Current = Worklist.pop_back_val();
- if (!Visited.insert(Current).second)
- continue;
-
- for (VPUser *U : Current->users()) {
- // Check if Current is used as an address operand for load/store.
- if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(U)) {
- if (MemR->getAddr() == Current)
- return true;
- continue;
- }
- if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
- unsigned Opcode = Rep->getOpcode();
- if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
- (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
- return true;
- }
-
- // Check if poison propagates through this recipe to any of its users.
- auto *R = cast<VPRecipeBase>(U);
- for (const VPValue *Op : R->operands()) {
- if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
- Worklist.push_back(R->getVPSingleValue());
- break;
- }
- }
- }
- }
-
- return false;
-}
-
const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
PredicatedScalarEvolution &PSE,
const Loop *L) {
@@ -217,7 +162,7 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
VPValue *SubLHS, *SubRHS;
auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
- SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
+ SubR->hasNoSignedWrap()) {
const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
if (!isa<SCEVCouldNotCompute>(V1) && !isa<SCEVCouldNotCompute>(V2))
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/induction-costs.ll b/llvm/test/Transforms/LoopVectorize/AArch64/induction-costs.ll
index 2e640e2d22658..e84abc749baa9 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/induction-costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/induction-costs.ll
@@ -516,8 +516,7 @@ exit:
; Test that sext(sub nsw) used in address computation is handled correctly
; in VPlan cost model (must match SCEV's handling).
-define void at sext_sub_nsw_for_address(ptr %base, i64 %n, ptr %src) #0 {
-;
+define void @sext_sub_nsw_for_address(ptr %base, i64 %n, ptr %src) #0 {
; CHECK-LABEL: define void @sext_sub_nsw_for_address(
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[N:%.*]], ptr [[SRC:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ITER_CHECK:.*]]:
``````````
</details>
https://github.com/llvm/llvm-project/pull/189374
More information about the llvm-commits
mailing list