diff options
author | Derek Schuff <dschuff@google.com> | 2018-01-19 17:45:54 +0000 |
---|---|---|
committer | Derek Schuff <dschuff@google.com> | 2018-01-19 17:45:54 +0000 |
commit | bfb02aec5a86de2ee8b4a88f03675e50a8e03460 (patch) | |
tree | 3bfd13dd01d9a3c7cdf08d03866d4f3e75819099 /llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp | |
parent | 99894b61baaa37fd03d0311e882e731dd143f1e6 (diff) | |
download | bcm5719-llvm-bfb02aec5a86de2ee8b4a88f03675e50a8e03460.tar.gz bcm5719-llvm-bfb02aec5a86de2ee8b4a88f03675e50a8e03460.zip |
[WebAssembly] Fix libcall signature lookup
RuntimeLibcallSignatures previously manually initialized all the libcall
names into an array and searched it linearly for the first match to lookup
the corresponding index.
r322802 switched that to initializing a map keyed by the libcall name.
Neither of these approaches works correctly because some libcall numbers use
the same name on different platforms (e.g. the "l" suffixed functions
use f80 or f128 or ppcf128).
This change fixes that by ensuring that each name only goes into the map
once. It also adds tests.
Differential Revision: https://reviews.llvm.org/D42271
llvm-svn: 322971
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp index bd97aaf28c1..580daba70c8 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp @@ -296,9 +296,12 @@ struct RuntimeLibcallSignatureTable { Table[RTLIB::UO_F32] = i32_func_f32_f32; Table[RTLIB::UO_F64] = i32_func_f64_f64; Table[RTLIB::UO_F128] = i32_func_i64_i64_i64_i64; - Table[RTLIB::O_F32] = i32_func_f32_f32; - Table[RTLIB::O_F64] = i32_func_f64_f64; - Table[RTLIB::O_F128] = i32_func_i64_i64_i64_i64; + // O_FXX has the weird property that it uses the same libcall name as UO_FXX + // This breaks our name-based lookup. Fortunately only the UO family of + // libcalls appears to be actually used. + Table[RTLIB::O_F32] = unsupported; + Table[RTLIB::O_F64] = unsupported; + Table[RTLIB::O_F128] = unsupported; // Memory Table[RTLIB::MEMCPY] = iPTR_func_iPTR_iPTR_iPTR; @@ -455,26 +458,24 @@ struct RuntimeLibcallSignatureTable { } }; - -StringRef StringRefOrEmpty(const char* arg) { - if (arg) return StringRef(arg); - return StringRef(); -} +ManagedStatic<RuntimeLibcallSignatureTable> RuntimeLibcallSignatures; // Maps libcall names to their RTLIB::Libcall number. Builds the map in a // constructor for use with ManagedStatic struct StaticLibcallNameMap { StringMap<RTLIB::Libcall> Map; StaticLibcallNameMap() { -#define HANDLE_LIBCALL(code, name) \ - Map[StringRefOrEmpty(name)] = RTLIB::code; - #include "llvm/CodeGen/RuntimeLibcalls.def" +#define HANDLE_LIBCALL(code, name) \ + if (name && RuntimeLibcallSignatures->Table[RTLIB::code] != unsupported) { \ + assert(Map.find(StringRef::withNullAsEmpty(name)) == Map.end() && \ + "duplicate libcall names in name map"); \ + Map[StringRef::withNullAsEmpty(name)] = RTLIB::code; \ + } +#include "llvm/CodeGen/RuntimeLibcalls.def" #undef HANDLE_LIBCALL } }; -ManagedStatic<RuntimeLibcallSignatureTable> RuntimeLibcallSignatures; - } // end anonymous namespace |