[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