diff options
author | Heejin Ahn <aheejin@gmail.com> | 2021-02-15 07:32:51 -0800 |
---|---|---|
committer | Heejin Ahn <aheejin@gmail.com> | 2021-02-17 12:14:11 -0800 |
commit | da01a9db8bb4d0ba362e1956ef7fa9bdd5e3b464 (patch) | |
tree | 6a0101ef47844fca9dc1d8db344a606ce315ac01 /llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp | |
parent | 3a030c2f2fe3de62c5eba4f916ce51e5d1214a42 (diff) | |
download | llvm-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.cpp | 32 |
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) |