[PATCH] D16319: [Inliner/WinEH] Honor implicit nounwinds

Joseph Tremoulet via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 19 10:18:25 PST 2016


JosephTremoulet marked 4 inline comments as done.
JosephTremoulet added a comment.

Updated per feedback.


================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:447-450
@@ +446,6 @@
+        MemoKey = CatchPad->getCatchSwitch();
+      else
+        MemoKey = FuncletPad;
+      assert(FuncletUnwindMap->count(MemoKey) &&
+             (*FuncletUnwindMap)[MemoKey] == UnwindDestToken &&
+             "must get memoized to avoid confusing later searches");
----------------
No, if the entire funclet tree has no invokes and consists entirely of cleanuppads that don't have cleanuprets and catchswitches that are "unwind to caller", then `UnwindDestToken` will be null here.

================
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);
----------------
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.


http://reviews.llvm.org/D16319





More information about the llvm-commits mailing list