forked from OSchip/llvm-project
[WebAssembly] Handle multiple EH_LABELs in EH pad
Usually `EH_LABEL`s are placed in - Before an `invoke` (which becomes calls in the backend) - After an `invoke` - At the start of an EH pad I don't know exactly why, but I noticed there are cases of multiple, not a single, `EH_LABEL` instructions in the beginning of an EH pad. In that case `global.set` instruction placed to restore `__stack_pointer` ended up between two `EH_LABEL` instructions before `CATCH`. It should follow after the `EH_LABEL`s and `CATCH`. This CL fixes that case. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D96970
This commit is contained in:
parent
406dc54903
commit
6f2999b36a
|
@ -212,7 +212,7 @@ bool WebAssemblyLateEHPrepare::addCatchAlls(MachineFunction &MF) {
|
|||
while (InsertPos != MBB.end() && InsertPos->isEHLabel())
|
||||
InsertPos++;
|
||||
// This runs after hoistCatches(), so we assume that if there is a catch,
|
||||
// that should be the non-EH label first instruction in an EH pad.
|
||||
// that should be the first non-EH-label instruction in an EH pad.
|
||||
if (InsertPos == MBB.end() ||
|
||||
!WebAssembly::isCatch(InsertPos->getOpcode())) {
|
||||
Changed = true;
|
||||
|
@ -383,10 +383,13 @@ bool WebAssemblyLateEHPrepare::restoreStackPointer(MachineFunction &MF) {
|
|||
// with leaf functions, and we don't restore __stack_pointer in leaf
|
||||
// functions anyway.
|
||||
auto InsertPos = MBB.begin();
|
||||
if (InsertPos->isEHLabel()) // EH pad starts with an EH label
|
||||
++InsertPos;
|
||||
if (WebAssembly::isCatch(InsertPos->getOpcode()))
|
||||
++InsertPos;
|
||||
// Skip EH_LABELs in the beginning of an EH pad if present.
|
||||
while (InsertPos != MBB.end() && InsertPos->isEHLabel())
|
||||
InsertPos++;
|
||||
assert(InsertPos != MBB.end() &&
|
||||
WebAssembly::isCatch(InsertPos->getOpcode()) &&
|
||||
"catch/catch_all should be present in every EH pad at this point");
|
||||
++InsertPos; // Skip the catch instruction
|
||||
FrameLowering->writeSPToGlobal(FrameLowering->getSPReg(MF), MF, MBB,
|
||||
InsertPos, MBB.begin()->getDebugLoc());
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
name: eh_label_test
|
||||
liveins:
|
||||
- { reg: '$arguments' }
|
||||
frameInfo:
|
||||
hasCalls: true
|
||||
body: |
|
||||
bb.0:
|
||||
; TRY should be before EH_LABEL wrappers of throwing calls
|
||||
|
@ -41,10 +43,15 @@ body: |
|
|||
bb.1 (landing-pad):
|
||||
; predecessors: %bb.0
|
||||
successors: %bb.2
|
||||
; CATCH_ALL should be after an EH_LABEL at the beginning of an EH pad
|
||||
; CATCH_ALL should be after EH_LABELs in the beginning of an EH pad.
|
||||
; (Sometimes there are multiple EH_LABELs in an EH pad. This test tests
|
||||
; that.) GLOBAL_SET should follow right after that.
|
||||
; CHECK: bb.1
|
||||
; CHECK: EH_LABEL
|
||||
; CHECK: EH_LABEL
|
||||
; CHECK-NEXT: CATCH_ALL
|
||||
; CHECK-NEXT: GLOBAL_SET_I32
|
||||
EH_LABEL <mcsymbol .Ltmp2>
|
||||
EH_LABEL <mcsymbol .Ltmp2>
|
||||
CATCHRET %bb.2, %bb.1, implicit-def dead $arguments
|
||||
|
||||
|
|
Loading…
Reference in New Issue