[llvm] [LoopUnroll] Bound automatic full-unroll cloning work (PR #211683)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 29 16:52:50 PDT 2026
https://github.com/khaki3 updated https://github.com/llvm/llvm-project/pull/211683
>From c9690386d28d9f19658065f7ae9c6f1db7883edb Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Thu, 23 Jul 2026 15:13:27 -0700
Subject: [PATCH 1/2] [LoopUnroll] Bound automatic full-unroll cloning work
Prevent precise profitability analysis from selecting automatic full unrolls whose transient cloning work can cause pathological compile times, while preserving explicit requests and target overrides.
---
.../llvm/Analysis/TargetTransformInfo.h | 3 +
llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 29 +++-
.../LoopUnroll/full-unroll-cloning-cost.ll | 149 ++++++++++++++++++
3 files changed, 178 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 107ae4dba5075..7f4baa6f24676 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -701,6 +701,9 @@ class TargetTransformInfo {
/// applies even if full unrolling is selected. This allows a target to fall
/// back to Partial unrolling if full unrolling is above FullUnrollMaxCount.
unsigned FullUnrollMaxCount;
+ /// Set the maximum estimated instructions cloned by automatic full
+ /// unrolling. Set to UINT64_MAX to disable.
+ uint64_t FullUnrollMaxClonedInstructions;
// Represents number of instructions optimized when "back edge"
// becomes "fall through" in unrolled loop.
// For now we count a conditional branch on a backedge and a comparison
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
index ad3b123f3327c..66970b87fd955 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -122,6 +122,11 @@ static cl::opt<unsigned> UnrollFullMaxCount(
cl::desc(
"Set the max unroll count for full unrolling, for testing purposes"));
+static cl::opt<uint64_t> UnrollFullMaxClonedInstructions(
+ "unroll-full-max-cloned-instructions", cl::init(100'000), cl::Hidden,
+ cl::desc("Maximum estimated instructions cloned by automatic full "
+ "unrolling"));
+
static cl::opt<bool>
UnrollAllowPartial("unroll-allow-partial", cl::Hidden,
cl::desc("Allows loops to be partially unrolled until "
@@ -206,6 +211,7 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
UP.MaxCount = std::numeric_limits<unsigned>::max();
UP.MaxUpperBound = UnrollMaxUpperBound;
UP.FullUnrollMaxCount = std::numeric_limits<unsigned>::max();
+ UP.FullUnrollMaxClonedInstructions = UnrollFullMaxClonedInstructions;
UP.BEInsns = 2;
UP.Partial = false;
UP.Runtime = false;
@@ -249,6 +255,8 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
UP.MaxUpperBound = UnrollMaxUpperBound;
if (UnrollFullMaxCount.getNumOccurrences() > 0)
UP.FullUnrollMaxCount = UnrollFullMaxCount;
+ if (UnrollFullMaxClonedInstructions.getNumOccurrences() > 0)
+ UP.FullUnrollMaxClonedInstructions = UnrollFullMaxClonedInstructions;
if (UnrollAllowPartial.getNumOccurrences() > 0)
UP.Partial = UnrollAllowPartial;
if (UnrollAllowRemainder.getNumOccurrences() > 0)
@@ -905,7 +913,7 @@ static std::optional<unsigned> shouldFullUnroll(
Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT,
ScalarEvolution &SE, const SmallPtrSetImpl<const Value *> &EphValues,
const unsigned FullUnrollTripCount, const UnrollCostEstimator UCE,
- const TargetTransformInfo::UnrollingPreferences &UP) {
+ const TargetTransformInfo::UnrollingPreferences &UP, bool ExplicitUnroll) {
assert(FullUnrollTripCount && "should be non-zero!");
if (FullUnrollTripCount > UP.FullUnrollMaxCount) {
@@ -918,6 +926,19 @@ static std::optional<unsigned> shouldFullUnroll(
// When computing the unrolled size, note that BEInsns are not replicated
// like the rest of the loop body.
uint64_t UnrolledSize = UCE.getUnrolledLoopSize(UP, FullUnrollTripCount);
+ uint64_t LoopInstructionCount = 0;
+ for (const BasicBlock *BB : L->blocks())
+ LoopInstructionCount += BB->size();
+ uint64_t AdditionalCopies = FullUnrollTripCount - 1;
+ if (!ExplicitUnroll && UP.Threshold != NoThreshold && AdditionalCopies &&
+ LoopInstructionCount >
+ UP.FullUnrollMaxClonedInstructions / AdditionalCopies) {
+ LLVM_DEBUG(dbgs().indent(2)
+ << "Not unrolling: estimated cloned instructions exceed "
+ << UP.FullUnrollMaxClonedInstructions << ".\n");
+ return std::nullopt;
+ }
+
if (UnrolledSize < UP.Threshold) {
LLVM_DEBUG(dbgs().indent(2) << "Unrolling: size " << UnrolledSize
<< " < threshold " << UP.Threshold << ".\n");
@@ -1093,7 +1114,8 @@ unsigned llvm::computeUnrollCount(
LLVM_DEBUG(dbgs().indent(1) << "Trying full unroll...\n");
if (TripCount) {
if (auto UnrollFactor =
- shouldFullUnroll(L, TTI, DT, SE, EphValues, TripCount, UCE, UP))
+ shouldFullUnroll(L, TTI, DT, SE, EphValues, TripCount, UCE, UP,
+ PInfo.ExplicitUnroll))
return *UnrollFactor;
}
@@ -1113,7 +1135,8 @@ unsigned llvm::computeUnrollCount(
if (!TripCount && MaxTripCount && (UP.UpperBound || MaxOrZero) &&
MaxTripCount <= UP.MaxUpperBound) {
if (auto UnrollFactor =
- shouldFullUnroll(L, TTI, DT, SE, EphValues, MaxTripCount, UCE, UP))
+ shouldFullUnroll(L, TTI, DT, SE, EphValues, MaxTripCount, UCE, UP,
+ PInfo.ExplicitUnroll))
return *UnrollFactor;
}
diff --git a/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll b/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll
new file mode 100644
index 0000000000000..22dccbd84d9b0
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll
@@ -0,0 +1,149 @@
+; RUN: opt < %s -passes='default<O2>' -disable-output
+; RUN: opt < %s -passes='require<opt-remark-emit>,loop(loop-unroll-full)' \
+; RUN: -unroll-full-max-cloned-instructions=1 -unroll-peel-count=0 -S \
+; RUN: | FileCheck %s
+; RUN: opt < %s -passes=loop-unroll \
+; RUN: -unroll-full-max-cloned-instructions=35 -unroll-peel-count=0 -S \
+; RUN: | FileCheck %s --check-prefix=BELOW
+; RUN: opt < %s -passes=loop-unroll \
+; RUN: -unroll-full-max-cloned-instructions=36 -unroll-peel-count=0 -S \
+; RUN: | FileCheck %s --check-prefix=AT
+; RUN: opt < %s -passes=loop-unroll \
+; RUN: -unroll-full-max-cloned-instructions=1 -unroll-peel-count=0 -S \
+; RUN: | FileCheck %s --check-prefix=EXPLICIT
+; RUN: llvm-extract -func=boundary %s -S \
+; RUN: | opt -passes=loop-unroll -unroll-full-max-cloned-instructions=1 \
+; RUN: -unroll-threshold=4294967295 -unroll-peel-count=0 -S \
+; RUN: | FileCheck %s --check-prefix=NO-THRESHOLD
+;
+; CHECK-LABEL: define void @nested(
+; CHECK: loop.5:
+; CHECK: %iv.5 = phi i64
+;
+; BELOW-LABEL: define i32 @boundary(
+; BELOW: loop:
+; BELOW: %iv = phi i32
+;
+; AT-LABEL: define i32 @boundary(
+; AT-NOT: phi
+; AT: ret i32 10
+;
+; EXPLICIT-LABEL: define i32 @explicit_enable(
+; EXPLICIT-NOT: phi
+; EXPLICIT: ret i32 10
+;
+; NO-THRESHOLD-LABEL: define i32 @boundary(
+; NO-THRESHOLD-NOT: phi
+; NO-THRESHOLD: ret i32 10
+
+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-unknown-linux-gnu"
+
+define i32 @boundary() {
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %next, %loop ]
+ %next = add i32 %iv, 1
+ %continue = icmp ult i32 %next, 10
+ br i1 %continue, label %loop, label %exit
+
+exit:
+ ret i32 %next
+}
+
+define i32 @explicit_enable() {
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %next, %loop ]
+ %next = add i32 %iv, 1
+ %continue = icmp ult i32 %next, 10
+ br i1 %continue, label %loop, label %exit, !llvm.loop !0
+
+exit:
+ ret i32 %next
+}
+
+define void @nested(i32 %arg) {
+entry:
+ br label %loop.1
+
+loop.1:
+ %iv.1 = phi i64 [ %next.1, %loop.1.latch ], [ 0, %entry ]
+ %cmp.1 = icmp slt i64 %iv.1, 10
+ br i1 %cmp.1, label %loop.2, label %exit
+
+loop.2:
+ %iv.2 = phi i64 [ %next.2, %loop.2.latch ], [ 0, %loop.1 ]
+ %value.2 = phi i32 [ %next.value.2, %loop.2.latch ], [ 0, %loop.1 ]
+ %cmp.2 = icmp slt i64 %iv.2, 10
+ br i1 %cmp.2, label %body.2, label %loop.1.latch
+
+body.2:
+ %next.value.2 = add i32 %value.2, 1
+ %enter.3 = icmp slt i32 %value.2, 0
+ br i1 %enter.3, label %loop.3, label %loop.2.latch
+
+loop.3:
+ %iv.3 = phi i64 [ %next.3, %loop.3.latch ], [ 0, %body.2 ]
+ %cmp.3 = icmp slt i64 %iv.3, 10
+ br i1 %cmp.3, label %loop.4, label %loop.2.latch
+
+loop.4:
+ %iv.4 = phi i64 [ %next.4, %loop.4.latch ], [ 0, %loop.3 ]
+ %value.4 = phi i32 [ %next.value.4, %loop.4.latch ], [ 0, %loop.3 ]
+ %cmp.4 = icmp slt i64 %iv.4, 10
+ br i1 %cmp.4, label %body.4, label %loop.3.latch
+
+body.4:
+ %next.value.4 = add i32 %value.4, 1
+ %enter.5 = icmp slt i32 %value.4, 0
+ br i1 %enter.5, label %loop.5, label %loop.4.latch
+
+loop.5:
+ %iv.5 = phi i64 [ %next.5, %body.5 ], [ 0, %body.4 ]
+ %value.5 = phi i32 [ %arg, %body.5 ], [ 0, %body.4 ]
+ %cmp.5 = icmp slt i64 %iv.5, 10
+ br i1 %cmp.5, label %body.5, label %loop.4.latch
+
+body.5:
+ %negative = icmp slt i32 %value.5, 0
+ call void @llvm.assume(i1 %negative)
+ call void @llvm.stackrestore.p0(ptr null)
+ %next.5 = add i64 %iv.5, 1
+ br label %loop.5
+
+loop.4.latch:
+ %next.4 = add i64 %iv.4, 1
+ br label %loop.4
+
+loop.3.latch:
+ %next.3 = add i64 %iv.3, 1
+ br label %loop.3
+
+loop.2.latch:
+ %next.2 = add i64 %iv.2, 1
+ br label %loop.2
+
+loop.1.latch:
+ %next.1 = add i64 %iv.1, 1
+ br label %loop.1
+
+exit:
+ ret void
+}
+
+declare void @llvm.stackrestore.p0(ptr) #0
+declare void @llvm.assume(i1 noundef) #1
+
+attributes #0 = { nocallback nofree nosync nounwind willreturn }
+attributes #1 = {
+ nocallback nofree nosync nounwind willreturn
+ memory(inaccessiblemem: write)
+}
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.unroll.enable"}
>From 91a20a9135d44e6d4bdd05dad1827a02dbd88f95 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Wed, 29 Jul 2026 16:52:37 -0700
Subject: [PATCH 2/2] [LoopUnroll] Keep cloning budget as cl::opt, not in UP
Address review: drop FullUnrollMaxClonedInstructions from
UnrollingPreferences, reject before getUnrolledLoopSize, and tighten the
test comments / remove leftover datalayout and NO-THRESHOLD coverage.
---
.../llvm/Analysis/TargetTransformInfo.h | 3 -
llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 56 ++++++++++---------
.../LoopUnroll/full-unroll-cloning-cost.ll | 22 ++++----
3 files changed, 40 insertions(+), 41 deletions(-)
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 7f4baa6f24676..107ae4dba5075 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -701,9 +701,6 @@ class TargetTransformInfo {
/// applies even if full unrolling is selected. This allows a target to fall
/// back to Partial unrolling if full unrolling is above FullUnrollMaxCount.
unsigned FullUnrollMaxCount;
- /// Set the maximum estimated instructions cloned by automatic full
- /// unrolling. Set to UINT64_MAX to disable.
- uint64_t FullUnrollMaxClonedInstructions;
// Represents number of instructions optimized when "back edge"
// becomes "fall through" in unrolled loop.
// For now we count a conditional branch on a backedge and a comparison
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
index 66970b87fd955..296c77f07c7ba 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -83,11 +83,10 @@ static cl::opt<unsigned>
UnrollThreshold("unroll-threshold", cl::Hidden,
cl::desc("The cost threshold for loop unrolling"));
-static cl::opt<unsigned>
- UnrollOptSizeThreshold(
- "unroll-optsize-threshold", cl::init(0), cl::Hidden,
- cl::desc("The cost threshold for loop unrolling when optimizing for "
- "size"));
+static cl::opt<unsigned> UnrollOptSizeThreshold(
+ "unroll-optsize-threshold", cl::init(0), cl::Hidden,
+ cl::desc("The cost threshold for loop unrolling when optimizing for "
+ "size"));
static cl::opt<unsigned> UnrollPartialThreshold(
"unroll-partial-threshold", cl::Hidden,
@@ -157,9 +156,9 @@ static cl::opt<unsigned> FlatLoopTripCountThreshold(
"threshold, the loop is considered as flat and will be less "
"aggressively unrolled."));
-static cl::opt<bool> UnrollUnrollRemainder(
- "unroll-remainder", cl::Hidden,
- cl::desc("Allow the loop remainder to be unrolled."));
+static cl::opt<bool>
+ UnrollUnrollRemainder("unroll-remainder", cl::Hidden,
+ cl::desc("Allow the loop remainder to be unrolled."));
// This option isn't ever intended to be enabled, it serves to allow
// experiments to check the assumptions about when this kind of revisit is
@@ -211,7 +210,6 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
UP.MaxCount = std::numeric_limits<unsigned>::max();
UP.MaxUpperBound = UnrollMaxUpperBound;
UP.FullUnrollMaxCount = std::numeric_limits<unsigned>::max();
- UP.FullUnrollMaxClonedInstructions = UnrollFullMaxClonedInstructions;
UP.BEInsns = 2;
UP.Partial = false;
UP.Runtime = false;
@@ -255,8 +253,6 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
UP.MaxUpperBound = UnrollMaxUpperBound;
if (UnrollFullMaxCount.getNumOccurrences() > 0)
UP.FullUnrollMaxCount = UnrollFullMaxCount;
- if (UnrollFullMaxClonedInstructions.getNumOccurrences() > 0)
- UP.FullUnrollMaxClonedInstructions = UnrollFullMaxClonedInstructions;
if (UnrollAllowPartial.getNumOccurrences() > 0)
UP.Partial = UnrollAllowPartial;
if (UnrollAllowRemainder.getNumOccurrences() > 0)
@@ -405,9 +401,9 @@ static std::optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
assert(PHIUsedList.empty() && "Must start with an empty phi used list");
CostWorklist.push_back(&RootI);
TargetTransformInfo::TargetCostKind CostKind =
- RootI.getFunction()->hasMinSize() ?
- TargetTransformInfo::TCK_CodeSize :
- TargetTransformInfo::TCK_SizeAndLatency;
+ RootI.getFunction()->hasMinSize()
+ ? TargetTransformInfo::TCK_CodeSize
+ : TargetTransformInfo::TCK_SizeAndLatency;
for (;; --Iteration) {
do {
Instruction *I = CostWorklist.pop_back_val();
@@ -499,8 +495,9 @@ static std::optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
<< "Starting LoopUnroll profitability analysis...\n");
TargetTransformInfo::TargetCostKind CostKind =
- L->getHeader()->getParent()->hasMinSize() ?
- TargetTransformInfo::TCK_CodeSize : TargetTransformInfo::TCK_SizeAndLatency;
+ L->getHeader()->getParent()->hasMinSize()
+ ? TargetTransformInfo::TCK_CodeSize
+ : TargetTransformInfo::TCK_SizeAndLatency;
// Simulate execution of each iteration of the loop counting instructions,
// which would be simplified.
// Since the same load will take different values on different iterations,
@@ -558,9 +555,10 @@ static std::optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
// and if the visitor returns true, mark the instruction as free after
// unrolling and continue.
bool IsFree = Analyzer.visit(I);
- bool Inserted = InstCostMap.insert({&I, (int)Iteration,
- (unsigned)IsFree,
- /*IsCounted*/ false}).second;
+ bool Inserted = InstCostMap
+ .insert({&I, (int)Iteration, (unsigned)IsFree,
+ /*IsCounted*/ false})
+ .second;
(void)Inserted;
assert(Inserted && "Cannot have a state for an unvisited instruction!");
@@ -923,22 +921,27 @@ static std::optional<unsigned> shouldFullUnroll(
return std::nullopt;
}
- // When computing the unrolled size, note that BEInsns are not replicated
- // like the rest of the loop body.
- uint64_t UnrolledSize = UCE.getUnrolledLoopSize(UP, FullUnrollTripCount);
+ // Bound estimated transient cloning work for automatic full unrolling.
+ // Explicit requests (e.g. llvm.loop.unroll.enable with a known trip count)
+ // bypass this compile-time guard; those still reach shouldFullUnroll because
+ // shouldPragmaUnroll only handles the upper-bound enable case.
uint64_t LoopInstructionCount = 0;
for (const BasicBlock *BB : L->blocks())
LoopInstructionCount += BB->size();
uint64_t AdditionalCopies = FullUnrollTripCount - 1;
if (!ExplicitUnroll && UP.Threshold != NoThreshold && AdditionalCopies &&
LoopInstructionCount >
- UP.FullUnrollMaxClonedInstructions / AdditionalCopies) {
+ UnrollFullMaxClonedInstructions / AdditionalCopies) {
LLVM_DEBUG(dbgs().indent(2)
<< "Not unrolling: estimated cloned instructions exceed "
- << UP.FullUnrollMaxClonedInstructions << ".\n");
+ << UnrollFullMaxClonedInstructions << ".\n");
return std::nullopt;
}
+ // When computing the unrolled size, note that BEInsns are not replicated
+ // like the rest of the loop body.
+ uint64_t UnrolledSize = UCE.getUnrolledLoopSize(UP, FullUnrollTripCount);
+
if (UnrolledSize < UP.Threshold) {
LLVM_DEBUG(dbgs().indent(2) << "Unrolling: size " << UnrolledSize
<< " < threshold " << UP.Threshold << ".\n");
@@ -1771,8 +1774,9 @@ PreservedAnalyses LoopUnrollPass::run(Function &F,
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
ProfileSummaryInfo *PSI =
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
- auto *BFI = (PSI && PSI->hasProfileSummary()) ?
- &AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
+ auto *BFI = (PSI && PSI->hasProfileSummary())
+ ? &AM.getResult<BlockFrequencyAnalysis>(F)
+ : nullptr;
bool Changed = false;
diff --git a/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll b/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll
index 22dccbd84d9b0..3fba3f4409fa3 100644
--- a/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll
+++ b/llvm/test/Transforms/LoopUnroll/full-unroll-cloning-cost.ll
@@ -1,20 +1,25 @@
+; Compile-time smoke test for @nested: without the cloning budget,
+; default<O2> can hang or take a very long time. With the budget, this RUN
+; finishes quickly.
; RUN: opt < %s -passes='default<O2>' -disable-output
-; RUN: opt < %s -passes='require<opt-remark-emit>,loop(loop-unroll-full)' \
+;
+; With a tiny budget, @nested is not fully unrolled (residual innermost loop).
+; RUN: opt < %s -passes=loop-unroll \
; RUN: -unroll-full-max-cloned-instructions=1 -unroll-peel-count=0 -S \
; RUN: | FileCheck %s
+;
+; Exact budget boundary on @boundary (body size 4, trip 10 => 4*(10-1)=36).
; RUN: opt < %s -passes=loop-unroll \
; RUN: -unroll-full-max-cloned-instructions=35 -unroll-peel-count=0 -S \
; RUN: | FileCheck %s --check-prefix=BELOW
; RUN: opt < %s -passes=loop-unroll \
; RUN: -unroll-full-max-cloned-instructions=36 -unroll-peel-count=0 -S \
; RUN: | FileCheck %s --check-prefix=AT
+;
+; llvm.loop.unroll.enable bypasses the cloning budget (ExplicitUnroll).
; RUN: opt < %s -passes=loop-unroll \
; RUN: -unroll-full-max-cloned-instructions=1 -unroll-peel-count=0 -S \
; RUN: | FileCheck %s --check-prefix=EXPLICIT
-; RUN: llvm-extract -func=boundary %s -S \
-; RUN: | opt -passes=loop-unroll -unroll-full-max-cloned-instructions=1 \
-; RUN: -unroll-threshold=4294967295 -unroll-peel-count=0 -S \
-; RUN: | FileCheck %s --check-prefix=NO-THRESHOLD
;
; CHECK-LABEL: define void @nested(
; CHECK: loop.5:
@@ -31,13 +36,6 @@
; EXPLICIT-LABEL: define i32 @explicit_enable(
; EXPLICIT-NOT: phi
; EXPLICIT: ret i32 10
-;
-; NO-THRESHOLD-LABEL: define i32 @boundary(
-; NO-THRESHOLD-NOT: phi
-; NO-THRESHOLD: ret i32 10
-
-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-unknown-linux-gnu"
define i32 @boundary() {
entry:
More information about the llvm-commits
mailing list