[llvm] [MCJIT] Fix frem.ll test failure with LLVM_ENABLE_RPMALLOC on Windows (PR #200319)
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 22:23:49 PDT 2026
https://github.com/igorkudrin updated https://github.com/llvm/llvm-project/pull/200319
>From a19ba5933d676a7a9ff29cc18a3ae56cfd5aec7b Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Thu, 28 May 2026 19:23:51 -0700
Subject: [PATCH 1/2] [MCJIT] Fix frem.ll test failure with
LLVM_ENABLE_RPMALLOC on Windows
When compiled with `LLVM_ENABLE_RPMALLOC`, `lli.exe` links statically to
the runtime. With `LLVM_EXPORT_SYMBOLS_FOR_PLUGINS` enabled, `lli.exe`
exports a subset of symbols from the runtime library, but not all. In
particular, `printf()` is exported from the application binary, but
`fflush()` and `exit()` are not. For a JITted module, unresolved
external symbols are loaded either from the application or dynamic
libraries, in this case, from `msvcrt.dll`. The `MCJIT/frem.ll` test
attempts to flush the output, but because the functions resolve to
different CRT instances, the output data is lost.
The patch avoids the test failure by flushing the streams in `lli.cpp`
before calling `exit()`.
---
llvm/test/ExecutionEngine/MCJIT/frem.ll | 2 --
llvm/tools/lli/lli.cpp | 5 +++++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/test/ExecutionEngine/MCJIT/frem.ll b/llvm/test/ExecutionEngine/MCJIT/frem.ll
index b8739c249cf58..de7cb081779d6 100644
--- a/llvm/test/ExecutionEngine/MCJIT/frem.ll
+++ b/llvm/test/ExecutionEngine/MCJIT/frem.ll
@@ -9,14 +9,12 @@
@str = internal constant [18 x i8] c"Double value: %f\0A\00"
declare i32 @printf(ptr nocapture, ...) nounwind
-declare i32 @fflush(ptr) nounwind
define i32 @main() {
%flt = load float, ptr @flt
%float2 = frem float %flt, 5.0
%double1 = fpext float %float2 to double
call i32 (ptr, ...) @printf(ptr @str, double %double1)
- call i32 @fflush(ptr null)
ret i32 0
}
diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index 38496cbd5ff77..f6f29ad0048ff 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -682,6 +682,11 @@ int main(int argc, char **argv, char * const *envp) {
// Run static destructors.
EE->runStaticConstructorsDestructors(true);
+ // Normally, the streams are flushed by `exti()`. In rare cases, we fail to
+ // find the correct instance of it, and the printed but not yet flushed
+ // content is lost. Flush the streams in advance, just in case.
+ fflush(nullptr);
+
// If the program didn't call exit explicitly, we should call it now.
// This ensures that any atexit handlers get called correctly.
if (Function *ExitF =
>From 5f5474c5908dc9f4c00105d09d1fa3870be5a1c4 Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Fri, 12 Jun 2026 19:20:48 -0700
Subject: [PATCH 2/2] fixup! Do not export symbols when linking with the static
CRT
---
llvm/tools/lli/CMakeLists.txt | 16 +++++++++++++++-
llvm/tools/lli/lli.cpp | 5 -----
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/llvm/tools/lli/CMakeLists.txt b/llvm/tools/lli/CMakeLists.txt
index 3106f25ad79f8..fbea0132c170b 100644
--- a/llvm/tools/lli/CMakeLists.txt
+++ b/llvm/tools/lli/CMakeLists.txt
@@ -51,11 +51,25 @@ if( LLVM_USE_PERF )
)
endif( LLVM_USE_PERF )
+if (MSVC AND CMAKE_MSVC_RUNTIME_LIBRARY AND
+ (NOT CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "DLL$"))
+ # Do not export symbols when linking with the static CRT because in this case,
+ # only a subset of CRT symbols is exported. When executing a module, this can
+ # cause imported CRT symbols to resolve to different CRT instances. For
+ # example, 'lli.exe' may export 'printf' but not 'fflush' or 'exit', causing
+ # 'printf' to bind to the static CRT while the latter resolve to the dynamic
+ # CRT. Disabling symbol export forces all imports to bind to the dynamic CRT
+ # instance.
+ set(MAYBE_EXPORT_SYMBOLS "")
+else()
+ set(MAYBE_EXPORT_SYMBOLS EXPORT_SYMBOLS)
+endif()
+
add_llvm_tool(lli
lli.cpp
DEPENDS
intrinsics_gen
- EXPORT_SYMBOLS
+ ${MAYBE_EXPORT_SYMBOLS}
)
diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index f6f29ad0048ff..38496cbd5ff77 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -682,11 +682,6 @@ int main(int argc, char **argv, char * const *envp) {
// Run static destructors.
EE->runStaticConstructorsDestructors(true);
- // Normally, the streams are flushed by `exti()`. In rare cases, we fail to
- // find the correct instance of it, and the printed but not yet flushed
- // content is lost. Flush the streams in advance, just in case.
- fflush(nullptr);
-
// If the program didn't call exit explicitly, we should call it now.
// This ensures that any atexit handlers get called correctly.
if (Function *ExitF =
More information about the llvm-commits
mailing list