From c3f23ca321796f34a23bb8c74c5457c263947d6f Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Sat, 6 Sep 2025 16:57:46 +0800 Subject: [PATCH 1/2] [LLVM 22] fix calls to `llvm.lifetime.start` --- gen/llvmhelpers.cpp | 21 ++++++--------------- gen/variable_lifetime.cpp | 21 ++++++++++++++++----- gen/variable_lifetime.h | 5 +++-- runtime/druntime/src/ldc/intrinsics.di | 1 + 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 83ed21341ce..8472433603f 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -906,27 +906,18 @@ void DtoVarDeclaration(VarDeclaration *vd) { // We also allocate a variable for zero-sized variables, because they are technically not `null` when loaded. // The x86_64 ABI "loads" zero-sized function arguments, and without an allocation ASan will report an error (Github #4816). - llvm::Value *allocainst; - bool isRealAlloca = false; LLType *lltype = DtoType(type); // void for noreturn if (lltype->isVoidTy()) { - allocainst = getNullPtr(); - } else if (type != vd->type) { - allocainst = DtoAlloca(type, vd->toChars()); - isRealAlloca = true; + irLocal->value = getNullPtr(); } else { - allocainst = DtoAlloca(vd, vd->toChars()); - isRealAlloca = true; - } - - irLocal->value = allocainst; + auto allocainst = type != vd->type ? DtoAlloca(type, vd->toChars()) + : DtoAlloca(vd, vd->toChars()); - if (!lltype->isVoidTy()) + irLocal->value = allocainst; gIR->DBuilder.EmitLocalVariable(allocainst, vd); - // Lifetime annotation is only valid on alloca. - if (isRealAlloca) { - // The lifetime of a stack variable starts from the point it is declared + // The lifetime of a stack variable starts from the + // point it is declared gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable( allocainst, DtoConstUlong(size(type))); } diff --git a/gen/variable_lifetime.cpp b/gen/variable_lifetime.cpp index cf21104de2f..2a460b5626c 100644 --- a/gen/variable_lifetime.cpp +++ b/gen/variable_lifetime.cpp @@ -37,7 +37,7 @@ LocalVariableLifetimeAnnotator::LocalVariableLifetimeAnnotator(IRState &irs) void LocalVariableLifetimeAnnotator::pushScope() { scopes.emplace_back(); } -void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::Value *address, +void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::AllocaInst *address, llvm::Value *size) { assert(address); assert(size); @@ -52,8 +52,13 @@ void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::Value *address, scopes.back().variables.emplace_back(size, address); // Emit lifetime start - irs.CreateCallOrInvoke(getLLVMLifetimeStartFn(), {size, address}, "", - true /*nothrow*/); + irs.CreateCallOrInvoke(getLLVMLifetimeStartFn(), +#if LDC_LLVM_VER >= 2200 + {address}, +#else + {size, address}, +#endif + "", true /*nothrow*/); } // Emits end-of-lifetime annotation for all variables in current scope. @@ -67,8 +72,14 @@ void LocalVariableLifetimeAnnotator::popScope() { assert(address); - irs.CreateCallOrInvoke(getLLVMLifetimeEndFn(), {size, address}, "", - true /*nothrow*/); + irs.CreateCallOrInvoke(getLLVMLifetimeEndFn(), +#if LDC_LLVM_VER >= 2200 + {address}, +#else + {size, address}, +#endif + "", true /*nothrow*/); + } scopes.pop_back(); } diff --git a/gen/variable_lifetime.h b/gen/variable_lifetime.h index f482030c9ad..2dcf02090f2 100644 --- a/gen/variable_lifetime.h +++ b/gen/variable_lifetime.h @@ -21,12 +21,13 @@ namespace llvm { class Function; class Type; class Value; +class AllocaInst; } struct IRState; struct LocalVariableLifetimeAnnotator { struct LocalVariableScope { - std::vector> variables; + std::vector> variables; }; /// Stack of scopes, each scope can have multiple variables. std::vector scopes; @@ -52,5 +53,5 @@ struct LocalVariableLifetimeAnnotator { void popScope(); /// Register a new local variable for lifetime annotation. - void addLocalVariable(llvm::Value *address, llvm::Value *size); + void addLocalVariable(llvm::AllocaInst *address, llvm::Value *size); }; diff --git a/runtime/druntime/src/ldc/intrinsics.di b/runtime/druntime/src/ldc/intrinsics.di index c0d88d8e2d7..e0f17e1488a 100644 --- a/runtime/druntime/src/ldc/intrinsics.di +++ b/runtime/druntime/src/ldc/intrinsics.di @@ -27,6 +27,7 @@ else version (LDC_LLVM_1801) enum LLVM_version = 1801; else version (LDC_LLVM_1901) enum LLVM_version = 1901; else version (LDC_LLVM_2001) enum LLVM_version = 2001; else version (LDC_LLVM_2100) enum LLVM_version = 2100; +else version (LDC_LLVM_2200) enum LLVM_version = 2200; else static assert(false, "LDC LLVM version not supported"); enum LLVM_atleast(int major) = (LLVM_version >= major * 100); From 47c9af5796b228e7b7247420606b771cee7e1e22 Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Mon, 10 Nov 2025 14:29:51 +0800 Subject: [PATCH 2/2] Fix warning for unused variable --- gen/variable_lifetime.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gen/variable_lifetime.cpp b/gen/variable_lifetime.cpp index 2a460b5626c..7bf575ba8ca 100644 --- a/gen/variable_lifetime.cpp +++ b/gen/variable_lifetime.cpp @@ -67,7 +67,9 @@ void LocalVariableLifetimeAnnotator::popScope() { return; for (const auto &var : scopes.back().variables) { +#if LDC_LLVM_VER < 2200 auto size = var.first; +#endif auto address = var.second; assert(address);