aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
index 81c16f0..a237da8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
@@ -50,7 +50,21 @@ bool WebAssembly::mayThrow(const MachineInstr &MI) {
return false;
const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI.getOpcode()));
- assert(MO.isGlobal());
+ assert(MO.isGlobal() || MO.isSymbol());
+
+ if (MO.isSymbol()) {
+ // Some intrinsics are lowered to calls to external symbols, which are then
+ // lowered to calls to library functions. Most of libcalls don't throw, but
+ // we only list some of them here now.
+ // TODO Consider adding 'nounwind' info in TargetLowering::CallLoweringInfo
+ // instead for more accurate info.
+ const char *Name = MO.getSymbolName();
+ if (strcmp(Name, "memcpy") == 0 || strcmp(Name, "memmove") == 0 ||
+ strcmp(Name, "memset") == 0)
+ return false;
+ return true;
+ }
+
const auto *F = dyn_cast<Function>(MO.getGlobal());
if (!F)
return true;