From 1aee99e8caed26646fab6f78401b5e8f97c8212c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 30 Apr 2021 22:38:40 +0200 Subject: [PATCH] [ValueTracking] Limit scan when checking poison UB (PR50155) The current code can scan an unlimited number of instructions, if the containing basic block is very large. The test case from PR50155 contains a basic block with approximately 100k instructions. To avoid this, limit the number of instructions we inspect. At the same time, drop the limit on the number of basic blocks, as this will be implicitly limited by the number of instructions as well. --- lib/Analysis/ValueTracking.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 3e46e11a652..e2c7253b4ff 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -5382,6 +5382,9 @@ static bool programUndefinedIfUndefOrPoison(const Value *V, return false; } + // Limit number of instructions we look at, to avoid scanning through large + // blocks. The current limit is chosen arbitrarily. + unsigned ScanLimit = 32; BasicBlock::const_iterator End = BB->end(); if (!PoisonOnly) { @@ -5390,6 +5393,11 @@ static bool programUndefinedIfUndefOrPoison(const Value *V, // well-defined operands. for (auto &I : make_range(Begin, End)) { + if (isa(I)) + continue; + if (--ScanLimit == 0) + break; + SmallPtrSet WellDefinedOps; getGuaranteedWellDefinedOps(&I, WellDefinedOps); for (auto *Op : WellDefinedOps) { @@ -5415,9 +5423,12 @@ static bool programUndefinedIfUndefOrPoison(const Value *V, for_each(V->users(), Propagate); Visited.insert(BB); - unsigned Iter = 0; - while (Iter++ < MaxAnalysisRecursionDepth) { + while (true) { for (auto &I : make_range(Begin, End)) { + if (isa(I)) + continue; + if (--ScanLimit == 0) + return false; if (mustTriggerUB(&I, YieldsPoison)) return true; if (!isGuaranteedToTransferExecutionToSuccessor(&I))