summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-02-12 12:27:08 +0000
committerHans Wennborg <hans@hanshq.net>2019-02-12 12:27:08 +0000
commit831b2047290f564ff3f07acb77e9ea72910e70ed (patch)
tree6ae44f0d1b7eb5932f6744025e2d6bc834542867
parentd1ca490a0d7ca03a6e2e0f3aa5aae6701d887a90 (diff)
[WebAssembly] Backport custom import name changes for LLVM to 8.0.
Specifically, this backports r352479, r352931, r353474, and r353476 to the 8.0 branch. The trunk patches don't apply cleanly to 8.0 due to some contemporaneous mass-rename and mass-clang-tidy patches, so this merges them to simplify rebasing. r352479 [WebAssembly] Re-enable main-function signature rewriting r352931 [WebAssembly] Add codegen support for the import_field attribute r353474 [WebAssembly] Fix imported function symbol names that differ from their import names in the .o format r353476 [WebAssembly] Update test output after rL353474. NFC. By Dan Gohman! git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@353835 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/BinaryFormat/Wasm.h4
-rw-r--r--include/llvm/MC/MCSymbolWasm.h22
-rw-r--r--lib/MC/WasmObjectWriter.cpp25
-rw-r--r--lib/Object/WasmObjectFile.cpp22
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp11
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h13
-rw-r--r--lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp9
-rw-r--r--lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp36
-rw-r--r--test/CodeGen/WebAssembly/call.ll4
-rw-r--r--test/CodeGen/WebAssembly/function-bitcasts-varargs.ll2
-rw-r--r--test/CodeGen/WebAssembly/function-bitcasts.ll2
-rw-r--r--test/CodeGen/WebAssembly/import-module.ll3
-rw-r--r--test/CodeGen/WebAssembly/main-declaration.ll16
-rw-r--r--test/CodeGen/WebAssembly/main-no-args.ll13
-rw-r--r--test/CodeGen/WebAssembly/main-three-args.ll16
-rw-r--r--test/CodeGen/WebAssembly/main-with-args.ll2
-rw-r--r--test/MC/WebAssembly/external-func-address.ll4
-rw-r--r--test/MC/WebAssembly/import-module.ll31
-rw-r--r--tools/yaml2obj/yaml2wasm.cpp3
19 files changed, 176 insertions, 62 deletions
diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h
index d9f0f94b298d..b02ddb6b7e29 100644
--- a/include/llvm/BinaryFormat/Wasm.h
+++ b/include/llvm/BinaryFormat/Wasm.h
@@ -165,7 +165,8 @@ struct WasmSymbolInfo {
StringRef Name;
uint8_t Kind;
uint32_t Flags;
- StringRef Module; // For undefined symbols the module name of the import
+ StringRef ImportModule; // For undefined symbols the module of the import
+ StringRef ImportName; // For undefined symbols the name of the import
union {
// For function or global symbols, the index in function or global index
// space.
@@ -284,6 +285,7 @@ const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
+const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40;
#define WASM_RELOC(name, value) name = value,
diff --git a/include/llvm/MC/MCSymbolWasm.h b/include/llvm/MC/MCSymbolWasm.h
index 8e66dc881d0f..34639b6ebb64 100644
--- a/include/llvm/MC/MCSymbolWasm.h
+++ b/include/llvm/MC/MCSymbolWasm.h
@@ -19,7 +19,8 @@ class MCSymbolWasm : public MCSymbol {
bool IsWeak = false;
bool IsHidden = false;
bool IsComdat = false;
- std::string ModuleName;
+ Optional<std::string> ImportModule;
+ Optional<std::string> ImportName;
wasm::WasmSignature *Signature = nullptr;
Optional<wasm::WasmGlobalType> GlobalType;
Optional<wasm::WasmEventType> EventType;
@@ -32,7 +33,7 @@ public:
// Use a module name of "env" for now, for compatibility with existing tools.
// This is temporary, and may change, as the ABI is not yet stable.
MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
- : MCSymbol(SymbolKindWasm, Name, isTemporary), ModuleName("env") {}
+ : MCSymbol(SymbolKindWasm, Name, isTemporary) {}
static bool classof(const MCSymbol *S) { return S->isWasm(); }
const MCExpr *getSize() const { return SymbolSize; }
@@ -55,8 +56,21 @@ public:
bool isComdat() const { return IsComdat; }
void setComdat(bool isComdat) { IsComdat = isComdat; }
- const StringRef getModuleName() const { return ModuleName; }
- void setModuleName(StringRef Name) { ModuleName = Name; }
+ const StringRef getImportModule() const {
+ if (ImportModule.hasValue()) {
+ return ImportModule.getValue();
+ }
+ return "env";
+ }
+ void setImportModule(StringRef Name) { ImportModule = Name; }
+
+ const StringRef getImportName() const {
+ if (ImportName.hasValue()) {
+ return ImportName.getValue();
+ }
+ return getName();
+ }
+ void setImportName(StringRef Name) { ImportName = Name; }
const wasm::WasmSignature *getSignature() const { return Signature; }
void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp
index 0cca3757be90..333748db9190 100644
--- a/lib/MC/WasmObjectWriter.cpp
+++ b/lib/MC/WasmObjectWriter.cpp
@@ -982,7 +982,8 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
encodeULEB128(Sym.ElementIndex, W.OS);
- if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
+ (Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeString(Sym.Name);
break;
case wasm::WASM_SYMBOL_TYPE_DATA:
@@ -1162,8 +1163,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
MCSymbolWasm *MemorySym =
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__linear_memory"));
wasm::WasmImport MemImport;
- MemImport.Module = MemorySym->getModuleName();
- MemImport.Field = MemorySym->getName();
+ MemImport.Module = MemorySym->getImportModule();
+ MemImport.Field = MemorySym->getImportName();
MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY;
Imports.push_back(MemImport);
@@ -1173,8 +1174,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
MCSymbolWasm *TableSym =
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__indirect_function_table"));
wasm::WasmImport TableImport;
- TableImport.Module = TableSym->getModuleName();
- TableImport.Field = TableSym->getName();
+ TableImport.Module = TableSym->getImportModule();
+ TableImport.Field = TableSym->getImportName();
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
Imports.push_back(TableImport);
@@ -1200,8 +1201,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
if (!WS.isDefined() && !WS.isComdat()) {
if (WS.isFunction()) {
wasm::WasmImport Import;
- Import.Module = WS.getModuleName();
- Import.Field = WS.getName();
+ Import.Module = WS.getImportModule();
+ Import.Field = WS.getImportName();
Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
Import.SigIndex = getFunctionType(WS);
Imports.push_back(Import);
@@ -1211,8 +1212,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
report_fatal_error("undefined global symbol cannot be weak");
wasm::WasmImport Import;
- Import.Module = WS.getModuleName();
- Import.Field = WS.getName();
+ Import.Module = WS.getImportModule();
+ Import.Field = WS.getImportName();
Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
Import.Global = WS.getGlobalType();
Imports.push_back(Import);
@@ -1222,8 +1223,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
report_fatal_error("undefined event symbol cannot be weak");
wasm::WasmImport Import;
- Import.Module = WS.getModuleName();
- Import.Field = WS.getName();
+ Import.Module = WS.getImportModule();
+ Import.Field = WS.getImportName();
Import.Kind = wasm::WASM_EXTERNAL_EVENT;
Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
Import.Event.SigIndex = getEventType(WS);
@@ -1448,6 +1449,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
if (WS.isUndefined())
Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+ if (WS.getName() != WS.getImportName())
+ Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME;
wasm::WasmSymbolInfo Info;
Info.Name = WS.getName();
diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp
index d84cb48c9fbd..66a53becbb05 100644
--- a/lib/Object/WasmObjectFile.cpp
+++ b/lib/Object/WasmObjectFile.cpp
@@ -505,9 +505,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
Function.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
Signature = &Signatures[Import.SigIndex];
- Info.Name = Import.Field;
- Info.Module = Import.Module;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
}
break;
@@ -530,8 +534,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
Global.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
- Info.Name = Import.Field;
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
GlobalType = &Import.Global;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
}
break;
@@ -585,9 +594,14 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
} else {
wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
EventType = &Import.Event;
Signature = &Signatures[EventType->SigIndex];
- Info.Name = Import.Field;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
}
break;
}
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
index 50143fb0ece3..7caeebb1a9aa 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
@@ -113,8 +113,15 @@ void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
}
void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
- StringRef ModuleName) {
- OS << "\t.import_module\t" << Sym->getName() << ", " << ModuleName << '\n';
+ StringRef ImportModule) {
+ OS << "\t.import_module\t" << Sym->getName() << ", "
+ << ImportModule << '\n';
+}
+
+void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
+ StringRef ImportName) {
+ OS << "\t.import_name\t" << Sym->getName() << ", "
+ << ImportName << '\n';
}
void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
index 3073938118b4..2ee9956c8e38 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
@@ -45,7 +45,10 @@ public:
virtual void emitEventType(const MCSymbolWasm *Sym) = 0;
/// .import_module
virtual void emitImportModule(const MCSymbolWasm *Sym,
- StringRef ModuleName) = 0;
+ StringRef ImportModule) = 0;
+ /// .import_name
+ virtual void emitImportName(const MCSymbolWasm *Sym,
+ StringRef ImportName) = 0;
protected:
void emitValueType(wasm::ValType Type);
@@ -67,7 +70,8 @@ public:
void emitIndIdx(const MCExpr *Value) override;
void emitGlobalType(const MCSymbolWasm *Sym) override;
void emitEventType(const MCSymbolWasm *Sym) override;
- void emitImportModule(const MCSymbolWasm *Sym, StringRef ModuleName) override;
+ void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule) override;
+ void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName) override;
};
/// This part is for Wasm object output
@@ -82,7 +86,9 @@ public:
void emitGlobalType(const MCSymbolWasm *Sym) override {}
void emitEventType(const MCSymbolWasm *Sym) override {}
void emitImportModule(const MCSymbolWasm *Sym,
- StringRef ModuleName) override {}
+ StringRef ImportModule) override {}
+ void emitImportName(const MCSymbolWasm *Sym,
+ StringRef ImportName) override {}
};
/// This part is for null output
@@ -98,6 +104,7 @@ public:
void emitGlobalType(const MCSymbolWasm *) override {}
void emitEventType(const MCSymbolWasm *) override {}
void emitImportModule(const MCSymbolWasm *, StringRef) override {}
+ void emitImportName(const MCSymbolWasm *, StringRef) override {}
};
} // end namespace llvm
diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index c4f03dfa7f9e..b492d1146950 100644
--- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -111,9 +111,16 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
F.hasFnAttribute("wasm-import-module")) {
StringRef Name =
F.getFnAttribute("wasm-import-module").getValueAsString();
- Sym->setModuleName(Name);
+ Sym->setImportModule(Name);
getTargetStreamer()->emitImportModule(Sym, Name);
}
+ if (TM.getTargetTriple().isOSBinFormatWasm() &&
+ F.hasFnAttribute("wasm-import-name")) {
+ StringRef Name =
+ F.getFnAttribute("wasm-import-name").getValueAsString();
+ Sym->setImportName(Name);
+ getTargetStreamer()->emitImportName(Sym, Name);
+ }
}
}
diff --git a/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp b/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
index 1a416520f97d..13f37f611ed0 100644
--- a/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
+++ b/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
@@ -36,11 +36,6 @@ using namespace llvm;
#define DEBUG_TYPE "wasm-fix-function-bitcasts"
-static cl::opt<bool>
- TemporaryWorkarounds("wasm-temporary-workarounds",
- cl::desc("Apply certain temporary workarounds"),
- cl::init(true), cl::Hidden);
-
namespace {
class FixFunctionBitcasts final : public ModulePass {
StringRef getPassName() const override {
@@ -227,6 +222,17 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
return Wrapper;
}
+// Test whether a main function with type FuncTy should be rewritten to have
+// type MainTy.
+bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy) {
+ // Only fix the main function if it's the standard zero-arg form. That way,
+ // the standard cases will work as expected, and users will see signature
+ // mismatches from the linker for non-standard cases.
+ return FuncTy->getReturnType() == MainTy->getReturnType() &&
+ FuncTy->getNumParams() == 0 &&
+ !FuncTy->isVarArg();
+}
+
bool FixFunctionBitcasts::runOnModule(Module &M) {
LLVM_DEBUG(dbgs() << "********** Fix Function Bitcasts **********\n");
@@ -243,14 +249,14 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
// "int main(int argc, char *argv[])", create an artificial call with it
// bitcasted to that type so that we generate a wrapper for it, so that
// the C runtime can call it.
- if (!TemporaryWorkarounds && !F.isDeclaration() && F.getName() == "main") {
+ if (F.getName() == "main") {
Main = &F;
LLVMContext &C = M.getContext();
Type *MainArgTys[] = {Type::getInt32Ty(C),
PointerType::get(Type::getInt8PtrTy(C), 0)};
FunctionType *MainTy = FunctionType::get(Type::getInt32Ty(C), MainArgTys,
/*isVarArg=*/false);
- if (F.getFunctionType() != MainTy) {
+ if (shouldFixMainFunction(F.getFunctionType(), MainTy)) {
LLVM_DEBUG(dbgs() << "Found `main` function with incorrect type: "
<< *F.getFunctionType() << "\n");
Value *Args[] = {UndefValue::get(MainArgTys[0]),
@@ -298,12 +304,18 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
Main->setName("__original_main");
Function *MainWrapper =
cast<Function>(CallMain->getCalledValue()->stripPointerCasts());
- MainWrapper->setName("main");
- MainWrapper->setLinkage(Main->getLinkage());
- MainWrapper->setVisibility(Main->getVisibility());
- Main->setLinkage(Function::PrivateLinkage);
- Main->setVisibility(Function::DefaultVisibility);
delete CallMain;
+ if (Main->isDeclaration()) {
+ // The wrapper is not needed in this case as we don't need to export
+ // it to anyone else.
+ MainWrapper->eraseFromParent();
+ } else {
+ // Otherwise give the wrapper the same linkage as the original main
+ // function, so that it can be called from the same places.
+ MainWrapper->setName("main");
+ MainWrapper->setLinkage(Main->getLinkage());
+ MainWrapper->setVisibility(Main->getVisibility());
+ }
}
return true;
diff --git a/test/CodeGen/WebAssembly/call.ll b/test/CodeGen/WebAssembly/call.ll
index db666a6c3668..77f17c850eda 100644
--- a/test/CodeGen/WebAssembly/call.ll
+++ b/test/CodeGen/WebAssembly/call.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -mattr=+sign-ext,+simd128 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -mattr=+sign-ext,+simd128 | FileCheck %s
; Test that basic call operations assemble as expected.
diff --git a/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll b/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll
index 515c5703d86c..b542276e068f 100644
--- a/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll
+++ b/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false -wasm-keep-registers | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-keep-registers | FileCheck %s
; Test that function pointer casts casting away varargs are replaced with
; wrappers.
diff --git a/test/CodeGen/WebAssembly/function-bitcasts.ll b/test/CodeGen/WebAssembly/function-bitcasts.ll
index a779cbe41422..813e8420ae54 100644
--- a/test/CodeGen/WebAssembly/function-bitcasts.ll
+++ b/test/CodeGen/WebAssembly/function-bitcasts.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers -enable-emscripten-cxx-exceptions -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers -enable-emscripten-cxx-exceptions | FileCheck %s
; Test that function pointer casts are replaced with wrappers.
diff --git a/test/CodeGen/WebAssembly/import-module.ll b/test/CodeGen/WebAssembly/import-module.ll
index a8202a77acb5..0cf0f2f25e0b 100644
--- a/test/CodeGen/WebAssembly/import-module.ll
+++ b/test/CodeGen/WebAssembly/import-module.ll
@@ -12,8 +12,9 @@ define void @test() {
declare void @foo() #0
declare void @plain()
-attributes #0 = { "wasm-import-module"="bar" }
+attributes #0 = { "wasm-import-module"="bar" "wasm-import-name"="qux" }
; CHECK-NOT: .import_module plain
; CHECK: .import_module foo, bar
+; CHECK: .import_name foo, qux
; CHECK-NOT: .import_module plain
diff --git a/test/CodeGen/WebAssembly/main-declaration.ll b/test/CodeGen/WebAssembly/main-declaration.ll
index f9d68db2bae8..544f5588c504 100644
--- a/test/CodeGen/WebAssembly/main-declaration.ll
+++ b/test/CodeGen/WebAssembly/main-declaration.ll
@@ -1,20 +1,18 @@
-; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
; Test main functions with alternate signatures.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
-declare void @main()
+declare i32 @main()
-define void @foo() {
- call void @main()
- ret void
+define i32 @foo() {
+ %t = call i32 @main()
+ ret i32 %t
}
-; CHECK-NOT: __original_main
; CHECK-LABEL: foo:
-; CHECK-NEXT: .functype foo () -> ()
-; CHECK-NEXT: call main@FUNCTION
+; CHECK-NEXT: .functype foo () -> (i32)
+; CHECK-NEXT: call __original_main@FUNCTION
; CHECK-NEXT: end_function
-; CHECK-NOT: __original_main
diff --git a/test/CodeGen/WebAssembly/main-no-args.ll b/test/CodeGen/WebAssembly/main-no-args.ll
index 0bc46717d97b..97023e269454 100644
--- a/test/CodeGen/WebAssembly/main-no-args.ll
+++ b/test/CodeGen/WebAssembly/main-no-args.ll
@@ -1,18 +1,19 @@
-; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
; Test main functions with alternate signatures.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
-define void @main() {
- ret void
+define i32 @main() {
+ ret i32 0
}
-; CHECK-LABEL: .L__original_main:
-; CHECK-NEXT: .functype .L__original_main () -> ()
+; CHECK-LABEL: __original_main:
+; CHECK-NEXT: .functype __original_main () -> (i32)
+; CHECK-NEXT: i32.const 0
; CHECK-NEXT: end_function
; CHECK-LABEL: main:
; CHECK-NEXT: .functype main (i32, i32) -> (i32)
-; CHECK: call .L__original_main@FUNCTION
+; CHECK: call __original_main@FUNCTION
diff --git a/test/CodeGen/WebAssembly/main-three-args.ll b/test/CodeGen/WebAssembly/main-three-args.ll
new file mode 100644
index 000000000000..77b3e5b8c306
--- /dev/null
+++ b/test/CodeGen/WebAssembly/main-three-args.ll
@@ -0,0 +1,16 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+; Test that main function with a non-standard third argument is
+; not wrapped.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define i32 @main(i32 %a, i8** %b, i8** %c) {
+ ret i32 0
+}
+
+; CHECK-LABEL: main:
+; CHECK-NEXT: .functype main (i32, i32, i32) -> (i32)
+
+; CHECK-NOT: __original_main:
diff --git a/test/CodeGen/WebAssembly/main-with-args.ll b/test/CodeGen/WebAssembly/main-with-args.ll
index d4a11ef14d46..205cb133f8ca 100644
--- a/test/CodeGen/WebAssembly/main-with-args.ll
+++ b/test/CodeGen/WebAssembly/main-with-args.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
; Test that main function with expected signature is not wrapped
diff --git a/test/MC/WebAssembly/external-func-address.ll b/test/MC/WebAssembly/external-func-address.ll
index 60ec23a1a8ed..8e36c76e84f3 100644
--- a/test/MC/WebAssembly/external-func-address.ll
+++ b/test/MC/WebAssembly/external-func-address.ll
@@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown"
declare void @f0(i32) #0
@ptr_to_f0 = hidden global void (i32)* @f0, align 4
-attributes #0 = { "wasm-import-module"="somewhere" }
+attributes #0 = { "wasm-import-module"="somewhere" "wasm-import-name"="something" }
declare void @f1(i32) #1
@ptr_to_f1 = hidden global void (i32)* @f1, align 4
@@ -47,7 +47,7 @@ define void @call(i32) {
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 1
; CHECK: - Module: somewhere
-; CHECK-NEXT: Field: f0
+; CHECK-NEXT: Field: something
; CHECK: - Module: env
; CHECK-NEXT: Field: f1
; CHECK-NEXT: Kind: FUNCTION
diff --git a/test/MC/WebAssembly/import-module.ll b/test/MC/WebAssembly/import-module.ll
new file mode 100644
index 000000000000..461d5c20ae9b
--- /dev/null
+++ b/test/MC/WebAssembly/import-module.ll
@@ -0,0 +1,31 @@
+; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define void @test() {
+ call void @foo()
+ call void @plain()
+ ret void
+}
+
+declare void @foo() #0
+declare void @plain()
+
+attributes #0 = { "wasm-import-module"="bar" "wasm-import-name"="qux" }
+
+; CHECK: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK: - Module: bar
+; CHECK-NEXT: Field: qux
+; CHECK-NEXT: Kind: FUNCTION
+
+; CHECK: - Module: env
+; CHECK-NEXT: Field: plain
+; CHECK-NEXT: Kind: FUNCTION
+
+; CHECK: - Type: CUSTOM
+; CHECK: Name: foo
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+
+; CHECK: Name: plain
+; CHECK-NEXT: Flags: [ UNDEFINED ]
diff --git a/tools/yaml2obj/yaml2wasm.cpp b/tools/yaml2obj/yaml2wasm.cpp
index 2d3e3b71f086..7d08e62bcedd 100644
--- a/tools/yaml2obj/yaml2wasm.cpp
+++ b/tools/yaml2obj/yaml2wasm.cpp
@@ -172,7 +172,8 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
encodeULEB128(Info.ElementIndex, SubSection.GetStream());
- if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
+ (Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeStringRef(Info.Name, SubSection.GetStream());
break;
case wasm::WASM_SYMBOL_TYPE_DATA: