Skip to content

Commit 5424e87

Browse files
committed
[LLVM 21] fix calls to llvm.lifetime.start
1 parent 897b155 commit 5424e87

File tree

3 files changed

+87
-18
lines changed

3 files changed

+87
-18
lines changed

gen/llvmhelpers.cpp

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,64 @@ void DtoResolveVariable(VarDeclaration *vd) {
858858
}
859859
}
860860

861+
namespace {
862+
bool eval(VarDeclaration *vd, Expression *e) {
863+
864+
auto ve = e->isVarExp();
865+
if (!ve) {
866+
return false;
867+
}
868+
VarDeclaration *v = nullptr;
869+
if (ve)
870+
v = ve->var->isVarDeclaration();
871+
return vd == v;
872+
}
873+
bool walk(VarDeclaration *vd, CommaExp *ce) {
874+
IF_LOG Logger::println("ce = %s", ce->toChars());
875+
if (auto ce2 = ce->e2->isCommaExp()) {
876+
if (walk(vd, ce2))
877+
return true;
878+
}
879+
if (auto ce1 = ce->e1->isCommaExp()) {
880+
if (walk(vd, ce1))
881+
return true;
882+
}
883+
if (eval(vd, ce->e2))
884+
return true;
885+
if (eval(vd, ce->e1))
886+
return true;
887+
return false;
888+
}
889+
bool varIsSret(VarDeclaration *vd, IrFunction *f) {
890+
if (!f->sretArg)
891+
return false;
892+
auto fd = f->decl;
893+
auto rets = fd->returns;
894+
if (!rets)
895+
return false;
896+
#if LDC_LLVM_VER >= 1800
897+
#define startswith starts_with
898+
#endif
899+
llvm::StringRef name = vd->ident->toChars();
900+
if (name.startswith("__tmpfordtor") ||name.startswith("__sl")) {
901+
return true;
902+
}
903+
#if LDC_LLVM_VER >= 1800
904+
#undef startswith
905+
#endif
906+
for (d_size_t i = 0; i < rets->length; i++) {
907+
auto rs = (*rets)[i];
908+
Expression *e = rs->exp;
909+
CommaExp *ce = e->isCommaExp();
910+
if (ce) {
911+
if (walk(vd, ce)) return true;
912+
}
913+
if (eval(vd, e))
914+
return true;
915+
}
916+
return false;
917+
}
918+
}
861919
/******************************************************************************
862920
* DECLARATION EXP HELPER
863921
******************************************************************************/
@@ -906,27 +964,26 @@ void DtoVarDeclaration(VarDeclaration *vd) {
906964

907965
// We also allocate a variable for zero-sized variables, because they are technically not `null` when loaded.
908966
// The x86_64 ABI "loads" zero-sized function arguments, and without an allocation ASan will report an error (Github #4816).
909-
llvm::Value *allocainst;
910-
bool isRealAlloca = false;
911967
LLType *lltype = DtoType(type); // void for noreturn
912968
if (lltype->isVoidTy()) {
913-
allocainst = getNullPtr();
914-
} else if (type != vd->type) {
969+
irLocal->value = getNullPtr();
970+
return;
971+
}
972+
973+
llvm::AllocaInst *allocainst;
974+
975+
if (type != vd->type) {
915976
allocainst = DtoAlloca(type, vd->toChars());
916-
isRealAlloca = true;
917977
} else {
918978
allocainst = DtoAlloca(vd, vd->toChars());
919-
isRealAlloca = true;
920979
}
921980

922981
irLocal->value = allocainst;
923982

924-
if (!lltype->isVoidTy())
925-
gIR->DBuilder.EmitLocalVariable(allocainst, vd);
983+
gIR->DBuilder.EmitLocalVariable(allocainst, vd);
926984

927-
// Lifetime annotation is only valid on alloca.
928-
if (isRealAlloca) {
929-
// The lifetime of a stack variable starts from the point it is declared
985+
// The lifetime of a stack variable starts from the point it is declared
986+
if (!vd->isParameter() && !varIsSret(vd, gIR->func())) {
930987
gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable(
931988
allocainst, DtoConstUlong(size(type)));
932989
}

gen/variable_lifetime.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ LocalVariableLifetimeAnnotator::LocalVariableLifetimeAnnotator(IRState &irs)
3737

3838
void LocalVariableLifetimeAnnotator::pushScope() { scopes.emplace_back(); }
3939

40-
void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::Value *address,
40+
void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::AllocaInst *address,
4141
llvm::Value *size) {
4242
assert(address);
4343
assert(size);
@@ -52,8 +52,13 @@ void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::Value *address,
5252
scopes.back().variables.emplace_back(size, address);
5353

5454
// Emit lifetime start
55-
irs.CreateCallOrInvoke(getLLVMLifetimeStartFn(), {size, address}, "",
56-
true /*nothrow*/);
55+
irs.CreateCallOrInvoke(getLLVMLifetimeStartFn(),
56+
#if LDC_LLVM_VER >= 2100
57+
{address},
58+
#else
59+
{size, address},
60+
#endif
61+
"", true /*nothrow*/);
5762
}
5863

5964
// Emits end-of-lifetime annotation for all variables in current scope.
@@ -67,8 +72,14 @@ void LocalVariableLifetimeAnnotator::popScope() {
6772

6873
assert(address);
6974

70-
irs.CreateCallOrInvoke(getLLVMLifetimeEndFn(), {size, address}, "",
71-
true /*nothrow*/);
75+
irs.CreateCallOrInvoke(getLLVMLifetimeEndFn(),
76+
#if LDC_LLVM_VER >= 2100
77+
{address},
78+
#else
79+
{size, address},
80+
#endif
81+
"", true /*nothrow*/);
82+
7283
}
7384
scopes.pop_back();
7485
}

gen/variable_lifetime.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ namespace llvm {
2121
class Function;
2222
class Type;
2323
class Value;
24+
class AllocaInst;
2425
}
2526
struct IRState;
2627

2728
struct LocalVariableLifetimeAnnotator {
2829
struct LocalVariableScope {
29-
std::vector<std::pair<llvm::Value *, llvm::Value *>> variables;
30+
std::vector<std::pair<llvm::Value *, llvm::AllocaInst *>> variables;
3031
};
3132
/// Stack of scopes, each scope can have multiple variables.
3233
std::vector<LocalVariableScope> scopes;
@@ -52,5 +53,5 @@ struct LocalVariableLifetimeAnnotator {
5253
void popScope();
5354

5455
/// Register a new local variable for lifetime annotation.
55-
void addLocalVariable(llvm::Value *address, llvm::Value *size);
56+
void addLocalVariable(llvm::AllocaInst *address, llvm::Value *size);
5657
};

0 commit comments

Comments
 (0)