Add support for LLVM 20 (modulo dynamic-compile regressions)#4911
Add support for LLVM 20 (modulo dynamic-compile regressions)#4911kinke merged 24 commits intoldc-developers:masterfrom
Conversation
This is now required by LLVM API starting from LLVM 20
Based on checking the `ldc2 -help` output when using LLVM 20 and 19 on Linux x86_64 (with all targets enabled, incl. experimental SPIRV/ Xtensa). And comparing that against official LDC v1.34 with LLVM 16.
|
There's a 32-bit x86 optimizer (?) regression blocking more CI results for the Win32 and Linux multilib CI jobs. This hits an LLVM 20 assertion: Edit: Seems to happen for all 32-bit targets, at least for Android ARMv7-A and riscv32. |
|
I can take a look. |
|
No worries! - Yeah it'd be great if you could look into that problem. |
ef25b12 to
737d77d
Compare
Where the ASan pass now apparently adds a `nosanitize_address` IR module flag, breaking these tests.
|
The same LLVM assertion is also hit for lit-test Looks like the other remaining failures on non-macOS are all dynamic-compile related - 4 hanging lit-tests on Windows x64 (incl. |
…profdata on Ubuntu 25.04
|
I only managed to take a look at the assertion issue this afternoon. The minimal reproducer (in LLVM IR) looks like this: source_filename = "reduced.ll"
target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i686-unknown-linux-gnu"
%"core.internal.container.common.RC!().RC" = type { ptr }
; Function Attrs: nofree norecurse nosync nounwind memory(write, argmem: readwrite, inaccessiblemem: none)
define x86_stdcallcc void @_D4core8internal9container5array__T5ArrayTSQBpQBnQBh6common__T2RCZQeZQBi__T10insertBackZQnMFNbNiQCcZv(ptr nocapture %0) local_unnamed_addr #0 personality ptr null {
if:
br label %forbody.i
forbody.i: ; preds = %forbody.i, %if
%__key37.01.i = phi i32 [ %3, %forbody.i ], [ 0, %if ]
%1 = getelementptr %"core.internal.container.common.RC!().RC", ptr %0, i32 %__key37.01.i
%2 = load ptr, ptr %1, align 4
store i32 0, ptr %2, align 4
store i32 0, ptr %1, align 1
%3 = add i32 %__key37.01.i, 1
%exitcond.not.i = icmp eq i32 %__key37.01.i, -1
br i1 %exitcond.not.i, label %_D4core8internal9container5array__T5ArrayTSQBpQBnQBh6common__T2RCZQeZQBi6lengthMFNbNdNikZv.exit, label %forbody.i
_D4core8internal9container5array__T5ArrayTSQBpQBnQBh6common__T2RCZQeZQBi6lengthMFNbNdNikZv.exit: ; preds = %forbody.i
ret void
}
attributes #0 = { nofree norecurse nosync nounwind memory(write, argmem: readwrite, inaccessiblemem: none) }It seems like LDC will blow up LLVM if the code contains patterns like this (needs struct RC
{
int* ptr;
}
void repro(RC* arg0)
{
for (int i = 0; i != -1; i++)
{
int* ptr = arg0[i].ptr;
*ptr = 0;
arg0[i].ptr = cast(int*)0;
}
}I will investigate further if the issue is with LDC or LLVM. |
|
Thx for digging! - It looks like we don't need a struct for this, nor a signed index/offset. This still hits the assertion with void repro(ubyte** arg0)
{
for (size_t i = 0; i != int.max / 2 + 1; i++)
{
*arg0[i] = 0;
arg0[i] = null;
}
}
Edit: Ah okay, the problematic max index seems to be Do we really have testcases with such a huge static index range? As soon as I add a |
Oh I see: ldc/runtime/druntime/src/core/internal/container/array.d Lines 211 to 232 in 20d22b1 Edit: Nope, commenting that out doesn't suffice. |
I don't think |
|
Ah, it seems like someone else encountered the same issue here: llvm/llvm-project#119365 (comment) |
|
@kinke A fix is being prepared in llvm/llvm-project#138528. You might want to backport this patch to the LDC fork of LLVM. Also, the fix (in From 1dfedc20a40da04a8c1e476871f14d5869ec0e1c Mon Sep 17 00:00:00 2001
From: liushuyu <liushuyu011@gmail.com>
Date: Mon, 5 May 2025 23:46:40 +0800
Subject: [PATCH] jit-rt: avoid double registering EHFrame plugin ...
... when using LLVM JITLink on LLVM 20+
---
runtime/jit-rt/cpp-so/jit_context.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/runtime/jit-rt/cpp-so/jit_context.cpp b/runtime/jit-rt/cpp-so/jit_context.cpp
index 88dcac4d0e..ccbd9011ec 100644
--- a/runtime/jit-rt/cpp-so/jit_context.cpp
+++ b/runtime/jit-rt/cpp-so/jit_context.cpp
@@ -113,7 +113,9 @@ static llvm::orc::LLJITBuilder buildLLJITforLDC() {
// we override the object linking layer if we are using LLVM JITLink.
// For RuntimeDyld, we use LLJIT's default setup process
// (which includes a lot of platform-related workarounds we need)
-#ifdef LDC_JITRT_USE_JITLINK
+ // on LLVM 20+, LLJIT will auto-configure eh-frame plugin and
+ // we avoid configuring the eh-frame plugin ourselves to avoid double registration
+#if defined(LDC_JITRT_USE_JITLINK) && LDC_LLVM_VER < 2000
.setObjectLinkingLayerCreator([&](llvm::orc::ExecutionSession &ES,
const llvm::Triple &TT) {
auto linker = std::make_unique<llvm::orc::ObjectLinkingLayer>(
--
2.49.0
|
|
Awesome, thx a lot mate! |
... when using LLVM JITLink on LLVM 20+
|
Okay, only some dynamic-compile failures remaining - 1 APInt assertion on macOS, 4 hangs on Windows, 10 failures on Linux. |
It seems to me that there might be some other LLVM JIT misuses or LLVM regressions. |
21477c6 to
71fd203
Compare
|
I could switch CI back to LDC-LLVM 19 for now, making this an 'add LLVM 20 support modulo dynamic-compile' PR that we could merge earlier. You could then simply revert that commit in a rebased #4924 to run CI with LLVM 20. |
Sounds good. Let's do it this way then. |
…ssions with LLVM 20
Includes #4843.