mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
[SEH] Ensure that empty __except blocks have their own BB
The 32-bit lowering assumed that WinEHPrepare had this invariant. WinEHPrepare did it for C++, but not SEH. The result was that we would insert calls to llvm.x86.seh.restoreframe in normal basic blocks, which corrupted the frame pointer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241699 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1ba30c84d5
commit
f0999f3b02
@ -533,9 +533,9 @@ void WinEHPrepare::findSEHEHReturnPoints(
|
||||
BasicBlock *NextBB;
|
||||
Constant *Selector;
|
||||
if (isSelectorDispatch(BB, CatchHandler, Selector, NextBB)) {
|
||||
// Split the edge if there is a phi node. Returning from EH to a phi node
|
||||
// is just as impossible as having a phi after an indirectbr.
|
||||
if (isa<PHINode>(CatchHandler->begin())) {
|
||||
// Split the edge if there are multiple predecessors. This creates a place
|
||||
// where we can insert EH recovery code.
|
||||
if (!CatchHandler->getSinglePredecessor()) {
|
||||
DEBUG(dbgs() << "splitting EH return edge from " << BB->getName()
|
||||
<< " to " << CatchHandler->getName() << '\n');
|
||||
BBI = CatchHandler = SplitCriticalEdge(
|
||||
|
@ -520,6 +520,11 @@ void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) {
|
||||
for (auto &Handler : ActionList) {
|
||||
if (auto *CH = dyn_cast<CatchHandler>(Handler.get())) {
|
||||
auto *BA = cast<BlockAddress>(CH->getHandlerBlockOrFunc());
|
||||
#ifndef NDEBUG
|
||||
for (BasicBlock *Pred : predecessors(BA->getBasicBlock()))
|
||||
assert(Pred->isLandingPad() &&
|
||||
"WinEHPrepare failed to split block");
|
||||
#endif
|
||||
ExceptBlocks.insert(BA->getBasicBlock());
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,38 @@ eh.resume:
|
||||
; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad.return_crit_edge ]
|
||||
; CHECK-NEXT: ret i32 %r
|
||||
|
||||
define i32 @except_join() personality i32 (...)* @__C_specific_handler {
|
||||
entry:
|
||||
invoke void @might_crash()
|
||||
to label %return unwind label %lpad
|
||||
|
||||
lpad:
|
||||
%ehvals = landingpad { i8*, i32 }
|
||||
catch i32 ()* @filt
|
||||
%sel = extractvalue { i8*, i32 } %ehvals, 1
|
||||
%filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
|
||||
%matches = icmp eq i32 %sel, %filt_sel
|
||||
br i1 %matches, label %return, label %eh.resume
|
||||
|
||||
return:
|
||||
ret i32 0
|
||||
|
||||
eh.resume:
|
||||
resume { i8*, i32 } %ehvals
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define i32 @except_join()
|
||||
; CHECK: landingpad { i8*, i32 }
|
||||
; CHECK-NEXT: catch i32 ()* @filt
|
||||
; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@except_join, %lpad.return_crit_edge))
|
||||
; CHECK-NEXT: indirectbr {{.*}} [label %lpad.return_crit_edge]
|
||||
;
|
||||
; CHECK: lpad.return_crit_edge:
|
||||
; CHECK: br label %return
|
||||
;
|
||||
; CHECK: return:
|
||||
; CHECK-NEXT: ret i32 0
|
||||
|
||||
define i32 @lpad_phi() personality i32 (...)* @__C_specific_handler {
|
||||
entry:
|
||||
invoke void @might_crash()
|
||||
|
Loading…
x
Reference in New Issue
Block a user