[llvm] [LoopVectorize] Fix an integer narrowing conversion in `getPredBlockCostDivisor(...)` (PR #187605)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 19 15:52:56 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-vectorizers
@llvm/pr-subscribers-llvm-transforms
Author: Alan Zhao (alanzhao1)
<details>
<summary>Changes</summary>
`LoopVectorizationCostModel::getPredBlockCostDivisor(...)` may return large `uint64_t` values that get coerced to an `unsigned` by `VPCostContext::getPredBlockCostDivisor(...)`, which can cause division by zero.
Fixes #<!-- -->187584
---
Full diff: https://github.com/llvm/llvm-project/pull/187605.diff
3 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+1-1)
- (modified) llvm/lib/Transforms/Vectorize/VPlanHelpers.h (+1-1)
- (added) llvm/test/Transforms/LoopVectorize/cost-divisor-overflow.ll (+68)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index c4b5b40578a6e..229b410992c67 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6885,7 +6885,7 @@ bool VPCostContext::skipCostComputation(Instruction *UI, bool IsVector) const {
SkipCostComputation.contains(UI);
}
-unsigned VPCostContext::getPredBlockCostDivisor(BasicBlock *BB) const {
+uint64_t VPCostContext::getPredBlockCostDivisor(BasicBlock *BB) const {
return CM.getPredBlockCostDivisor(CostKind, BB);
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanHelpers.h b/llvm/lib/Transforms/Vectorize/VPlanHelpers.h
index 113ca8c4d0f7c..0d4a842c700f6 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanHelpers.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanHelpers.h
@@ -366,7 +366,7 @@ struct VPCostContext {
/// \returns how much the cost of a predicated block should be divided by.
/// Forwards to LoopVectorizationCostModel::getPredBlockCostDivisor.
- unsigned getPredBlockCostDivisor(BasicBlock *BB) const;
+ uint64_t getPredBlockCostDivisor(BasicBlock *BB) const;
/// Returns the OperandInfo for \p V, if it is a live-in.
TargetTransformInfo::OperandValueInfo getOperandInfo(VPValue *V) const;
diff --git a/llvm/test/Transforms/LoopVectorize/cost-divisor-overflow.ll b/llvm/test/Transforms/LoopVectorize/cost-divisor-overflow.ll
new file mode 100644
index 0000000000000..1e836ac07974f
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/cost-divisor-overflow.ll
@@ -0,0 +1,68 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
+; RUN: opt < %s -passes=loop-vectorize -S | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-grtev4-linux-gnu"
+
+; Tests that the computed predicate block cost divisor doesn't get coerced to
+; zero and cause a division by zero error.
+; See https://github.com/llvm/llvm-project/issues/187584
+define void @wombat() {
+; CHECK-LABEL: define void @wombat() {
+; CHECK-NEXT: [[BB:.*]]:
+; CHECK-NEXT: br label %[[BB2:.*]]
+; CHECK: [[BB1:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[BB2]]:
+; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[ADD:%.*]], %[[BB6:.*]] ], [ 0, %[[BB]] ]
+; CHECK-NEXT: [[PHI3:%.*]] = phi i64 [ [[PHI7:%.*]], %[[BB6]] ], [ 0, %[[BB]] ]
+; CHECK-NEXT: br i1 true, label %[[BB4:.*]], label %[[BB6]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: br i1 false, label %[[BB6]], label %[[BB5:.*]], !prof [[PROF0:![0-9]+]]
+; CHECK: [[BB5]]:
+; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr null, align 8
+; CHECK-NEXT: [[CALL:%.*]] = call i64 @llvm.smin.i64(i64 [[LOAD]], i64 [[PHI3]])
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[PHI7]] = phi i64 [ [[PHI3]], %[[BB4]] ], [ [[CALL]], %[[BB5]] ], [ [[PHI3]], %[[BB2]] ]
+; CHECK-NEXT: [[ADD]] = add i64 [[PHI]], 1
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[PHI]], 1
+; CHECK-NEXT: br i1 [[ICMP]], label %[[BB1]], label %[[BB2]]
+;
+bb:
+ br label %bb2
+
+bb1: ; preds = %bb6
+ ret void
+
+bb2: ; preds = %bb6, %bb
+ %phi = phi i64 [ %add, %bb6 ], [ 0, %bb ]
+ %phi3 = phi i64 [ %phi7, %bb6 ], [ 0, %bb ]
+ br i1 true, label %bb4, label %bb6
+
+bb4: ; preds = %bb2
+ br i1 false, label %bb6, label %bb5, !prof !0
+
+bb5: ; preds = %bb4
+ %load = load i64, ptr null, align 8
+ %call = call i64 @llvm.smin.i64(i64 %load, i64 %phi3)
+ br label %bb6
+
+bb6: ; preds = %bb5, %bb4, %bb2
+ %phi7 = phi i64 [ %phi3, %bb4 ], [ %call, %bb5 ], [ %phi3, %bb2 ]
+ %add = add i64 %phi, 1
+ %icmp = icmp eq i64 %phi, 1
+ br i1 %icmp, label %bb1, label %bb2
+}
+
+; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
+declare i64 @llvm.smin.i64(i64, i64) #0
+
+attributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+
+!0 = !{!"branch_weights", i32 -2147483648, i32 0}
+;.
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.
+; CHECK: [[PROF0]] = !{!"branch_weights", i32 -2147483648, i32 0}
+;.
``````````
</details>
https://github.com/llvm/llvm-project/pull/187605
More information about the llvm-commits
mailing list