When two symbols import the same thing, only one import should be emitted in the Wasm file.
Details
Diff Detail
Unit Tests
Event Timeline
lld/test/wasm/duplicate-function-imports.ll | ||
---|---|---|
1 ↗ | (On Diff #356845) | Why .ll and not .s here? |
lld/test/wasm/duplicate-global-imports.s | ||
31 | Maybe we should do a global.get on each of these globals so we can see that the de-duplication is working in the relocations. Sadly obj2yaml doesn't do disassembly so the test will be a little opaque, at least until https://reviews.llvm.org/D105539 lands | |
lld/test/wasm/duplicate-table-imports.s | ||
41 | Lets do a .get on each of the tables? | |
lld/wasm/SyntheticSections.h | ||
198 | Maybe just importedGlobals, importedFunctions and importedTables? |
lld/test/wasm/duplicate-function-imports.ll | ||
---|---|---|
1 ↗ | (On Diff #356845) | I used .ll because it was the first test I wrote and it was derived from the C snippet. I'm happy to change it to .s if you prefer. |
lld/test/wasm/duplicate-global-imports.s | ||
31 | Regarding this and removing --no-gc-sections: is it generally preferred to create uses of things rather than to pass --no-gc-sections in tests? Happy to update this either way, just curious. | |
lld/test/wasm/duplicate-table-imports.s | ||
3 | Will do. | |
41 | There is a table.get for each table:
| |
lld/wasm/SyntheticSections.h | ||
198 | Sure thing, will change to these names. |
lld/test/wasm/duplicate-table-imports.s | ||
---|---|---|
3 | I switched to --export-all rather than explicitly enumerating each export, but removing --allow-undefined makes it error out because the t{1,2,3} symbols are undefined, and I don't know how to make a defined, imported table in a .s. |
lld/test/wasm/duplicate-function-imports.ll | ||
---|---|---|
1 ↗ | (On Diff #356845) | Yes please, I've been trying to covert all the existing .ll tests .s for a while so would rather not any any new .ll if possible. |
lld/test/wasm/duplicate-global-imports.s | ||
31 | My general philosophy is to try to minimize the number of flags passed in a given test. This tends to make to more obvious what is being tested (less noise) and makes makes it easier to find tests for a given open by simply grepping for it. There could also be an argument that we want to do most of our testing on the default path since that is the most well trodden one... maybe? Of course its a balance and we don't want to be jumping through too many hoops to avoid extra flags. |
Updated based on review feedback:
- Removed --allow-undefined and --no-gc-sections from duplicate-global-imports.s
- Added global.gets for each global in duplicate-global-imports.s
- Switched to --export-all instead of explicitly listing each export in duplicate-table-imports.s
- Renamed alreadyImportedStuff to importedStuff
Given that we're doing things like GC in the linker, and that the linker is already responsible for creating the imports in the first place (and already has several different options affecting that) I think this makes sense for the linker too.
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
126 | Do these need to be optional? Doesn't getImportModuleAndName unconditionally set them? |
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
113 | The fact that we need template here make me thing maybe we should just move importModule/importName into the symbol base class and we could then just do isUndefined() here... but that is a bigger change. | |
lld/wasm/SyntheticSections.h | ||
156 | What about putting ImportKey and this DenseMapInfo in that anonymous namespace since they should not be needed outside this file? Then we could avoid the prefix in lld::wasm::ImportKey maybe? |
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
113 | I created https://reviews.llvm.org/D106026.. I don't mind which one lands first. |
lld/wasm/SyntheticSections.h | ||
---|---|---|
156 | When I do this, I get the following warning a few times: /home/nick/llvm-project/lld/wasm/SyntheticSections.h:165:7: warning: ‘lld::wasm::ImportSection’ has a field ‘lld::wasm::ImportSection::importedGlobals’ whose type uses the anonymous namespace [-Wsubobject-linkage] 165 | class ImportSection : public SyntheticSection { | ^~~~~~~~~~~~~ Do you still prefer this approach? |
Do you have any idea what is up with https://reviews.llvm.org/harbormaster/unit/view/870129/ ? Locally the test passes just fine, and the types certainly look correct to me. It almost looks like whatever version of llvm-mc running in CI doesn't understand ref types properly? Pretty confused here.
lld/wasm/SyntheticSections.h | ||
---|---|---|
156 | Oh sorry, I didn't realize this was in a header. Ignore my previous comment. |
@aardappel just added the type checker vary recently (https://reviews.llvm.org/D104945). So maybe you need to update your local branch?
Ah yes, I think this is it. That patch mentions that .globaltype etc must come *before* the entity now, and I believe that is what is going wrong in this test case. Will update the patch in one sec.
What do you think about landing https://reviews.llvm.org/D106026 first? (would avoid the use of template <typename UndefinedT> in this patch).
I don't really mind either way.
Obviously it is one tiny rebase less work for me if this lands first, but that's not much work and if that patch is green and ready to land, then I say go for it.
By the way, I am not LLVM committer, so I'll need your help actually landing this patch when the time comes.
Thanks. This *should* be ready, except that there seems to be a few failures in CI: https://reviews.llvm.org/harbormaster/unit/114556/
AFAICT, they are all unrelated. Not sure whether these are known-flaky tests or how to retry them or what. Any ideas?
Reverted by 16aac493e59519377071e900d119ba2e7e5b525d due to an use-of-uninitialized-value bug.
lld/test/wasm/duplicate-table-imports.s | ||
---|---|---|
44 | Newer tests in other lld ports use ## for non-CHECK-non-RUN comments. | |
lld/wasm/SyntheticSections.h | ||
99 | The coding standard doesn't use /* |
Do you have a link to a CI run with sanitizers enabled, or something like that, that shows which value is uninitialized? Thanks!
Is there documentation anywhere on how to build wasm-ld with memory sanitizer enabled?
I've tried this:
$ cmake -DLLVM_USE_SANITIZER=MemoryWithOrigins -DLLVM_ENABLE_PROJECTS=lld path/to/llvm $ make -j8
but then I get memory sanitizer errors while running make like this:
[ 5%] Building Attributes.inc... Uninitialized bytes in __interceptor_memchr at offset 6 inside [0x7020000006c0, 7) ==1094381==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x52842d in llvm::StringRef::find(char, unsigned long) const /home/nick/llvm-project/llvm/include/llvm/ADT/StringRef.h:319:29 #1 0x11b0ccf in llvm::StringRef::split(llvm::SmallVectorImpl<llvm::StringRef>&, char, int, bool) const /home/nick/llvm-project/llvm/lib/Support/StringRef.cpp:341:20 #2 0x11da056 in llvm::Triple::Triple(llvm::Twine const&) /home/nick/llvm-project/llvm/lib/Support/Triple.cpp:770:19 #3 0x12f4e33 in llvm::sys::getProcessTriple[abi:cxx11]() /home/nick/llvm-project/llvm/lib/Support/Host.cpp:1727:10 #4 0x10b1bd5 in (anonymous namespace)::CommandLineParser::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*, bool) /home/nick/llvm-project/llvm/lib/Support/CommandLine.cpp:1345:17 #5 0x10b1570 in llvm::cl::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*, char const*, bool) /home/nick/llvm-project/llvm/lib/Support/CommandLine.cpp:1320:24 #6 0xff18e5 in main /home/nick/llvm-project/llvm/utils/TableGen/TableGen.cpp:283:3 #7 0x7f773ee7acb1 in __libc_start_main csu/../csu/libc-start.c:314:16 #8 0x428a1d in _start (/home/nick/llvm-project/obj/bin/llvm-tblgen+0x428a1d) Uninitialized value was stored to memory at #0 0x42e7c9 in __msan_memcpy (/home/nick/llvm-project/obj/bin/llvm-tblgen+0x42e7c9) #1 0x527135 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.tcc:225:6 #2 0x11f977f in llvm::Twine::str[abi:cxx11]() const /home/nick/llvm-project/llvm/lib/Support/Twine.cpp:20:12 #3 0x11d9f3d in llvm::Triple::Triple(llvm::Twine const&) /home/nick/llvm-project/llvm/lib/Support/Triple.cpp:765:16 #4 0x12f4e33 in llvm::sys::getProcessTriple[abi:cxx11]() /home/nick/llvm-project/llvm/lib/Support/Host.cpp:1727:10 #5 0x10b1bd5 in (anonymous namespace)::CommandLineParser::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*, bool) /home/nick/llvm-project/llvm/lib/Support/CommandLine.cpp:1345:17 #6 0x10b1570 in llvm::cl::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*, char const*, bool) /home/nick/llvm-project/llvm/lib/Support/CommandLine.cpp:1320:24 #7 0xff18e5 in main /home/nick/llvm-project/llvm/utils/TableGen/TableGen.cpp:283:3 #8 0x7f773ee7acb1 in __libc_start_main csu/../csu/libc-start.c:314:16 Uninitialized value was created by a heap allocation #0 0x4a30a9 in operator new(unsigned long) (/home/nick/llvm-project/obj/bin/llvm-tblgen+0x4a30a9) #1 0x7f773f19c87f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::reserve(unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x14387f) #2 0xffffffffffffef9f (<unknown module>) SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/nick/llvm-project/llvm/include/llvm/ADT/StringRef.h:319:29 in llvm::StringRef::find(char, unsigned long) const Exiting make[2]: *** [include/llvm/IR/CMakeFiles/intrinsics_gen.dir/build.make:136: include/llvm/IR/Attributes.inc] Error 77 make[2]: Leaving directory '/home/nick/llvm-project/obj' make[1]: *** [CMakeFiles/Makefile2:11564: include/llvm/IR/CMakeFiles/intrinsics_gen.dir/all] Error 2 make[1]: Leaving directory '/home/nick/llvm-project/obj' make: *** [Makefile:152: all] Error 2
https://github.com/google/sanitizers/wiki/SanitizerBotReproduceBuild
msan isn't usable without an instrumented C++ standard library.
I personally use simplified https://github.com/MaskRay/Config/wiki/LLVM out/msan
If setting up a local asan build is painful (I've never don't it myself), and you think you know the source of the error you could also just re-land with the fix.
I'm pretty sure the issue was that I was comparing/hashing maximums in WasmLimits's operator== and hash traits unconditionally, rather than only if Flags & WASM_LIMITS_FLAG_HAS_MAX.
Updated to only hash/compare WasmLimits's Maximum when Flags & WASM_LIMITS_FLAGS_HAS_MAX. This should fix the use of uninitialized data that led to reverting the original commit.
lld/wasm/Writer.cpp | ||
---|---|---|
568 ↗ | (On Diff #360936) | Is this chunk intentional? |
lld/wasm/Writer.cpp | ||
---|---|---|
568 ↗ | (On Diff #360936) | Whoops, I think this was a bad rebase. Apologies! Updated patch incoming. |
lld/wasm/SyntheticSections.h | ||
---|---|---|
134 | Please be note this line introduced below build error: ^ In file included from /media/sdb/tao/llvm/llvm-project-debug/lld/wasm/MapFile.h:12:0, from /media/sdb/tao/llvm/llvm-project-debug/lld/wasm/MapFile.cpp:21: /media/sdb/tao/llvm/llvm-project-debug/llvm/include/llvm/ADT/ArrayRef.h:29:31: error: from definition of ‘template<class T> struct llvm::DenseMapInfo’ [-fpermissive] template<typename T> struct DenseMapInfo; |
lld/wasm/SyntheticSections.h | ||
---|---|---|
134 | Looks like there is already a fix in flight: https://reviews.llvm.org/D107422 |
lld/wasm/SyntheticSections.h | ||
---|---|---|
134 | Yes, it's gcc dependent error, I used gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12). My config command is cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt;lld" ../llvm Looks not very special. I know this error won't be triggered with "-D CMAKE_C_COMPILER=clang -D CMAKE_CXX_COMPILER=clang++". |
lld/wasm/SyntheticSections.h | ||
---|---|---|
134 | Do we not have any bots that build with a recent enough gcc version to report this failure? Seems odd. |
lld/wasm/SyntheticSections.h | ||
---|---|---|
134 | I checked recent enough gcc version (11.2.0), this error can't be reproduced, it's gcc old version dependent error. |
I think we can remove --no-gc-sections (if you use each on in a global.get) and --allow-undefined.