[llvm] 378941f - [ValueTracking] add scan limit for assumes
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 15 12:24:44 PST 2021
Author: Sanjay Patel
Date: 2021-02-15T15:24:20-05:00
New Revision: 378941f611ab46b985721874081df88bdf3b7cb1
URL: https://github.com/llvm/llvm-project/commit/378941f611ab46b985721874081df88bdf3b7cb1
DIFF: https://github.com/llvm/llvm-project/commit/378941f611ab46b985721874081df88bdf3b7cb1.diff
LOG: [ValueTracking] add scan limit for assumes
In the motivating example from https://llvm.org/PR49171 and
reduced test here, we would unroll and clone assumes so much
that compile-time effectively became infinite while analyzing
all of those assumes.
Added:
llvm/test/Transforms/LoopUnroll/assume-timeout.ll
Modified:
llvm/lib/Analysis/ValueTracking.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 34c4f7106c4b..493eb08bb9b0 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -551,8 +551,12 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
// The context comes first, but they're both in the same block.
// Make sure there is nothing in between that might interrupt
// the control flow, not even CxtI itself.
+ // We limit the scan distance between the assume and its context instruction
+ // to avoid a compile-time explosion. This limit is chosen arbitrarily, so
+ // it can be adjusted if needed (could be turned into a cl::opt).
+ unsigned ScanLimit = 15;
for (BasicBlock::const_iterator I(CxtI), IE(Inv); I != IE; ++I)
- if (!isGuaranteedToTransferExecutionToSuccessor(&*I))
+ if (!isGuaranteedToTransferExecutionToSuccessor(&*I) || --ScanLimit == 0)
return false;
return !isEphemeralValueOf(Inv, CxtI);
diff --git a/llvm/test/Transforms/LoopUnroll/assume-timeout.ll b/llvm/test/Transforms/LoopUnroll/assume-timeout.ll
new file mode 100644
index 000000000000..01aeaa09857a
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/assume-timeout.ll
@@ -0,0 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -loop-unroll -unroll-threshold=300 -S < %s | FileCheck %s
+
+; This test caused a compile-time explosion in ValueTracking
+; because we cloned the assume value and call greatly and
+; then spent far too long analyzing those.
+
+define void @PR49171(i32 %arg) {
+; CHECK-LABEL: @PR49171(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[ASSUME:%.*]] = icmp eq i32 0, [[ARG:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv2 = phi i32 [ 0, %entry ], [ %arg, %loop ]
+ %assume = icmp eq i32 %iv2, %arg
+ call void @llvm.assume(i1 %assume)
+ %iv.inc = add nuw nsw i32 %iv, 1
+ %exitcond = icmp eq i32 %iv.inc, 50 ; Increase me!
+ br i1 %exitcond, label %exit, label %loop
+
+exit:
+ ret void
+}
+
+declare void @llvm.assume(i1)
More information about the llvm-commits
mailing list