Skip to content

Commit 780b4dc

Browse files
bylawsdpaoliello
authored andcommitted
[AArch64] Fix generated types for ARM64EC variadic entry thunk targets (#80595)
ISel handles filling in x4/x5 when calling variadic functions as they don't correspond to the 5th/6th X64 arguments but rather to the end of the shadow space on the stack and the size in bytes of all stack parameters (ignored and written as 0 for calls from entry thunks). Will PR a follow up with ISel handling after this is merged.
1 parent 064dd62 commit 780b4dc

File tree

2 files changed

+29
-23
lines changed

2 files changed

+29
-23
lines changed

llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp

+27-21
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ static cl::opt<bool> GenerateThunks("arm64ec-generate-thunks", cl::Hidden,
4343

4444
namespace {
4545

46+
enum class ThunkType { GuestExit, Entry, Exit };
47+
4648
class AArch64Arm64ECCallLowering : public ModulePass {
4749
public:
4850
static char ID;
@@ -69,14 +71,14 @@ class AArch64Arm64ECCallLowering : public ModulePass {
6971
Type *I64Ty;
7072
Type *VoidTy;
7173

72-
void getThunkType(FunctionType *FT, AttributeList AttrList, bool EntryThunk,
74+
void getThunkType(FunctionType *FT, AttributeList AttrList, ThunkType TT,
7375
raw_ostream &Out, FunctionType *&Arm64Ty,
7476
FunctionType *&X64Ty);
7577
void getThunkRetType(FunctionType *FT, AttributeList AttrList,
7678
raw_ostream &Out, Type *&Arm64RetTy, Type *&X64RetTy,
7779
SmallVectorImpl<Type *> &Arm64ArgTypes,
7880
SmallVectorImpl<Type *> &X64ArgTypes, bool &HasSretPtr);
79-
void getThunkArgTypes(FunctionType *FT, AttributeList AttrList,
81+
void getThunkArgTypes(FunctionType *FT, AttributeList AttrList, ThunkType TT,
8082
raw_ostream &Out,
8183
SmallVectorImpl<Type *> &Arm64ArgTypes,
8284
SmallVectorImpl<Type *> &X64ArgTypes, bool HasSretPtr);
@@ -89,10 +91,11 @@ class AArch64Arm64ECCallLowering : public ModulePass {
8991

9092
void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
9193
AttributeList AttrList,
92-
bool EntryThunk, raw_ostream &Out,
94+
ThunkType TT, raw_ostream &Out,
9395
FunctionType *&Arm64Ty,
9496
FunctionType *&X64Ty) {
95-
Out << (EntryThunk ? "$ientry_thunk$cdecl$" : "$iexit_thunk$cdecl$");
97+
Out << (TT == ThunkType::Entry ? "$ientry_thunk$cdecl$"
98+
: "$iexit_thunk$cdecl$");
9699

97100
Type *Arm64RetTy;
98101
Type *X64RetTy;
@@ -102,23 +105,25 @@ void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
102105

103106
// The first argument to a thunk is the called function, stored in x9.
104107
// For exit thunks, we pass the called function down to the emulator;
105-
// for entry thunks, we just call the Arm64 function directly.
106-
if (!EntryThunk)
108+
// for entry/guest exit thunks, we just call the Arm64 function directly.
109+
if (TT == ThunkType::Exit)
107110
Arm64ArgTypes.push_back(PtrTy);
108111
X64ArgTypes.push_back(PtrTy);
109112

110113
bool HasSretPtr = false;
111114
getThunkRetType(FT, AttrList, Out, Arm64RetTy, X64RetTy, Arm64ArgTypes,
112115
X64ArgTypes, HasSretPtr);
113116

114-
getThunkArgTypes(FT, AttrList, Out, Arm64ArgTypes, X64ArgTypes, HasSretPtr);
117+
getThunkArgTypes(FT, AttrList, TT, Out, Arm64ArgTypes, X64ArgTypes,
118+
HasSretPtr);
115119

116-
Arm64Ty = FunctionType::get(Arm64RetTy, Arm64ArgTypes, false);
120+
Arm64Ty = FunctionType::get(Arm64RetTy, Arm64ArgTypes,
121+
TT == ThunkType::Entry && FT->isVarArg());
117122
X64Ty = FunctionType::get(X64RetTy, X64ArgTypes, false);
118123
}
119124

120125
void AArch64Arm64ECCallLowering::getThunkArgTypes(
121-
FunctionType *FT, AttributeList AttrList, raw_ostream &Out,
126+
FunctionType *FT, AttributeList AttrList, ThunkType TT, raw_ostream &Out,
122127
SmallVectorImpl<Type *> &Arm64ArgTypes,
123128
SmallVectorImpl<Type *> &X64ArgTypes, bool HasSretPtr) {
124129

@@ -151,14 +156,16 @@ void AArch64Arm64ECCallLowering::getThunkArgTypes(
151156
X64ArgTypes.push_back(I64Ty);
152157
}
153158

154-
// x4
155-
Arm64ArgTypes.push_back(PtrTy);
156-
X64ArgTypes.push_back(PtrTy);
157-
// x5
158-
Arm64ArgTypes.push_back(I64Ty);
159-
// FIXME: x5 isn't actually passed/used by the x64 side; revisit once we
160-
// have proper isel for varargs
161-
X64ArgTypes.push_back(I64Ty);
159+
if (TT != ThunkType::Entry) {
160+
// x4
161+
Arm64ArgTypes.push_back(PtrTy);
162+
X64ArgTypes.push_back(PtrTy);
163+
// x5
164+
Arm64ArgTypes.push_back(I64Ty);
165+
// FIXME: x5 isn't actually passed/used by the x64 side; revisit once we
166+
// have proper isel for varargs
167+
X64ArgTypes.push_back(I64Ty);
168+
}
162169
return;
163170
}
164171

@@ -339,8 +346,7 @@ Function *AArch64Arm64ECCallLowering::buildExitThunk(FunctionType *FT,
339346
SmallString<256> ExitThunkName;
340347
llvm::raw_svector_ostream ExitThunkStream(ExitThunkName);
341348
FunctionType *Arm64Ty, *X64Ty;
342-
getThunkType(FT, Attrs, /*EntryThunk*/ false, ExitThunkStream, Arm64Ty,
343-
X64Ty);
349+
getThunkType(FT, Attrs, ThunkType::Exit, ExitThunkStream, Arm64Ty, X64Ty);
344350
if (Function *F = M->getFunction(ExitThunkName))
345351
return F;
346352

@@ -443,7 +449,7 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
443449
SmallString<256> EntryThunkName;
444450
llvm::raw_svector_ostream EntryThunkStream(EntryThunkName);
445451
FunctionType *Arm64Ty, *X64Ty;
446-
getThunkType(F->getFunctionType(), F->getAttributes(), /*EntryThunk*/ true,
452+
getThunkType(F->getFunctionType(), F->getAttributes(), ThunkType::Entry,
447453
EntryThunkStream, Arm64Ty, X64Ty);
448454
if (Function *F = M->getFunction(EntryThunkName))
449455
return F;
@@ -518,7 +524,7 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
518524
Function *AArch64Arm64ECCallLowering::buildGuestExitThunk(Function *F) {
519525
llvm::raw_null_ostream NullThunkName;
520526
FunctionType *Arm64Ty, *X64Ty;
521-
getThunkType(F->getFunctionType(), F->getAttributes(), /*EntryThunk*/ true,
527+
getThunkType(F->getFunctionType(), F->getAttributes(), ThunkType::GuestExit,
522528
NullThunkName, Arm64Ty, X64Ty);
523529
auto MangledName = getArm64ECMangledFunctionName(F->getName().str());
524530
assert(MangledName && "Can't guest exit to function that's already native");

llvm/test/CodeGen/AArch64/arm64ec-entry-thunks.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ define void @has_varargs(...) nounwind {
147147
; CHECK-NEXT: add x29, sp, #160
148148
; CHECK-NEXT: .seh_add_fp 160
149149
; CHECK-NEXT: .seh_endprologue
150-
; CHECK-NEXT: ldp x8, x5, [x4, #32]
151-
; CHECK-NEXT: mov x4, x8
150+
; CHECK-NEXT: mov x4, sp
151+
; CHECK-NEXT: mov x5, xzr
152152
; CHECK-NEXT: blr x9
153153
; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret
154154
; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret]

0 commit comments

Comments
 (0)