Skip to content

Commit e9fb909

Browse files
Merge pull request #39359 from apple/maxd/wasm-swifterror
IRGen: fix `swifterror` attribute mismatch for WebAssembly
2 parents 43ddb88 + 950792a commit e9fb909

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

include/swift/Runtime/RuntimeFnWrappersGen.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ namespace swift {
2525
class AvailabilityContext;
2626
class ASTContext;
2727

28+
namespace irgen {
29+
class IRGenModule;
30+
}
31+
2832
enum class RuntimeAvailability {
2933
AlwaysAvailable,
3034
AvailableByCompatibilityLibrary,
@@ -39,7 +43,8 @@ llvm::Constant *getRuntimeFn(llvm::Module &Module, llvm::Constant *&cache,
3943
RuntimeAvailability availability,
4044
llvm::ArrayRef<llvm::Type *> retTypes,
4145
llvm::ArrayRef<llvm::Type *> argTypes,
42-
llvm::ArrayRef<llvm::Attribute::AttrKind> attrs);
46+
llvm::ArrayRef<llvm::Attribute::AttrKind> attrs,
47+
irgen::IRGenModule *IGM = nullptr);
4348

4449
} // namespace swift
4550
#endif

lib/IRGen/GenCall.cpp

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

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

42514251
// Initialize at the alloca point.

lib/IRGen/IRGenModule.cpp

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

585590
#ifndef NDEBUG
586591
sanityCheckStdlib(*this);
@@ -881,7 +886,8 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
881886
RuntimeAvailability availability,
882887
llvm::ArrayRef<llvm::Type*> retTypes,
883888
llvm::ArrayRef<llvm::Type*> argTypes,
884-
ArrayRef<Attribute::AttrKind> attrs) {
889+
ArrayRef<Attribute::AttrKind> attrs,
890+
IRGenModule *IGM) {
885891

886892
if (cache)
887893
return cache;
@@ -954,6 +960,22 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
954960
fn->addFnAttrs(buildFnAttr);
955961
fn->addRetAttrs(buildRetAttr);
956962
fn->addParamAttrs(0, buildFirstParamAttr);
963+
964+
// Add swiftself and swifterror attributes only when swift_willThrow
965+
// swift_willThrow is defined in RuntimeFunctions.def, but due to the
966+
// DSL limitation, arguments attributes are not set.
967+
// On the other hand, caller of `swift_willThrow` assumes that it's attributed
968+
// with `swiftself` and `swifterror`.
969+
// This mismatch of attributes would be issue when lowering to WebAssembly.
970+
// While lowering, LLVM counts how many dummy params are necessary to match
971+
// callee and caller signature. So we need to add them correctly.
972+
if (functionName == "swift_willThrow") {
973+
assert(IGM && "IGM is required for swift_willThrow.");
974+
fn->addParamAttr(0, Attribute::AttrKind::SwiftSelf);
975+
if (IGM->ShouldUseSwiftError) {
976+
fn->addParamAttr(1, Attribute::AttrKind::SwiftError);
977+
}
978+
}
957979
}
958980

959981
return cache;
@@ -997,7 +1019,7 @@ void IRGenModule::registerRuntimeEffect(ArrayRef<RuntimeEffect> effect,
9971019
registerRuntimeEffect(EFFECT, #NAME); \
9981020
return getRuntimeFn(Module, ID##Fn, #NAME, CC, \
9991021
AVAILABILITY(this->Context), \
1000-
RETURNS, ARGS, ATTRS); \
1022+
RETURNS, ARGS, ATTRS, this); \
10011023
}
10021024

10031025
#include "swift/Runtime/RuntimeFunctions.def"

lib/IRGen/IRGenModule.h

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

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

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

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4812,7 +4812,7 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy,
48124812
DebugValueInst *DbgValue) {
48134813
// We don't need a shadow error variable for debugging on ABI's that return
48144814
// swifterror in a register.
4815-
if (IGM.IsSwiftErrorInRegister)
4815+
if (IGM.ShouldUseSwiftError)
48164816
return;
48174817
auto ErrorResultSlot = getCalleeErrorResultSlot(IGM.silConv.getSILType(
48184818
ErrorInfo, FnTy, IGM.getMaximalTypeExpansionContext()));

0 commit comments

Comments
 (0)