[llvm] [WebAssembly] Allow try_table to target loops in AsmTypeCheck (PR #111432)

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 13:30:55 PDT 2024


https://github.com/aheejin updated https://github.com/llvm/llvm-project/pull/111432

>From dc388857bc2746f4be5eccb4c6a5115b20875a64 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Thu, 3 Oct 2024 23:54:18 +0000
Subject: [PATCH 1/2] [WebAssembly] Allow try_table to target loops in
 AsmTypeCheck

---
 .../AsmParser/WebAssemblyAsmTypeCheck.cpp     | 24 ++++++++++++-----
 llvm/test/MC/WebAssembly/annotations.s        | 27 ++++++++++++++++---
 llvm/test/MC/WebAssembly/eh-assembly.s        | 25 ++++++++++++++++-
 .../test/MC/WebAssembly/type-checker-errors.s | 17 ++++++++++++
 4 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
index bfe6996977e690..cc8212d2c9d28d 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
@@ -371,13 +371,23 @@ bool WebAssemblyAsmTypeCheck::checkTryTable(SMLoc ErrorLoc,
     if (Level < BlockInfoStack.size()) {
       const auto &DestBlockInfo =
           BlockInfoStack[BlockInfoStack.size() - Level - 1];
-      if (compareTypes(SentTypes, DestBlockInfo.Sig.Returns)) {
-        std::string ErrorMsg =
-            ErrorMsgBase + "type mismatch, catch tag type is " +
-            getTypesString(SentTypes) + ", but destination's type is " +
-            getTypesString(DestBlockInfo.Sig.Returns);
-        Error |= typeError(ErrorLoc, ErrorMsg);
-      }
+     if (DestBlockInfo.IsLoop) {
+        if (compareTypes(SentTypes, DestBlockInfo.Sig.Params)) {
+          std::string ErrorMsg =
+              ErrorMsgBase + "type mismatch, catch tag type is " +
+              getTypesString(SentTypes) + ", but destination's type is " +
+              getTypesString(DestBlockInfo.Sig.Params);
+          Error |= typeError(ErrorLoc, ErrorMsg);
+        }
+     } else {
+       if (compareTypes(SentTypes, DestBlockInfo.Sig.Returns)) {
+         std::string ErrorMsg =
+             ErrorMsgBase + "type mismatch, catch tag type is " +
+             getTypesString(SentTypes) + ", but destination's type is " +
+             getTypesString(DestBlockInfo.Sig.Returns);
+         Error |= typeError(ErrorLoc, ErrorMsg);
+       }
+     }
     } else {
       Error = typeError(ErrorLoc, ErrorMsgBase + "invalid depth " +
                                       std::to_string(Level));
diff --git a/llvm/test/MC/WebAssembly/annotations.s b/llvm/test/MC/WebAssembly/annotations.s
index 2a5bea27941789..f761ef3f06b1fc 100644
--- a/llvm/test/MC/WebAssembly/annotations.s
+++ b/llvm/test/MC/WebAssembly/annotations.s
@@ -7,7 +7,7 @@
   .section .text.test_annotation,"",@
   .type    test_annotation, at function
 test_annotation:
-  .functype   test_annotation () -> ()
+  .functype   test_annotation (exnref) -> ()
   .tagtype  __cpp_exception i32
   .tagtype  __c_longjmp i32
   try
@@ -54,8 +54,18 @@ test_annotation:
     return
   end_block
   drop
-  end_function
 
+  i32.const 0
+  loop (i32) -> ()
+    local.get 0
+    loop (exnref) -> ()
+      try_table (catch __cpp_exception 1) (catch_all_ref 0)
+      end_try_table
+      drop
+    end_loop
+    drop
+  end_loop
+  end_function
 
 # CHECK:      test_annotation:
 # CHECK:        try
@@ -105,5 +115,16 @@ test_annotation:
 # CHECK-NEXT:   return
 # CHECK-NEXT:   end_block                               # label7:
 # CHECK-NEXT:   drop
-# CHECK-NEXT:   end_function
 
+# CHECK:        i32.const       0
+# CHECK-NEXT:   loop            (i32) -> ()                     # label12:
+# CHECK-NEXT:   local.get       0
+# CHECK-NEXT:   loop            (exnref) -> ()                  # label13:
+# CHECK-NEXT:   try_table        (catch __cpp_exception 1) (catch_all_ref 0) # 1: up to label12
+# CHECK-NEXT:                                 # 0: up to label13
+# CHECK-NEXT:   end_try_table                           # label14:
+# CHECK-NEXT:   drop
+# CHECK-NEXT:   end_loop
+# CHECK-NEXT:   drop
+# CHECK-NEXT:   end_loop
+# CHECK-NEXT:   end_function
diff --git a/llvm/test/MC/WebAssembly/eh-assembly.s b/llvm/test/MC/WebAssembly/eh-assembly.s
index 38cda10a387a3b..31dfce5a3cde31 100644
--- a/llvm/test/MC/WebAssembly/eh-assembly.s
+++ b/llvm/test/MC/WebAssembly/eh-assembly.s
@@ -7,7 +7,7 @@
   .functype  foo () -> ()
 
 eh_test:
-  .functype  eh_test () -> ()
+  .functype  eh_test (exnref) -> ()
 
   # try_table with all four kinds of catch clauses
   block exnref
@@ -82,6 +82,18 @@ eh_test:
   end_try_table
   drop
   drop
+
+  # try_table targeting loops
+  i32.const 0
+  loop (i32) -> ()
+    local.get 0
+    loop (exnref) -> ()
+      try_table (catch __cpp_exception 1) (catch_all_ref 0)
+      end_try_table
+      drop
+    end_loop
+    drop
+  end_loop
   end_function
 
 eh_legacy_test:
@@ -203,6 +215,17 @@ eh_legacy_test:
 # CHECK-NEXT:    drop
 # CHECK-NEXT:    drop
 
+# CHECK:         i32.const       0
+# CHECK-NEXT:    loop            (i32) -> ()
+# CHECK-NEXT:    local.get       0
+# CHECK-NEXT:    loop            (exnref) -> ()
+# CHECK-NEXT:    try_table        (catch __cpp_exception 1) (catch_all_ref 0)
+# CHECK:         end_try_table
+# CHECK-NEXT:    drop
+# CHECK-NEXT:    end_loop
+# CHECK-NEXT:    drop
+# CHECK-NEXT:    end_loop
+
 # CHECK:       eh_legacy_test:
 # CHECK:         try
 # CHECK-NEXT:    i32.const       3
diff --git a/llvm/test/MC/WebAssembly/type-checker-errors.s b/llvm/test/MC/WebAssembly/type-checker-errors.s
index c1c8209e1dce0c..9aa652348c538e 100644
--- a/llvm/test/MC/WebAssembly/type-checker-errors.s
+++ b/llvm/test/MC/WebAssembly/type-checker-errors.s
@@ -966,4 +966,21 @@ eh_test:
     end_block
   end_block
   drop
+
+  loop
+  i32.const 0
+    loop (i32) -> ()
+      loop (i32) -> ()
+        loop
+# CHECK: :[[@LINE+4]]:11: error: try_table: catch index 0: type mismatch, catch tag type is [i32], but destination's type is []
+# CHECK: :[[@LINE+3]]:11: error: try_table: catch index 1: type mismatch, catch tag type is [i32, exnref], but destination's type is [i32]
+# CHECK: :[[@LINE+2]]:11: error: try_table: catch index 2: type mismatch, catch tag type is [], but destination's type is [i32]
+# CHECK: :[[@LINE+1]]:11: error: try_table: catch index 3: type mismatch, catch tag type is [exnref], but destination's type is []
+          try_table (catch __cpp_exception 0) (catch_ref __cpp_exception 1) (catch_all 2) (catch_all_ref 3)
+          end_try_table
+        end_loop
+        drop
+      end_loop
+    end_loop
+  end_loop
   end_function

>From 0524e120fdd2128e41e90eab628840ff1c0bb27e Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Mon, 7 Oct 2024 20:30:39 +0000
Subject: [PATCH 2/2] clang-format

---
 .../AsmParser/WebAssemblyAsmTypeCheck.cpp     | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
index cc8212d2c9d28d..dbc75eba1b154a 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
@@ -371,7 +371,7 @@ bool WebAssemblyAsmTypeCheck::checkTryTable(SMLoc ErrorLoc,
     if (Level < BlockInfoStack.size()) {
       const auto &DestBlockInfo =
           BlockInfoStack[BlockInfoStack.size() - Level - 1];
-     if (DestBlockInfo.IsLoop) {
+      if (DestBlockInfo.IsLoop) {
         if (compareTypes(SentTypes, DestBlockInfo.Sig.Params)) {
           std::string ErrorMsg =
               ErrorMsgBase + "type mismatch, catch tag type is " +
@@ -379,15 +379,15 @@ bool WebAssemblyAsmTypeCheck::checkTryTable(SMLoc ErrorLoc,
               getTypesString(DestBlockInfo.Sig.Params);
           Error |= typeError(ErrorLoc, ErrorMsg);
         }
-     } else {
-       if (compareTypes(SentTypes, DestBlockInfo.Sig.Returns)) {
-         std::string ErrorMsg =
-             ErrorMsgBase + "type mismatch, catch tag type is " +
-             getTypesString(SentTypes) + ", but destination's type is " +
-             getTypesString(DestBlockInfo.Sig.Returns);
-         Error |= typeError(ErrorLoc, ErrorMsg);
-       }
-     }
+      } else {
+        if (compareTypes(SentTypes, DestBlockInfo.Sig.Returns)) {
+          std::string ErrorMsg =
+              ErrorMsgBase + "type mismatch, catch tag type is " +
+              getTypesString(SentTypes) + ", but destination's type is " +
+              getTypesString(DestBlockInfo.Sig.Returns);
+          Error |= typeError(ErrorLoc, ErrorMsg);
+        }
+      }
     } else {
       Error = typeError(ErrorLoc, ErrorMsgBase + "invalid depth " +
                                       std::to_string(Level));



More information about the llvm-commits mailing list