Skip to content

Commit 4d1c827

Browse files
authored
[WebAssembly] Support parsing .lto_set_conditional (#126546)
In the split-LTO-unit mode in ThinLTO, a compilation module is split into two and global variables that meet a specific criteria is moved to the split module. https://github.com/llvm/llvm-project/blob/d21fc58aeeaa7f0369a24dbe70a0360e0edbf76f/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp#L315-L366 And if there is an originally local-linkage global value defined in the original module and referenced in the split module or the vice versa, that value is _promoted_ by attaching a module ID to their names in order to prevent name clashes because now they can be referenced from other modules. https://github.com/llvm/llvm-project/blob/d21fc58aeeaa7f0369a24dbe70a0360e0edbf76f/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp#L46-L100 And when that promoted global value is a function, a `.lto_set_conditional` entry is written to the original module to avoid breaking references from inline assembly: https://github.com/llvm/llvm-project/blob/d21fc58aeeaa7f0369a24dbe70a0360e0edbf76f/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp#L84-L91 The syntax of this is, if the original function name is `symbolA` and the module ID is `123`, ```ll module asm ".lto_set_conditional symbolA,symbolA.123" ``` These symbols are parsed here: https://github.com/llvm/llvm-project/blob/648981f913431749c4656268ed670677a88511f6/llvm/lib/MC/MCParser/AsmParser.cpp#L6467 The first function symbol in this `.lto_set_conditional` do not exist as a function in the bitcode anymore because it was renamed to the second. So they are not assigned as function symbols but they are not really data either, so the object writer crashes here: https://github.com/llvm/llvm-project/blob/5b9e6c7993359c16b4d645c851bb7fe2fd7b78c7/llvm/lib/MC/WasmObjectWriter.cpp#L1820 This PR makes the object writer just skip those symbols. --- This problem was discovered when I was testing with `-fwhole-program-vtables`. The reason we didn't have this problem before with ThinLTO was because `-fsplit-lto-unit`, which splits LTO units when possible, defaults to false, but it defaults to true when `-fwhole-program-vtables` is used.
1 parent bd7585b commit 4d1c827

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,18 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
17851785
WS.setIndex(InvalidIndex);
17861786
continue;
17871787
}
1788+
// In bitcode generated by split-LTO-unit mode in ThinLTO, these lines can
1789+
// appear:
1790+
// module asm ".lto_set_conditional symbolA,symbolA.[moduleId]"
1791+
// ...
1792+
// (Here [moduleId] will be replaced by a real module hash ID)
1793+
//
1794+
// Here the original symbol (symbolA here) has been renamed to the new name
1795+
// created by attaching its module ID, so the original symbol does not
1796+
// appear in the bitcode anymore, and thus not in DataLocations. We should
1797+
// ignore them.
1798+
if (WS.isData() && WS.isDefined() && !DataLocations.count(&WS))
1799+
continue;
17881800
LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n");
17891801

17901802
uint32_t Flags = 0;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# RUN: llvm-mc -triple=wasm32-unknown-unknown
2+
3+
# Tests if `.lto_set_conditional` directives are parsed without crashing.
4+
.lto_set_conditional a, a.new
5+
.type a.new,@function
6+
a.new:
7+
.functype a.new () -> ()
8+
end_function

0 commit comments

Comments
 (0)