[PATCH] D15139: [IR] Reformulate LLVM's EH funclet IR

Joseph Tremoulet via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 11 18:35:55 PST 2015


JosephTremoulet added inline comments.

================
Comment at: test/CodeGen/WinEH/wineh-cloning.ll:288-289
@@ -370,75 +287,4 @@
     to label %unreachable unwind label %right
 left:
-  cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-inner:
-  cleanuppad []
-  invoke void @f()
-    to label %unreachable unwind label %inner.child
-inner.child:
-  cleanuppad []
-  %x = call i32 @g()
-  call void @h(i32 %x)
-  unreachable
-unreachable:
-  unreachable
-}
-; %inner is a two-parent child which itself has a child; need
-; to make two copies of both the %inner and %inner.child.
-; CHECK-LABEL: define void @test8(
-; CHECK:     invoke.cont:
-; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
-; CHECK:     left:
-; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:               to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:               to label %[[UNREACHABLE_INNER_RIGHT:.+]] unwind label %[[INNER_CHILD_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:               to label %[[UNREACHABLE_INNER_LEFT:.+]] unwind label %[[INNER_CHILD_LEFT:.+]]
-; CHECK:     [[INNER_CHILD_RIGHT]]:
-; CHECK:       [[TMP:\%.+]] = cleanuppad []
-; CHECK:       [[X:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X]])
-; CHECK:       unreachable
-; CHECK:     [[INNER_CHILD_LEFT]]:
-; CHECK:       [[TMP:\%.+]] = cleanuppad []
-; CHECK:       [[X:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X]])
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_INNER_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_INNER_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_ENTRY]]:
-; CHECK:       unreachable
-
-
-define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %unreachable unwind label %right
-left:
-  cleanuppad []
+  cleanuppad within none []
   call void @h(i32 1)
----------------
majnemer wrote:
> andrew.w.kaylor wrote:
> > The original concern was that some future optimization would innocently transform otherwise reasonable code into this form.  I think the hypothetically dangerous input looked something like this:
> > ```
> > left:
> >   cleanuppad within none []
> >   call void @h(i32 1)
> >   invoke void @f()
> >     to label %unreachable unwind label %not_right
> > not_right:
> >   cleanuppad within none []
> >   call void @h(i32 2)
> >   call void @f()
> >   unreachable
> > right:
> >   cleanuppad within none []
> >   call void @h(i32 2)
> >   invoke void @f()
> >     to label %unreachable unwind label %not_left
> > not_left:
> >   cleanuppad within none []
> >   call void @h(i32 1)
> >   call void @f()
> >   unreachable
> > ```
> > So if we can get that out of the clang front end, then a reasonable optimization could transform it into this test case, and I don't see how the code generator could do anything reasonable with the form shown in this test case.
> Such a hypothetical optimization would be defeated once we add support for bundle operands in the front-end.  The bundle operands will defeat tail-merging/CSE because the call-sites will look like they have different operands.
I think this is another example of a case where we'll need the bundles tagging calls/invokes in EH pads.  With that, the notion of which pad an invoke "is in" will be well-defined, and we'll be able to add a rule that it's UB to take an invoke's unwind edge if its unwind dest's parent pad isn't the parent of the pad that the invoke is in.  WinEHPrep will then be able to prune the UB unwind edges, so if presented with the IR in this test (which, as David points out, couldn't be the result of optimizing your example anymore, but I think would still be legal/verifiable IR) it would see that the two invokes to `@f()` unwind to illegal destinations, and rewrite those as calls.


http://reviews.llvm.org/D15139





More information about the llvm-commits mailing list