Skip to content

Commit c431c40

Browse files
committed
[InstCombine] Improve infinite loop detection
Summary: This patch limits the default number of iterations performed by InstCombine. It also exposes a new option that allows to specify how many iterations is considered getting stuck in an infinite loop. Based on experiments performed on real-world C++ programs, InstCombine seems to perform at most ~8-20 iterations, so treating 1000 iterations as an infinite loop seems like a safe choice. See D71145 for details. The two limits can be specified via command line options. Reviewers: spatel, lebedev.ri, nikic, xbolva00, grosser Reviewed By: spatel Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71673
1 parent 494b131 commit c431c40

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ STATISTIC(NumReassoc , "Number of reassociations");
122122
DEBUG_COUNTER(VisitCounter, "instcombine-visit",
123123
"Controls which instructions are visited");
124124

125-
static constexpr unsigned InstCombineDefaultMaxIterations = UINT_MAX - 1;
125+
static constexpr unsigned InstCombineDefaultMaxIterations = 1000;
126+
static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 1000;
126127

127128
static cl::opt<bool>
128129
EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"),
@@ -137,6 +138,12 @@ static cl::opt<unsigned> LimitMaxIterations(
137138
cl::desc("Limit the maximum number of instruction combining iterations"),
138139
cl::init(InstCombineDefaultMaxIterations));
139140

141+
static cl::opt<unsigned> InfiniteLoopDetectionThreshold(
142+
"instcombine-infinite-loop-threshold",
143+
cl::desc("Number of instruction combining iterations considered an "
144+
"infinite loop"),
145+
cl::init(InstCombineDefaultInfiniteLoopThreshold), cl::Hidden);
146+
140147
static cl::opt<unsigned>
141148
MaxArraySize("instcombine-maxarray-size", cl::init(1024),
142149
cl::desc("Maximum array size considered when doing a combine"));
@@ -3571,13 +3578,17 @@ static bool combineInstructionsOverFunction(
35713578
unsigned Iteration = 0;
35723579
while (true) {
35733580
++Iteration;
3581+
3582+
if (Iteration > InfiniteLoopDetectionThreshold) {
3583+
report_fatal_error(
3584+
"Instruction Combining seems stuck in an infinite loop after " +
3585+
Twine(InfiniteLoopDetectionThreshold) + " iterations.");
3586+
}
3587+
35743588
if (Iteration > MaxIterations) {
35753589
LLVM_DEBUG(dbgs() << "\n\n[IC] Iteration limit #" << MaxIterations
35763590
<< " on " << F.getName()
35773591
<< " reached; stopping before reaching a fixpoint\n");
3578-
LLVM_DEBUG(dbgs().flush());
3579-
assert(Iteration <= InstCombineDefaultMaxIterations &&
3580-
"InstCombine stuck in an infinite loop?");
35813592
break;
35823593
}
35833594

llvm/test/Transforms/InstCombine/limit-max-iterations.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
; RUN: opt < %s -instcombine --instcombine-max-iterations=0 -S | FileCheck %s --check-prefix=ZERO
33
; RUN: opt < %s -instcombine --instcombine-max-iterations=1 -S | FileCheck %s --check-prefix=ONE
44
; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefix=FIXPOINT
5+
; RUN: not opt < %s -instcombine -S --instcombine-infinite-loop-threshold=3 2>&1 | FileCheck %s --check-prefix=LOOP
56

67
; Based on xor-of-icmps-with-extra-uses.ll. This requires multiple iterations of
78
; InstCombine to reach a fixpoint.
@@ -32,6 +33,8 @@ define i1 @v0_select_of_consts(i32 %X, i32* %selected) {
3233
; FIXPOINT-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65535
3334
; FIXPOINT-NEXT: ret i1 [[TMP1]]
3435

36+
; LOOP: LLVM ERROR: Instruction Combining seems stuck in an infinite loop after 3 iterations.
37+
3538
%cond0 = icmp sgt i32 %X, 32767
3639
%cond1 = icmp sgt i32 %X, -32768
3740
%select = select i1 %cond0, i32 32767, i32 -32768

0 commit comments

Comments
 (0)