-
-
Notifications
You must be signed in to change notification settings - Fork 271
[LLVM 21] fix calls to llvm.lifetime.start
#4979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
aacda96 to
812d365
Compare
|
Did you check whether those lifetime calls are there for LLVM 20? (in the exact same functions?) Would help to get a standalone smaller testcase btw. Something like this: https://d.godbolt.org/z/d6f9763KE |
|
I think I found the extremely weird answer in the clang source (see #4990) - the calls still feature the size argument, although the declaration has a single pointer parameter: https://github.com/llvm/llvm-project/blob/220bac16a417e97bf97fdcb34855e28b2e6dfdf7/clang/lib/CodeGen/CGDecl.cpp#L1363 |
|
that is weird! |
812d365 to
9ebd597
Compare
|
reduced to struct CodepointSet
{
CodepointSet opBinary(string op, U)(U )
{
return this;
}
this(this) { }
}
CodepointSet memoizeExpr(string expr)()
{
if (__ctfe)
return mixin(expr);
CodepointSet slot;
return slot;
}
void wordCharacter() {
memoizeExpr!"unicode.A | unicode.M";
}
struct unicode
{
static CodepointSet opDispatch(string name)()
{
CodepointSet set;
return set;
}
}it generates a broken call ; Function Attrs: uwtable(sync)
define weak_odr void @_D7package__T11memoizeExprVAyaa21_756e69636f64652e41207c20756e69636f64652e4dZQCmFNaNbNiNfZSQDl__T13InversionListTSQEi8GcPolicyZQBe(ptr noalias sret(%"package.InversionList!(GcPolicy).InversionList") align 1 %.sret_arg) #0 {
%slot = alloca %"package.InversionList!(GcPolicy).InversionList", align 1
%__copytmp3 = alloca %"package.InversionList!(GcPolicy).InversionList", align 1
call void @llvm.lifetime.start.p0(ptr captures(none) %slot) #2
call void @llvm.memset.p0.i64(ptr align 1 %slot, i8 0, i64 1, i1 false)
call void @llvm.lifetime.start.p0(ptr captures(none) %.sret_arg) #2 ; <<<<<< HERE
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.sret_arg, ptr align 1 %slot, i64 1, i1 false)
call void @_D7package__T13InversionListTSQBc8GcPolicyZQBe15__fieldPostblitMFNaNbNiNeZv(ptr nonnull %.sret_arg) #0
ret void
} |
|
53d7c1d is not the correct fix, and fails when built with recent LLVM. and removing the early return from if (lltype->isVoidTy()) {
irLocal->value = getNullPtr();
return;
}does not fix it either. I think this is a DMD bug where if (__ctfe)
return mixin(expr);
alias T = typeof(mixin(expr));
T slot;
return slot; // This NRVO is broken
}the |
9ebd597 to
69b3f0e
Compare
|
Hopefully this is now fixed. |
69b3f0e to
5424e87
Compare
5424e87 to
0e742c1
Compare
This mostly fixes compilation for LLVM21, except for some breakage with regards to moving
llvm.lifetime.startto taking only andAllocaInst(or aPoison).and
(the above ` | grep "%0")
which both produce a call to
@llvm.lifetime.start.p0(ptr captures(none) %0)and%0in this case is anArgumentnot anAllocaInst.I'm trying to figure out where those calls are coming from. Is it the ABI messing things up somehow? I don't know what is special about those functions.
there is only the one use of it and