]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Make sure EH pads are preferred in sorting
authorHeejin Ahn <aheejin@gmail.com>
Tue, 1 Oct 2019 06:53:28 +0000 (06:53 +0000)
committerHeejin Ahn <aheejin@gmail.com>
Tue, 1 Oct 2019 06:53:28 +0000 (06:53 +0000)
Summary:
In CFGSort, we try to make EH pads have higher priorities as soon as
they are ready to be sorted, to prevent creation of unwind destination
mismatches in CFGStackify. We did that by making priority queues'
comparison function  prefer EH pads, but it was possible for an EH pad
to be popped from `Preferred` queue and then not sorted immediately and
enter `Ready` queue instead in a certain condition. This patch makes
sure that special condition does not consider EH pads as its candidates.

Reviewers: dschuff

Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68229

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373302 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
test/CodeGen/WebAssembly/cfg-stackify-eh.ll

index 9f94866c08901bc58f7be8d5d9d8866a812115b1..c069af9eed623bafcb54cb1e1f61cddccd724caa 100644 (file)
@@ -317,6 +317,7 @@ static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI,
       // If Next was originally ordered before MBB, and it isn't because it was
       // loop-rotated above the header, it's not preferred.
       if (Next->getNumber() < MBB->getNumber() &&
+          (WasmDisableEHPadSort || !Next->isEHPad()) &&
           (!R || !R->contains(Next) ||
            R->getHeader()->getNumber() < Next->getNumber())) {
         Ready.push(Next);
index 104e324faaed746dcbfa7ce81ebc5a8cf53da40d..191c3d785521f7a87d552cad0b4afd540131b143 100644 (file)
@@ -621,6 +621,49 @@ try.cont:                                         ; preds = %catch.start1, %catc
   ret void
 }
 
+; In CFGSort, EH pads should be sorted as soon as it is available and
+; 'Preferred' queue and should NOT be entered into 'Ready' queue unless we are
+; in the middle of sorting another region that does not contain the EH pad. In
+; this example, 'catch.start' should be sorted right after 'if.then' is sorted
+; (before 'cont' is sorted) and there should not be any unwind destination
+; mismatches in CFGStackify.
+
+; NOOPT: block
+; NOOPT:   try
+; NOOPT:     call      foo
+; NOOPT:   catch
+; NOOPT:   end_try
+; NOOPT:   call      foo
+; NOOPT: end_block
+; NOOPT: return
+define void @test9(i32 %arg) personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+entry:
+  %tobool = icmp ne i32 %arg, 0
+  br i1 %tobool, label %if.then, label %if.end
+
+catch.dispatch:                                   ; preds = %if.then
+  %0 = catchswitch within none [label %catch.start] unwind to caller
+
+catch.start:                                      ; preds = %catch.dispatch
+  %1 = catchpad within %0 [i8* null]
+  %2 = call i8* @llvm.wasm.get.exception(token %1)
+  %3 = call i32 @llvm.wasm.get.ehselector(token %1)
+  %4 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
+  call void @__cxa_end_catch() [ "funclet"(token %1) ]
+  catchret from %1 to label %if.end
+
+if.then:                                          ; preds = %entry
+  invoke void @foo()
+          to label %cont unwind label %catch.dispatch
+
+cont:                                             ; preds = %if.then
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %cont, %catch.start, %entry
+  ret void
+}
+
 declare void @foo()
 declare void @bar()
 declare i32 @baz()