OSDN Git Service

[WebAssembly] Fix ScopeTops info in CFGStackify for EH pads
authorHeejin Ahn <aheejin@gmail.com>
Wed, 27 Feb 2019 01:35:14 +0000 (01:35 +0000)
committerHeejin Ahn <aheejin@gmail.com>
Wed, 27 Feb 2019 01:35:14 +0000 (01:35 +0000)
Summary:
When creating `ScopeTops` info for `try` ~ `catch` ~ `end_try`, we
should create not only `end_try` -> `try` mapping but also `catch` ->
`try` mapping as well. If this is not created, `block` and `end_block`
markers later added may span across an existing `catch`, resulting in
the incorrect code like:
```
try
  block     --|  (X)
catch         |
  end_block --|
end_try
```

Reviewers: dschuff

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

Tags: #llvm

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

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

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

index 9001787..35ca7b9 100644 (file)
@@ -594,11 +594,22 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
               TII.get(WebAssembly::END_TRY));
   registerTryScope(Begin, End, &MBB);
 
-  // Track the farthest-spanning scope that ends at this point.
-  int Number = Cont->getNumber();
-  if (!ScopeTops[Number] ||
-      ScopeTops[Number]->getNumber() > Header->getNumber())
-    ScopeTops[Number] = Header;
+  // Track the farthest-spanning scope that ends at this point. We create two
+  // mappings: (BB with 'end_try' -> BB with 'try') and (BB with 'catch' -> BB
+  // with 'try'). We need to create 'catch' -> 'try' mapping here too because
+  // markers should not span across 'catch'. For example, this should not
+  // happen:
+  //
+  // try
+  //   block     --|  (X)
+  // catch         |
+  //   end_block --|
+  // end_try
+  for (int Number : {Cont->getNumber(), MBB.getNumber()}) {
+    if (!ScopeTops[Number] ||
+        ScopeTops[Number]->getNumber() > Header->getNumber())
+      ScopeTops[Number] = Header;
+  }
 }
 
 void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) {
index 8e99334..ed1996f 100644 (file)
@@ -88,7 +88,44 @@ try.cont:                                         ; preds = %entry, %catch, %cat
 ; }
 
 ; CHECK-LABEL: test1
-; TODO Fill in CHECK lines once we fix ScopeTops info bug in D58605
+; CHECK: try
+; CHECK:   call      foo
+; CHECK: catch
+; CHECK:   block
+; CHECK:     block
+; CHECK:       br_if     0, {{.*}}                     # 0: down to label7
+; CHECK:       i32.call  $drop=, __cxa_begin_catch
+; CHECK:       try
+; CHECK:         call      foo
+; CHECK:         br        2                           # 2: down to label6
+; CHECK:       catch
+; CHECK:         try
+; CHECK:           block
+; CHECK:             br_if     0, {{.*}}               # 0: down to label11
+; CHECK:             i32.call  $drop=, __cxa_begin_catch
+; CHECK:             try
+; CHECK:               call      foo
+; CHECK:               br        2                     # 2: down to label10
+; CHECK:             catch
+; CHECK:               call      __cxa_end_catch
+; CHECK:               rethrow                         # down to catch3
+; CHECK:             end_try
+; CHECK:           end_block                           # label11:
+; CHECK:           call      __cxa_rethrow
+; CHECK:           unreachable
+; CHECK:         catch     {{.*}}                      # catch3:
+; CHECK:           call      __cxa_end_catch
+; CHECK:           rethrow                             # to caller
+; CHECK:         end_try                               # label10:
+; CHECK:         call      __cxa_end_catch
+; CHECK:         br        2                           # 2: down to label6
+; CHECK:       end_try
+; CHECK:     end_block                                 # label7:
+; CHECK:     call      __cxa_rethrow
+; CHECK:     unreachable
+; CHECK:   end_block                                   # label6:
+; CHECK:   call      __cxa_end_catch
+; CHECK: end_try
 define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
 entry:
   invoke void @foo()