llvm.org GIT mirror llvm / f0999f3
[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 Reid Kleckner 5 years ago
3 changed file(s) with 40 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
532532 BasicBlock *NextBB;
533533 Constant *Selector;
534534 if (isSelectorDispatch(BB, CatchHandler, Selector, NextBB)) {
535 // Split the edge if there is a phi node. Returning from EH to a phi node
536 // is just as impossible as having a phi after an indirectbr.
537 if (isa(CatchHandler->begin())) {
535 // Split the edge if there are multiple predecessors. This creates a place
536 // where we can insert EH recovery code.
537 if (!CatchHandler->getSinglePredecessor()) {
538538 DEBUG(dbgs() << "splitting EH return edge from " << BB->getName()
539539 << " to " << CatchHandler->getName() << '\n');
540540 BBI = CatchHandler = SplitCriticalEdge(
519519 for (auto &Handler : ActionList) {
520520 if (auto *CH = dyn_cast(Handler.get())) {
521521 auto *BA = cast(CH->getHandlerBlockOrFunc());
522 #ifndef NDEBUG
523 for (BasicBlock *Pred : predecessors(BA->getBasicBlock()))
524 assert(Pred->isLandingPad() &&
525 "WinEHPrepare failed to split block");
526 #endif
522527 ExceptBlocks.insert(BA->getBasicBlock());
523528 }
524529 }
105105 ; CHECK: return:
106106 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad.return_crit_edge ]
107107 ; CHECK-NEXT: ret i32 %r
108
109 define i32 @except_join() personality i32 (...)* @__C_specific_handler {
110 entry:
111 invoke void @might_crash()
112 to label %return unwind label %lpad
113
114 lpad:
115 %ehvals = landingpad { i8*, i32 }
116 catch i32 ()* @filt
117 %sel = extractvalue { i8*, i32 } %ehvals, 1
118 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
119 %matches = icmp eq i32 %sel, %filt_sel
120 br i1 %matches, label %return, label %eh.resume
121
122 return:
123 ret i32 0
124
125 eh.resume:
126 resume { i8*, i32 } %ehvals
127 }
128
129 ; CHECK-LABEL: define i32 @except_join()
130 ; CHECK: landingpad { i8*, i32 }
131 ; CHECK-NEXT: catch i32 ()* @filt
132 ; 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))
133 ; CHECK-NEXT: indirectbr {{.*}} [label %lpad.return_crit_edge]
134 ;
135 ; CHECK: lpad.return_crit_edge:
136 ; CHECK: br label %return
137 ;
138 ; CHECK: return:
139 ; CHECK-NEXT: ret i32 0
108140
109141 define i32 @lpad_phi() personality i32 (...)* @__C_specific_handler {
110142 entry: