aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2021-02-15 07:32:51 -0800
committerHeejin Ahn <aheejin@gmail.com>2021-02-17 12:14:11 -0800
commitda01a9db8bb4d0ba362e1956ef7fa9bdd5e3b464 (patch)
tree6a0101ef47844fca9dc1d8db344a606ce315ac01 /llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
parent3a030c2f2fe3de62c5eba4f916ce51e5d1214a42 (diff)
downloadllvm-da01a9db8bb4d0ba362e1956ef7fa9bdd5e3b464.zip
llvm-da01a9db8bb4d0ba362e1956ef7fa9bdd5e3b464.tar.gz
llvm-da01a9db8bb4d0ba362e1956ef7fa9bdd5e3b464.tar.bz2
[WebAssemblly] Fix EHPadStack update in fixCallUnwindMismatches
Updating `EHPadStack` with respect to `TRY` and `CATCH` instructions have to be done after checking all other conditions, not before. Because we did this before checking other conditions, when we encounter `TRY` and we want to record the current mismatching range, we already have popped up the entry from `EHPadStack`, which we need to access to record the range. The `baz` call in the added test needs try-delegate because the previous TRY marker placement for `quux` was placed before `baz`, because `baz`'s return value was stackified in RegStackify. If this wasn't stackified this try-delegate is not strictly necessary, but at the moment it is not easy to identify cases like this. I plan to transfer `nounwind` attributes from the LLVM IR to prevent cases like this. The call in the test does not have `unwind` attribute in order to test this bug, but in many cases of this pattern the previous call has `nounwind` attribute. Reviewed By: tlively Differential Revision: https://reviews.llvm.org/D96711
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 9f5290a..7035f74 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -1192,39 +1192,39 @@ bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
for (auto &MBB : reverse(MF)) {
bool SeenThrowableInstInBB = false;
for (auto &MI : reverse(MBB)) {
- if (MI.getOpcode() == WebAssembly::TRY)
- EHPadStack.pop_back();
- else if (WebAssembly::isCatch(MI.getOpcode()))
- EHPadStack.push_back(MI.getParent());
bool MayThrow = WebAssembly::mayThrow(MI);
// If MBB has an EH pad successor and this is the last instruction that
// may throw, this instruction unwinds to the EH pad and not to the
// caller.
- if (MBB.hasEHPadSuccessor() && MayThrow && !SeenThrowableInstInBB) {
+ if (MBB.hasEHPadSuccessor() && MayThrow && !SeenThrowableInstInBB)
SeenThrowableInstInBB = true;
- continue;
- }
// We wrap up the current range when we see a marker even if we haven't
// finished a BB.
- if (RangeEnd && WebAssembly::isMarker(MI.getOpcode())) {
+ else if (RangeEnd && WebAssembly::isMarker(MI.getOpcode()))
RecordCallerMismatchRange(EHPadStack.back());
- continue;
- }
// If EHPadStack is empty, that means it correctly unwinds to the caller
// if it throws, so we're good. If MI does not throw, we're good too.
- if (EHPadStack.empty() || !MayThrow)
- continue;
+ else if (EHPadStack.empty() || !MayThrow) {
+ }
// We found an instruction that unwinds to the caller but currently has an
// incorrect unwind destination. Create a new range or increment the
// currently existing range.
- if (!RangeEnd)
- RangeBegin = RangeEnd = &MI;
- else
- RangeBegin = &MI;
+ else {
+ if (!RangeEnd)
+ RangeBegin = RangeEnd = &MI;
+ else
+ RangeBegin = &MI;
+ }
+
+ // Update EHPadStack.
+ if (MI.getOpcode() == WebAssembly::TRY)
+ EHPadStack.pop_back();
+ else if (WebAssembly::isCatch(MI.getOpcode()))
+ EHPadStack.push_back(MI.getParent());
}
if (RangeEnd)