Skip to content

Commit

Permalink
[ARM64EC] Add support for parsing __vectorcall (#87725)
Browse files Browse the repository at this point in the history
MSVC doesn't support generating __vectorcall calls in Arm64EC mode, but
it does treat it as a distinct type. The Microsoft STL depends on this
functionality. (Not sure if this is intentional.) Add support for
parsing the same way as MSVC, and add some checks to ensure we don't try
to actually generate code.

The error handling in CodeGen is ugly, but I can't think of a better way
to do it.
  • Loading branch information
efriedma-quic committed Apr 10, 2024
1 parent 4c6ae8e commit 71097e9
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
5 changes: 4 additions & 1 deletion clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1543,10 +1543,13 @@ WindowsARM64TargetInfo::getBuiltinVaListKind() const {
TargetInfo::CallingConvCheckResult
WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
switch (CC) {
case CC_X86VectorCall:
if (getTriple().isWindowsArm64EC())
return CCCR_OK;
return CCCR_Ignore;
case CC_X86StdCall:
case CC_X86ThisCall:
case CC_X86FastCall:
case CC_X86VectorCall:
return CCCR_Ignore;
case CC_C:
case CC_OpenCLKernel:
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5591,6 +5591,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
/*AttrOnCallSite=*/true,
/*IsThunk=*/false);

if (CallingConv == llvm::CallingConv::X86_VectorCall &&
getTarget().getTriple().isWindowsArm64EC()) {
CGM.Error(Loc, "__vectorcall calling convention is not currently "
"supported");
}

if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
if (FD->hasAttr<StrictFPAttr>())
// All calls within a strictfp function are marked strictfp
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,14 @@ void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD,
llvm::AttributeList PAL;
ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv,
/*AttrOnCallSite=*/false, IsThunk);
if (CallingConv == llvm::CallingConv::X86_VectorCall &&
getTarget().getTriple().isWindowsArm64EC()) {
SourceLocation Loc;
if (const Decl *D = GD.getDecl())
Loc = D->getLocation();

Error(Loc, "__vectorcall calling convention is not currently supported");
}
F->setAttributes(PAL);
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
Expand Down
14 changes: 14 additions & 0 deletions clang/test/CodeGenCXX/arm64ec-vectorcall.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: %clang_cc1 -triple arm64ec-windows-msvc -emit-llvm -o - %s -verify

// ARM64EC doesn't support generating __vectorcall calls... but __vectorcall
// function types need to be distinct from __cdecl function types to support
// compiling the STL. Make sure we only diagnose constructs that actually
// require generating code.
void __vectorcall f1();
void f2(void __vectorcall p()) {}
void f2(void p()) {}
void __vectorcall (*f3)();
void __vectorcall f4(); // expected-error {{__vectorcall}}
void __vectorcall f5() { // expected-error {{__vectorcall}}
f4(); // expected-error{{__vectorcall}}
}

0 comments on commit 71097e9

Please sign in to comment.