[llvm] r354945 - [WebAssembly] Fix ScopeTops info in CFGStackify for EH pads

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 26 17:35:14 PST 2019


Author: aheejin
Date: Tue Feb 26 17:35:14 2019
New Revision: 354945

URL: http://llvm.org/viewvc/llvm-project?rev=354945&view=rev
Log:
[WebAssembly] Fix ScopeTops info in CFGStackify for EH pads

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

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
    llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify-eh.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp?rev=354945&r1=354944&r2=354945&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp Tue Feb 26 17:35:14 2019
@@ -594,11 +594,22 @@ void WebAssemblyCFGStackify::placeTryMar
               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) {

Modified: llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify-eh.ll?rev=354945&r1=354944&r2=354945&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify-eh.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify-eh.ll Tue Feb 26 17:35:14 2019
@@ -88,7 +88,44 @@ try.cont:
 ; }
 
 ; 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()




More information about the llvm-commits mailing list