diff --git a/include/llvm/MC/MCSymbolWasm.h b/include/llvm/MC/MCSymbolWasm.h index 309ebf96d1b..dc8d26a8858 100644 --- a/include/llvm/MC/MCSymbolWasm.h +++ b/include/llvm/MC/MCSymbolWasm.h @@ -19,6 +19,7 @@ private: bool IsFunction = false; bool IsWeak = false; bool IsHidden = false; + bool IsComdat = false; std::string ModuleName; SmallVector Returns; SmallVector Params; @@ -49,6 +50,9 @@ public: bool isHidden() const { return IsHidden; } void setHidden(bool isHidden) { IsHidden = isHidden; } + bool isComdat() const { return IsComdat; } + void setComdat(bool isComdat) { IsComdat = isComdat; } + const StringRef getModuleName() const { return ModuleName; } const SmallVector &getReturns() const { diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index ac2e45484ed..c7c6ca7a86e 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -490,8 +490,10 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K, const Twine &Group, unsigned UniqueID, const char *BeginSymName) { MCSymbolWasm *GroupSym = nullptr; - if (!Group.isTriviallyEmpty() && !Group.str().empty()) + if (!Group.isTriviallyEmpty() && !Group.str().empty()) { GroupSym = cast(getOrCreateSymbol(Group)); + GroupSym->setComdat(true); + } return getWasmSection(Section, K, GroupSym, UniqueID, BeginSymName); } diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp index e5099a83b6f..ff000733999 100644 --- a/lib/MC/WasmObjectWriter.cpp +++ b/lib/MC/WasmObjectWriter.cpp @@ -1122,7 +1122,8 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, continue; // If the symbol is not defined in this translation unit, import it. - if (!WS.isDefined(/*SetUsed=*/false) || WS.isVariable()) { + if ((!WS.isDefined(/*SetUsed=*/false) && !WS.isComdat()) || + WS.isVariable()) { WasmImport Import; Import.ModuleName = WS.getModuleName(); Import.FieldName = WS.getName(); diff --git a/test/MC/WebAssembly/comdat.ll b/test/MC/WebAssembly/comdat.ll index 30ae9cadb2e..7dc0992c105 100644 --- a/test/MC/WebAssembly/comdat.ll +++ b/test/MC/WebAssembly/comdat.ll @@ -22,7 +22,41 @@ define linkonce_odr i32 @sharedFn() #1 comdat($sharedComdat) { ret i32 0 } -; CHECK: - Type: EXPORT +; CHECK: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: __linear_memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Memory: +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: __indirect_function_table +; CHECK-NEXT: Kind: TABLE +; CHECK-NEXT: Table: +; CHECK-NEXT: ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Initial: 0x00000000 +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: funcImport +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ] +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 0 +; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: callImport ; CHECK-NEXT: Kind: FUNCTION @@ -35,7 +69,7 @@ define linkonce_odr i32 @sharedFn() #1 comdat($sharedComdat) { ; CHECK-NEXT: Index: 3 ; CHECK-NEXT: - Name: constantData ; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 0 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB