[PATCH] D129745: Fix a stack overflow in ScalarEvolution.
Johannes Reifferscheid via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 14 09:13:04 PDT 2022
jreiffers added a comment.
In D129745#3652264 <https://reviews.llvm.org/D129745#3652264>, @fhahn wrote:
> Would it be possible to share a reproducer? Is this a new stack overflow?
Here's what I've been using:
TEST_F(ScalarEvolutionsTest, StackOverflowForDeepExpression) {
#define MAX 70
#define MAX_STR "70"
std::string kLoopBodyTemplate = R"(
%a${n} = getelementptr inbounds i8, ptr %0, i64 14794768
%b${n} = getelementptr inbounds [1 x [8192 x float]], ptr %a${n}, i64 0, i64 0, i64 %i${n-1}
%c${n} = load float, ptr %b${n}, align 4
%d${n} = getelementptr inbounds [1 x [8192 x [2 x float]]], ptr %1, i64 0, i64 0, i64 %i${n-1}, i64 0
store float %c${n}, ptr %d${n}, align 8
%e${n} = getelementptr inbounds i8, ptr %1, i64 14762000
%f${n} = getelementptr inbounds [1 x [8192 x float]], ptr %e${n}, i64 0, i64 0, i64 %i${n-1}
%g${n} = load float, ptr %f${n}, align 4
%h${n} = getelementptr inbounds [1 x [8192 x [2 x float]]], ptr %1, i64 0, i64 0, i64 %i${n-1}, i64 1
store float %g${n}, ptr %h${n}, align 4
%i${n} = add nuw nsw i64 %i${n-1}, 1
%j${n} = icmp eq i64 %i${n}, 8192
)";
std::string ModuleCode = R"(
define i32 @foo() {
while.171.exit:
br label %fusion.286.loop_header.dim.2.preheader
fusion.286.loop_header.dim.2.preheader: ; preds = %fusion.286.loop_header.dim.2.preheader, %while.171.exit
%i0 = phi i64 [ 0, %while.171.exit ], [ %i)" MAX_STR
R"(, %fusion.286.loop_header.dim.2.preheader ]
%0 = inttoptr i32 0 to ptr
%1 = inttoptr i32 0 to ptr
)";
for (int i = 1; i <= MAX; ++i) {
ModuleCode += replace_all(replace_all(kLoopBodyTemplate, "${n}", itostr(i)),
"${n-1}", itostr(i - 1));
}
ModuleCode +=
"br i1 %j" MAX_STR
R"(, label %fusion.286.loop_exit.dim.0, label %fusion.286.loop_header.dim.2.preheader
fusion.286.loop_exit.dim.0:
ret i32 0
}
)";
LLVMContext C;
SMDiagnostic Err;
std::unique_ptr<Module> M = parseAssemblyString(ModuleCode, Err, C);
ASSERT_EQ(Err.getMessage(), "");
struct rlimit rl;
ASSERT_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
rl.rlim_cur = 1;
ASSERT_EQ(setrlimit(RLIMIT_STACK, &rl), 0);
ASSERT_TRUE(M && "Could not parse module?");
ASSERT_TRUE(!verifyModule(*M, &llvm::errs()) &&
"Must have been well formed!");
runWithSE(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "i63"));
ASSERT_NE(ScevIV, nullptr);
});
}
But it's not very reliable, you may have to run it a few times and/or fiddle with MAX. For me it fails about 30% of the time.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D129745/new/
https://reviews.llvm.org/D129745
More information about the llvm-commits
mailing list