[PATCH] D16319: [Inliner/WinEH] Honor implicit nounwinds
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 19 17:17:36 PST 2016
majnemer accepted this revision.
majnemer added a comment.
This revision is now accepted and ready to land.
LGTM, thanks for fixing this!
================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:615-624
@@ +614,12 @@
+ Value *UnwindDestToken;
+ if (auto *ParentPad =
+ dyn_cast<Instruction>(CatchSwitch->getParentPad())) {
+ // This catchswitch is nested inside another funclet. If that
+ // funclet has an unwind destination within the inlinee, then
+ // unwinding out of this catchswitch would be UB. Rewriting this
+ // catchswitch to unwind to the inlined invoke's unwind dest would
+ // give the parent funclet multiple unwind destinations, which is
+ // something that subsequent EH table generation can't handle and
+ // that the veirifer rejects. So when we see such a call, leave it
+ // as "unwind to caller".
+ UnwindDestToken = getUnwindDestToken(ParentPad, FuncletUnwindMap);
----------------
JosephTremoulet wrote:
> No, this happens when you have an unwind-to-caller catchswitch nested inside an outer pad which unwinds somewhere else in the inlinee. E.g. if you start with
>
> ```
> define void inlinee() {
> ...
> %parent = cleanuppad within none []
> ...
> %current = catchswitch within %parent [label ...] unwind label %sibling
> ...
> sibling:
> %sib = cleanuppad within %parent []
> unreachable
> ...
> cleanupret from %parent unwind label %uncle
> ```
>
> then SimplifyUnreachable could turn that into
>
> ```
> define void inlinee() {
> ...
> %parent = cleanuppad within none []
> ...
> %current = catchswitch within %parent [label ...] unwind to caller
> ...
> cleanupret from %parent unwind label %uncle
> ```
>
> and //that's// the case this code is dealing with.
Would we need to do this if we had catchswitches which could be annotated as nounwind?
http://reviews.llvm.org/D16319
More information about the llvm-commits
mailing list