Skip to content

Commit 6733a8c

Browse files
committed
IRGen: fix swifterror attribute mismatch for WebAssembly
1 parent 2ae2fee commit 6733a8c

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ void IRGenModule::addSwiftErrorAttributes(llvm::AttributeList &attrs,
347347
// We create a shadow stack location of the swifterror parameter for the
348348
// debugger on such platforms and so we can't mark the parameter with a
349349
// swifterror attribute.
350-
if (IsSwiftErrorInRegister)
350+
if (ShouldUseSwiftError)
351351
b.addAttribute(llvm::Attribute::SwiftError);
352352

353353
// The error result should not be aliased, captured, or pointed at invalid
@@ -4081,7 +4081,7 @@ Address IRGenFunction::createErrorResultSlot(SILType errorType, bool isAsync) {
40814081
// The slot for async callees cannot be annotated swifterror because those
40824082
// errors are never passed in registers but rather are always passed
40834083
// indirectly in the async context.
4084-
if (IGM.IsSwiftErrorInRegister && !isAsync)
4084+
if (IGM.ShouldUseSwiftError && !isAsync)
40854085
cast<llvm::AllocaInst>(addr.getAddress())->setSwiftError(true);
40864086

40874087
// Initialize at the alloca point.

lib/IRGen/IRGenModule.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,10 +575,15 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
575575
AtomicBoolSize = Size(ClangASTContext->getTypeSize(atomicBoolTy));
576576
AtomicBoolAlign = Alignment(ClangASTContext->getTypeSize(atomicBoolTy));
577577
}
578-
579-
IsSwiftErrorInRegister =
578+
// On WebAssembly, tail optional arguments are not allowed because Wasm requires
579+
// callee and caller signature to be the same. So LLVM adds dummy arguments for
580+
// `swiftself` and `swifterror`. If there is `swiftself` but is no `swifterror` in
581+
// a swiftcc function or invocation, then LLVM adds dummy `swifterror` parameter or
582+
// argument. To count up how many dummy arguments should be added, we need to mark
583+
// it as `swifterror` even though it's not in register.
584+
ShouldUseSwiftError =
580585
clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister(
581-
ClangCodeGen->CGM());
586+
ClangCodeGen->CGM()) || TargetInfo.OutputObjectFormat == llvm::Triple::Wasm;
582587

583588
#ifndef NDEBUG
584589
sanityCheckStdlib(*this);
@@ -932,6 +937,19 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
932937
fn->addAttributes(llvm::AttributeList::FunctionIndex, buildFnAttr);
933938
fn->addAttributes(llvm::AttributeList::ReturnIndex, buildRetAttr);
934939
fn->addParamAttrs(0, buildFirstParamAttr);
940+
941+
// Add swiftself and swifterror attributes only when swift_willThrow
942+
// swift_willThrow is defined in RuntimeFunctions.def, but due to the
943+
// DSL limitation, arguments attributes are not set.
944+
// On the other hand, caller of `swift_willThrow` assumes that it's attributed
945+
// with `swiftself` and `swifterror`.
946+
// This mismatch of attributes would be issue when lowering to WebAssembly.
947+
// While lowering, LLVM counts how many dummy params are necessary to match
948+
// callee and caller signature. So we need to add them correctly.
949+
if (functionName == "swift_willThrow") {
950+
fn->addParamAttr(0, Attribute::AttrKind::SwiftSelf);
951+
fn->addParamAttr(1, Attribute::AttrKind::SwiftError);
952+
}
935953
}
936954

937955
return cache;

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,8 @@ class IRGenModule {
616616
/// Should we add value names to local IR values?
617617
bool EnableValueNames = false;
618618

619-
// Is swifterror returned in a register by the target ABI.
620-
bool IsSwiftErrorInRegister;
619+
// Should `swifterror` attribute be explicitly added for the target ABI.
620+
bool ShouldUseSwiftError;
621621

622622
llvm::Type *VoidTy; /// void (usually {})
623623
llvm::IntegerType *Int1Ty; /// i1

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4586,7 +4586,7 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy,
45864586
DebugValueInst *DbgValue) {
45874587
// We don't need a shadow error variable for debugging on ABI's that return
45884588
// swifterror in a register.
4589-
if (IGM.IsSwiftErrorInRegister)
4589+
if (IGM.ShouldUseSwiftError)
45904590
return;
45914591
auto ErrorResultSlot = getCalleeErrorResultSlot(IGM.silConv.getSILType(
45924592
ErrorInfo, FnTy, IGM.getMaximalTypeExpansionContext()));

0 commit comments

Comments
 (0)