From 812d365ca558c4d9b87b741f6f2bab569546f232 Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Sat, 6 Sep 2025 16:57:46 +0800 Subject: [PATCH] [LLVM 21] fix calls to `llvm.lifetime.start` --- gen/llvmhelpers.cpp | 25 +++++++++++-------------- gen/variable_lifetime.cpp | 21 ++++++++++++++++----- gen/variable_lifetime.h | 5 +++-- runtime/druntime/src/ldc/intrinsics.di | 1 + 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 7d24c08c339..882a3c953f3 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -897,30 +897,27 @@ 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) { + irLocal->value = getNullPtr(); + return; + } + + llvm::AllocaInst *allocainst; + + if (type != vd->type) { allocainst = DtoAlloca(type, vd->toChars()); - isRealAlloca = true; } else { allocainst = DtoAlloca(vd, vd->toChars()); - isRealAlloca = true; } irLocal->value = allocainst; - if (!lltype->isVoidTy()) - gIR->DBuilder.EmitLocalVariable(allocainst, vd); + 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 - gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable( - allocainst, DtoConstUlong(size(type))); - } + // The lifetime of a stack variable starts from the point it is declared + gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable( + allocainst, DtoConstUlong(size(type))); } IF_LOG Logger::cout() << "llvm value for decl: " << *getIrLocal(vd)->value diff --git a/gen/variable_lifetime.cpp b/gen/variable_lifetime.cpp index cf21104de2f..a6659f6ec34 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 >= 2100 + {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 >= 2100 + {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);