[llvm] [WebAssembly] Print type signature and table for call_indirect (PR #179120)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 13 23:25:42 PST 2026


https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/179120

>From 1d8dc5fd4dc506a7a34532d1cea363865b45da03 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Mon, 2 Feb 2026 00:26:29 +0900
Subject: [PATCH 01/12] [WebAssembly] Print type signature and table for
 call_indirect

Update WebAssemblyInstPrinter.cpp to correctly print type
and table operands for both register and stack modes.
---
 .../MCTargetDesc/WebAssemblyInstPrinter.cpp   | 18 +++++++++++
 .../WebAssembly/WebAssemblyInstrCall.td       |  4 +--
 llvm/test/CodeGen/WebAssembly/call-pic.ll     |  2 +-
 llvm/test/CodeGen/WebAssembly/call.ll         | 30 +++++++++----------
 .../CodeGen/WebAssembly/function-bitcasts.ll  |  2 +-
 llvm/test/CodeGen/WebAssembly/multivalue.ll   |  2 +-
 llvm/test/CodeGen/WebAssembly/reg-stackify.ll |  2 +-
 llvm/test/CodeGen/WebAssembly/swiftcc.ll      |  8 ++---
 llvm/test/CodeGen/WebAssembly/tailcall.ll     | 28 ++++++++---------
 9 files changed, 57 insertions(+), 39 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 651f631c1ee55..f883c5175a408 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -49,6 +49,24 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &OS) {
   switch (MI->getOpcode()) {
+  case WebAssembly::CALL_INDIRECT:
+  case WebAssembly::RET_CALL_INDIRECT: {
+    OS << "\t" << getMnemonic(*MI).first << "\t";
+    unsigned TypeOperand = 0;
+    unsigned TableOperand = 1;
+    if (MI->getOpcode() == WebAssembly::CALL_INDIRECT) {
+      unsigned NumDefs = MI->getOperand(0).getImm();
+      TypeOperand = 1 + NumDefs;      // Type 위치 보정
+      TableOperand = 1 + NumDefs + 1; // Table 위치 보정
+    }
+    printOperand(MI, TableOperand, OS);
+    OS << ", ";
+    printOperand(MI, TypeOperand, OS);
+    if (MI->getOpcode() == WebAssembly::CALL_INDIRECT) {
+      OS << ", ";
+    }
+    break;
+  }
   case WebAssembly::CALL_INDIRECT_S:
   case WebAssembly::RET_CALL_INDIRECT_S: {
     // A special case for call_indirect (and ret_call_indirect), if the table
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
index ca9a5ef9dda1c..485b12e256224 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
@@ -64,7 +64,7 @@ defm CALL_INDIRECT :
     (outs),
     (ins TypeIndex:$type, table32_op:$table),
     [],
-    "call_indirect", "call_indirect\t$type, $table", 0x11>;
+    "call_indirect\t$type, $table", "call_indirect\t$type, $table", 0x11>;
 
 let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in
 defm RET_CALL :
@@ -77,7 +77,7 @@ let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in
 defm RET_CALL_INDIRECT :
   I<(outs), (ins TypeIndex:$type, table32_op:$table, variable_ops),
     (outs), (ins TypeIndex:$type, table32_op:$table), [],
-    "return_call_indirect\t", "return_call_indirect\t$type, $table",
+    "return_call_indirect\t$type, $table", "return_call_indirect\t$type, $table",
     0x13>,
   Requires<[HasTailCall]>;
 
diff --git a/llvm/test/CodeGen/WebAssembly/call-pic.ll b/llvm/test/CodeGen/WebAssembly/call-pic.ll
index f6f24bdd0530c..53943246a8f92 100644
--- a/llvm/test/CodeGen/WebAssembly/call-pic.ll
+++ b/llvm/test/CodeGen/WebAssembly/call-pic.ll
@@ -19,7 +19,7 @@ define void @call_indirect_func() {
 ; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, indirect_func at MBREL{{$}}
 ; CHECK-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
 ; CHECK-NEXT: i32.load $push[[L3:[0-9]+]]=, 0($pop[[L2]]){{$}}
-; CHECK-NEXT: call_indirect $push[[L4:[0-9]+]]=, $pop[[L3]]{{$}}
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (i32), $push[[L4:[0-9]+]]=, $pop[[L3]]{{$}}
   %1 = load ptr, ptr @indirect_func, align 4
   %call = call i32 %1()
   ret void
diff --git a/llvm/test/CodeGen/WebAssembly/call.ll b/llvm/test/CodeGen/WebAssembly/call.ll
index 2f7658ac5a6cc..2a1ad944ba6e0 100644
--- a/llvm/test/CodeGen/WebAssembly/call.ll
+++ b/llvm/test/CodeGen/WebAssembly/call.ll
@@ -94,7 +94,7 @@ define i32 @call_i32_binary(i32 %a, i32 %b) {
 ; CHECK-LABEL: call_indirect_void:
 ; CHECK-NEXT: .functype call_indirect_void (i32) -> (){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $pop[[L0]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, () -> (), $pop[[L0]]{{$}}
 ; CHECK-NEXT: return{{$}}
 define void @call_indirect_void(ptr %callee) {
   call void %callee()
@@ -104,7 +104,7 @@ define void @call_indirect_void(ptr %callee) {
 ; CHECK-LABEL: call_indirect_i32:
 ; CHECK-NEXT: .functype call_indirect_i32 (i32) -> (i32){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (i32), $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
 define i32 @call_indirect_i32(ptr %callee) {
   %t = call i32 %callee()
@@ -114,7 +114,7 @@ define i32 @call_indirect_i32(ptr %callee) {
 ; CHECK-LABEL: call_indirect_i64:
 ; CHECK-NEXT: .functype call_indirect_i64 (i32) -> (i64){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, () -> (i64), $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
 define i64 @call_indirect_i64(ptr %callee) {
   %t = call i64 %callee()
@@ -124,7 +124,7 @@ define i64 @call_indirect_i64(ptr %callee) {
 ; CHECK-LABEL: call_indirect_float:
 ; CHECK-NEXT: .functype call_indirect_float (i32) -> (f32){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, () -> (f32), $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
 define float @call_indirect_float(ptr %callee) {
   %t = call float %callee()
@@ -134,7 +134,7 @@ define float @call_indirect_float(ptr %callee) {
 ; CHECK-LABEL: call_indirect_double:
 ; CHECK-NEXT: .functype call_indirect_double (i32) -> (f64){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, () -> (f64), $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
 define double @call_indirect_double(ptr %callee) {
   %t = call double %callee()
@@ -144,7 +144,7 @@ define double @call_indirect_double(ptr %callee) {
 ; CHECK-LABEL: call_indirect_v128:
 ; CHECK-NEXT: .functype call_indirect_v128 (i32) -> (v128){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, () -> (v128), $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
 define <16 x i8> @call_indirect_v128(ptr %callee) {
   %t = call <16 x i8> %callee()
@@ -155,7 +155,7 @@ define <16 x i8> @call_indirect_v128(ptr %callee) {
 ; CHECK-NEXT: .functype call_indirect_arg (i32, i32) -> (){{$}}
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 1{{$}}
 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $pop[[L0]], $pop[[L1]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, (i32) -> (), $pop[[L0]], $pop[[L1]]{{$}}
 ; CHECK-NEXT: return{{$}}
 define void @call_indirect_arg(ptr %callee, i32 %arg) {
   call void %callee(i32 %arg)
@@ -167,7 +167,7 @@ define void @call_indirect_arg(ptr %callee, i32 %arg) {
 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 1{{$}}
 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 2{{$}}
 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: {{^}} call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]], $pop[[L2]]{{$}}
+; CHECK-NEXT: {{^}} call_indirect __indirect_function_table, (i32, i32) -> (i32), $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]], $pop[[L2]]{{$}}
 ; CHECK-NEXT: drop $pop[[NUM]]{{$}}
 ; CHECK-NEXT: return{{$}}
 define void @call_indirect_arg_2(ptr %callee, i32 %arg, i32 %arg2) {
@@ -219,7 +219,7 @@ define void @coldcc_tail_call_void_nullary() {
 ; CHECK-NEXT: i32.const	$push[[L3:[0-9]+]]=, void_nullary{{$}}
 ; CHECK-NEXT: i32.const	$push[[L2:[0-9]+]]=, other_void_nullary{{$}}
 ; CHECK-NEXT: i32.add 	$push[[L4:[0-9]+]]=, $pop[[L3]], $pop[[L2]]{{$}}
-; CHECK-NEXT: call_indirect	$pop[[L4]]{{$}}
+; CHECK-NEXT: call_indirect	__indirect_function_table, () -> (), $pop[[L4]]{{$}}
 ; CHECK-NEXT: call void_nullary{{$}}
 ; CHECK-NEXT: return{{$}}
 declare void @vararg_func(...)
@@ -243,7 +243,7 @@ bb2:
 ; CHECK-NEXT: local.get  $push{{.*}}=, [[L0]]
 ; CHECK-NEXT: i32.const  $push{{.*}}=, 12
 ; CHECK-NEXT: i32.add
-; CHECK-NEXT: call_indirect  $pop{{.*}}
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (), $pop{{.*}}
 define void @call_indirect_alloca() {
 entry:
   %ptr = alloca i32, align 4
@@ -254,9 +254,9 @@ entry:
 ; Calling non-functional globals should be lowered to call_indirects.
 ; CHECK-LABEL: call_indirect_int:
 ; CHECK:      i32.const  $push[[L0:[0-9]+]]=, global_i8
-; CHECK-NEXT: call_indirect  $pop[[L0]]
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (), $pop[[L0]]
 ; CHECK-NEXT: i32.const  $push[[L1:[0-9]+]]=, global_i32
-; CHECK-NEXT: call_indirect  $pop[[L1]]
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (), $pop[[L1]]
 @global_i8 = global i8 0
 @global_i32 = global i32 0
 define void @call_indirect_int() {
@@ -268,9 +268,9 @@ define void @call_indirect_int() {
 ; Calling aliases of non-functional globals should be lowered to call_indirects.
 ; CHECK-LABEL: call_indirect_int_alias:
 ; CHECK:      i32.const  $push[[L0:[0-9]+]]=, global_i8_alias
-; CHECK-NEXT: call_indirect  $pop[[L0]]
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (), $pop[[L0]]
 ; CHECK-NEXT: i32.const  $push[[L1:[0-9]+]]=, global_i32_alias
-; CHECK-NEXT: call_indirect  $pop[[L1]]
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (), $pop[[L1]]
 @global_i8_alias = alias i8, ptr @global_i8
 @global_i32_alias = alias i32, ptr @global_i32
 define void @call_indirect_int_alias() {
@@ -284,7 +284,7 @@ define void @call_indirect_int_alias() {
 ; CHECK-LABEL: call_func_alias:
 ; SLOW:      call  func_alias
 ; FAST:      i32.const  $push[[L0:[0-9]+]]=, func_alias
-; FAST-NEXT: call_indirect  $pop[[L0]]
+; FAST-NEXT: call_indirect __indirect_function_table, () -> (), $pop[[L0]]
 @func_alias = alias void (), ptr @call_void_nullary
 define void @call_func_alias() {
   call void @func_alias()
diff --git a/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll b/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll
index 0553f61ef9056..c623e7287c034 100644
--- a/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll
+++ b/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll
@@ -121,7 +121,7 @@ define void @test_store() {
 ; CHECK-NEXT: .functype test_load () -> (i32){{$}}
 ; CHECK-NEXT: i32.const   $push[[L0:[0-9]+]]=, 0{{$}}
 ; CHECK-NEXT: i32.load    $push[[L1:[0-9]+]]=, global_func($pop[[L0]]){{$}}
-; CHECK-NEXT: call_indirect $push{{[0-9]+}}=, $pop[[L1]]{{$}}
+; CHECK-NEXT: call_indirect __indirect_function_table, () -> (i32), $push{{[0-9]+}}=, $pop[[L1]]{{$}}
 define i32 @test_load() {
   %1 = load ptr, ptr @global_func
   %2 = call i32 %1()
diff --git a/llvm/test/CodeGen/WebAssembly/multivalue.ll b/llvm/test/CodeGen/WebAssembly/multivalue.ll
index 5001db7e57a1e..2fa6381e4c4c7 100644
--- a/llvm/test/CodeGen/WebAssembly/multivalue.ll
+++ b/llvm/test/CodeGen/WebAssembly/multivalue.ll
@@ -62,7 +62,7 @@ define %pair @pair_call_return() {
 ; CHECK-NEXT: call_indirect () -> (i32, i64){{$}}
 ; REF:        call_indirect __indirect_function_table, () -> (i32, i64){{$}}
 ; CHECK-NEXT: end_function{{$}}
-; REGS: call_indirect $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
+; REGS: call_indirect 0, () -> (i32, i64), $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
 define %pair @pair_call_indirect(ptr %f) {
   %p = call %pair %f()
   ret %pair %p
diff --git a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
index f1466a48e7394..f9c233d1be3a3 100644
--- a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
@@ -643,7 +643,7 @@ define i32 @stackpointer_dependency(ptr readnone) {
 ; CHECK-NEXT: local.tee $push[[L3:.+]]=, $0=, $pop[[L4]]
 ; CHECK-NEXT: i32.load  $push[[L0:.+]]=, 0($0)
 ; CHECK-NEXT: i32.load  $push[[L1:.+]]=, 0($pop[[L0]])
-; CHECK-NEXT: call_indirect $push{{.+}}=, $pop[[L3]], $1, $pop[[L1]]
+; CHECK-NEXT: call_indirect __indirect_function_table, (i32, i32) -> (i32), $push{{.+}}=, $pop[[L3]], $1, $pop[[L1]]
 ; NOREGS-LABEL: call_indirect_stackify:
 ; NOREGS: i32.load  0
 ; NOREGS-NEXT: local.tee 0
diff --git a/llvm/test/CodeGen/WebAssembly/swiftcc.ll b/llvm/test/CodeGen/WebAssembly/swiftcc.ll
index 0c5c3d8bbb0ff..b6cc6fb441ee0 100644
--- a/llvm/test/CodeGen/WebAssembly/swiftcc.ll
+++ b/llvm/test/CodeGen/WebAssembly/swiftcc.ll
@@ -18,21 +18,21 @@ define swiftcc void @bar() {
 ; REG: call    foo, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
   call swiftcc void @foo(i32 1, i32 2)
 
-; REG: call_indirect   $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
+; REG: call_indirect  __indirect_function_table, (i32, i32, i32, i32) -> (), $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
 ; CHECK: call_indirect __indirect_function_table, (i32, i32, i32, i32) -> ()
   call swiftcc void %1(i32 1, i32 2)
 
-; REG: call_indirect   $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
+; REG: call_indirect  __indirect_function_table, (i32, i32, i32, i32) -> (), $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
 ; CHECK: call_indirect __indirect_function_table, (i32, i32, i32, i32) -> ()
   call swiftcc void %1(i32 1, i32 2, i32 swiftself 3)
 
   %err = alloca swifterror ptr, align 4
 
-; REG: call_indirect   $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
+; REG: call_indirect  __indirect_function_table, (i32, i32, i32, i32) -> (), $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
 ; CHECK: call_indirect __indirect_function_table, (i32, i32, i32, i32) -> ()
   call swiftcc void %1(i32 1, i32 2, ptr swifterror %err)
 
-; REG: call_indirect   $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
+; REG: call_indirect  __indirect_function_table, (i32, i32, i32, i32) -> (), $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
 ; CHECK: call_indirect __indirect_function_table, (i32, i32, i32, i32) -> ()
   call swiftcc void %1(i32 1, i32 2, i32 swiftself 3, ptr swifterror %err)
 
diff --git a/llvm/test/CodeGen/WebAssembly/tailcall.ll b/llvm/test/CodeGen/WebAssembly/tailcall.ll
index 84bd142462e37..e05b65f51a073 100644
--- a/llvm/test/CodeGen/WebAssembly/tailcall.ll
+++ b/llvm/test/CodeGen/WebAssembly/tailcall.ll
@@ -82,7 +82,7 @@ define i32 @indirect_notail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_notail:
 ; CHECK:         .functype indirect_notail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect $push0=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect 0, (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
 ; CHECK-NEXT:    return $pop0
   %p = extractvalue %fn %f, 0
   %v = notail call i32 %p(%fn %f, i32 %x, i32 %y)
@@ -93,7 +93,7 @@ define i32 @indirect_musttail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_musttail:
 ; CHECK:         .functype indirect_musttail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    return_call_indirect , $0, $1, $2, $0
+; CHECK-NEXT:    return_call_indirect 0, (i32, i32, i32) -> (i32), $0, $1, $2, $0
   %p = extractvalue %fn %f, 0
   %v = musttail call i32 %p(%fn %f, i32 %x, i32 %y)
   ret i32 %v
@@ -103,7 +103,7 @@ define i32 @indirect_tail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_tail:
 ; CHECK:         .functype indirect_tail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    return_call_indirect , $0, $1, $2, $0
+; CHECK-NEXT:    return_call_indirect 0, (i32, i32, i32) -> (i32), $0, $1, $2, $0
   %p = extractvalue %fn %f, 0
   %v = tail call i32 %p(%fn %f, i32 %x, i32 %y)
   ret i32 %v
@@ -118,7 +118,7 @@ define i1 @choice_notail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    call_indirect $push5=, $0, $pop4 # Invalid depth argument!
+; SLOW-NEXT:    call_indirect 0, (i32) -> (i32), $push5=, $0, $pop4 # Invalid depth argument!
 ; SLOW-NEXT:    return $pop5
 ;
 ; FAST-LABEL: choice_notail:
@@ -129,7 +129,7 @@ define i1 @choice_notail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push5=, $pop3, $pop4, $pop2
-; FAST-NEXT:    call_indirect $push0=, $0, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect 0, (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
 ; FAST-NEXT:    return $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = notail call i1 %p(i1 %x)
@@ -145,7 +145,7 @@ define i1 @choice_musttail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    return_call_indirect , $0, $pop4
+; SLOW-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $pop4
 ;
 ; FAST-LABEL: choice_musttail:
 ; FAST:         .functype choice_musttail (i32) -> (i32)
@@ -155,7 +155,7 @@ define i1 @choice_musttail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push0=, $pop4, $pop3, $pop2
-; FAST-NEXT:    return_call_indirect , $0, $pop0
+; FAST-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = musttail call i1 %p(i1 %x)
   ret i1 %v
@@ -170,7 +170,7 @@ define i1 @choice_tail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    return_call_indirect , $0, $pop4
+; SLOW-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $pop4
 ;
 ; FAST-LABEL: choice_tail:
 ; FAST:         .functype choice_tail (i32) -> (i32)
@@ -180,7 +180,7 @@ define i1 @choice_tail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push5=, $pop3, $pop4, $pop2
-; FAST-NEXT:    call_indirect $push0=, $0, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect  0, (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
 ; FAST-NEXT:    return $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = tail call i1 %p(i1 %x)
@@ -264,7 +264,7 @@ define void @mismatched_indirect_void(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: mismatched_indirect_void:
 ; CHECK:         .functype mismatched_indirect_void (i32, i32, i32) -> ()
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect $drop=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect 0, (i32, i32, i32) -> (i32), $drop=, $0, $1, $2, $0 # Invalid depth argument!
 ; CHECK-NEXT:    return
   %p = extractvalue %fn %f, 0
   %v = tail call i32 %p(%fn %f, i32 %x, i32 %y)
@@ -275,7 +275,7 @@ define float @mismatched_indirect_f32(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: mismatched_indirect_f32:
 ; CHECK:         .functype mismatched_indirect_f32 (i32, i32, i32) -> (f32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect $push0=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect 0, (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
 ; CHECK-NEXT:    f32.reinterpret_i32 $push1=, $pop0
 ; CHECK-NEXT:    return $pop1
   %p = extractvalue %fn %f, 0
@@ -538,7 +538,7 @@ define i32 @indirect_epilogue(ptr %p) {
 ; CHECK-NEXT:    i32.const $push2=, 256
 ; CHECK-NEXT:    i32.add $push3=, $1, $pop2
 ; CHECK-NEXT:    global.set __stack_pointer, $pop3
-; CHECK-NEXT:    return_call_indirect , $0, $0
+; CHECK-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $0
   %a = alloca [64 x i32]
   %v = musttail call i32 %p(ptr %p)
   ret i32 %v
@@ -564,7 +564,7 @@ define i32 @unique_caller(ptr %p) {
 ; SLOW-NEXT:    i64.const $push2=, 0
 ; SLOW-NEXT:    f64.const $push1=, 0x0p0
 ; SLOW-NEXT:    i32.load $push0=, 0($0)
-; SLOW-NEXT:    return_call_indirect , $pop4, $pop3, $pop2, $pop1, $pop0
+; SLOW-NEXT:    return_call_indirect  0, (i32, f32, i64, f64) -> (i32), $pop4, $pop3, $pop2, $pop1, $pop0
 ;
 ; FAST-LABEL: unique_caller:
 ; FAST:         .functype unique_caller (i32) -> (i32)
@@ -576,7 +576,7 @@ define i32 @unique_caller(ptr %p) {
 ; FAST-NEXT:    i32.const $push6=, 0
 ; FAST-NEXT:    f64.convert_i32_s $push4=, $pop6
 ; FAST-NEXT:    i32.load $push5=, 0($0)
-; FAST-NEXT:    call_indirect $push0=, $pop1, $pop2, $pop3, $pop4, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect 0, (i32, f32, i64, f64) -> (i32), $push0=, $pop1, $pop2, $pop3, $pop4, $pop5 # Invalid depth argument!
 ; FAST-NEXT:    return $pop0
   %f = load ptr, ptr %p
   %v = tail call i32 %f(i32 0, float 0., i64 0, double 0.)

>From 89caa96f44330967025b24b944722bee327b2822 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Mon, 9 Feb 2026 00:43:33 +0900
Subject: [PATCH 02/12] consolidate handling indirect  for register and stack

---
 .../MCTargetDesc/WebAssemblyInstPrinter.cpp   | 34 ++++++-------------
 llvm/test/CodeGen/WebAssembly/multivalue.ll   |  2 +-
 llvm/test/CodeGen/WebAssembly/tailcall.ll     | 28 +++++++--------
 3 files changed, 26 insertions(+), 38 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index f883c5175a408..c59291b270ab9 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -48,25 +48,17 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                                        StringRef Annot,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &OS) {
+
+  unsigned TypeOperand = 0;
+  unsigned TableOperand = 1;
   switch (MI->getOpcode()) {
-  case WebAssembly::CALL_INDIRECT:
-  case WebAssembly::RET_CALL_INDIRECT: {
-    OS << "\t" << getMnemonic(*MI).first << "\t";
-    unsigned TypeOperand = 0;
-    unsigned TableOperand = 1;
-    if (MI->getOpcode() == WebAssembly::CALL_INDIRECT) {
-      unsigned NumDefs = MI->getOperand(0).getImm();
-      TypeOperand = 1 + NumDefs;      // Type 위치 보정
-      TableOperand = 1 + NumDefs + 1; // Table 위치 보정
-    }
-    printOperand(MI, TableOperand, OS);
-    OS << ", ";
-    printOperand(MI, TypeOperand, OS);
-    if (MI->getOpcode() == WebAssembly::CALL_INDIRECT) {
-      OS << ", ";
-    }
-    break;
+  case WebAssembly::CALL_INDIRECT: {
+    unsigned NumDefs = MI->getOperand(0).getImm();
+    TypeOperand = NumDefs + 1;
+    TableOperand = NumDefs + 2;
+    [[fallthrough]];
   }
+  case WebAssembly::RET_CALL_INDIRECT:
   case WebAssembly::CALL_INDIRECT_S:
   case WebAssembly::RET_CALL_INDIRECT_S: {
     // A special case for call_indirect (and ret_call_indirect), if the table
@@ -77,17 +69,13 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
     OS << "\t";
     OS << getMnemonic(*MI).first;
     OS << " ";
-
-    assert(MI->getNumOperands() == 2);
-    const unsigned TypeOperand = 0;
-    const unsigned TableOperand = 1;
     if (MI->getOperand(TableOperand).isExpr()) {
       printOperand(MI, TableOperand, OS);
       OS << ", ";
-    } else {
-      assert(MI->getOperand(TableOperand).getImm() == 0);
     }
     printOperand(MI, TypeOperand, OS);
+    if (MI->getOpcode() == WebAssembly::CALL_INDIRECT)
+      OS << ", ";
     break;
   }
   default:
diff --git a/llvm/test/CodeGen/WebAssembly/multivalue.ll b/llvm/test/CodeGen/WebAssembly/multivalue.ll
index 2fa6381e4c4c7..537adff3f3405 100644
--- a/llvm/test/CodeGen/WebAssembly/multivalue.ll
+++ b/llvm/test/CodeGen/WebAssembly/multivalue.ll
@@ -62,7 +62,7 @@ define %pair @pair_call_return() {
 ; CHECK-NEXT: call_indirect () -> (i32, i64){{$}}
 ; REF:        call_indirect __indirect_function_table, () -> (i32, i64){{$}}
 ; CHECK-NEXT: end_function{{$}}
-; REGS: call_indirect 0, () -> (i32, i64), $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
+; REGS: call_indirect () -> (i32, i64), $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
 define %pair @pair_call_indirect(ptr %f) {
   %p = call %pair %f()
   ret %pair %p
diff --git a/llvm/test/CodeGen/WebAssembly/tailcall.ll b/llvm/test/CodeGen/WebAssembly/tailcall.ll
index e05b65f51a073..8900fe9cff24b 100644
--- a/llvm/test/CodeGen/WebAssembly/tailcall.ll
+++ b/llvm/test/CodeGen/WebAssembly/tailcall.ll
@@ -82,7 +82,7 @@ define i32 @indirect_notail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_notail:
 ; CHECK:         .functype indirect_notail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect 0, (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
 ; CHECK-NEXT:    return $pop0
   %p = extractvalue %fn %f, 0
   %v = notail call i32 %p(%fn %f, i32 %x, i32 %y)
@@ -93,7 +93,7 @@ define i32 @indirect_musttail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_musttail:
 ; CHECK:         .functype indirect_musttail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    return_call_indirect 0, (i32, i32, i32) -> (i32), $0, $1, $2, $0
+; CHECK-NEXT:    return_call_indirect (i32, i32, i32) -> (i32), $0, $1, $2, $0
   %p = extractvalue %fn %f, 0
   %v = musttail call i32 %p(%fn %f, i32 %x, i32 %y)
   ret i32 %v
@@ -103,7 +103,7 @@ define i32 @indirect_tail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_tail:
 ; CHECK:         .functype indirect_tail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    return_call_indirect 0, (i32, i32, i32) -> (i32), $0, $1, $2, $0
+; CHECK-NEXT:    return_call_indirect (i32, i32, i32) -> (i32), $0, $1, $2, $0
   %p = extractvalue %fn %f, 0
   %v = tail call i32 %p(%fn %f, i32 %x, i32 %y)
   ret i32 %v
@@ -118,7 +118,7 @@ define i1 @choice_notail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    call_indirect 0, (i32) -> (i32), $push5=, $0, $pop4 # Invalid depth argument!
+; SLOW-NEXT:    call_indirect (i32) -> (i32), $push5=, $0, $pop4 # Invalid depth argument!
 ; SLOW-NEXT:    return $pop5
 ;
 ; FAST-LABEL: choice_notail:
@@ -129,7 +129,7 @@ define i1 @choice_notail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push5=, $pop3, $pop4, $pop2
-; FAST-NEXT:    call_indirect 0, (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
 ; FAST-NEXT:    return $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = notail call i1 %p(i1 %x)
@@ -145,7 +145,7 @@ define i1 @choice_musttail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $pop4
+; SLOW-NEXT:    return_call_indirect (i32) -> (i32), $0, $pop4
 ;
 ; FAST-LABEL: choice_musttail:
 ; FAST:         .functype choice_musttail (i32) -> (i32)
@@ -155,7 +155,7 @@ define i1 @choice_musttail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push0=, $pop4, $pop3, $pop2
-; FAST-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $pop0
+; FAST-NEXT:    return_call_indirect (i32) -> (i32), $0, $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = musttail call i1 %p(i1 %x)
   ret i1 %v
@@ -170,7 +170,7 @@ define i1 @choice_tail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $pop4
+; SLOW-NEXT:    return_call_indirect (i32) -> (i32), $0, $pop4
 ;
 ; FAST-LABEL: choice_tail:
 ; FAST:         .functype choice_tail (i32) -> (i32)
@@ -180,7 +180,7 @@ define i1 @choice_tail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push5=, $pop3, $pop4, $pop2
-; FAST-NEXT:    call_indirect  0, (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
 ; FAST-NEXT:    return $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = tail call i1 %p(i1 %x)
@@ -264,7 +264,7 @@ define void @mismatched_indirect_void(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: mismatched_indirect_void:
 ; CHECK:         .functype mismatched_indirect_void (i32, i32, i32) -> ()
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect 0, (i32, i32, i32) -> (i32), $drop=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect (i32, i32, i32) -> (i32), $drop=, $0, $1, $2, $0 # Invalid depth argument!
 ; CHECK-NEXT:    return
   %p = extractvalue %fn %f, 0
   %v = tail call i32 %p(%fn %f, i32 %x, i32 %y)
@@ -275,7 +275,7 @@ define float @mismatched_indirect_f32(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: mismatched_indirect_f32:
 ; CHECK:         .functype mismatched_indirect_f32 (i32, i32, i32) -> (f32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect 0, (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
 ; CHECK-NEXT:    f32.reinterpret_i32 $push1=, $pop0
 ; CHECK-NEXT:    return $pop1
   %p = extractvalue %fn %f, 0
@@ -538,7 +538,7 @@ define i32 @indirect_epilogue(ptr %p) {
 ; CHECK-NEXT:    i32.const $push2=, 256
 ; CHECK-NEXT:    i32.add $push3=, $1, $pop2
 ; CHECK-NEXT:    global.set __stack_pointer, $pop3
-; CHECK-NEXT:    return_call_indirect 0, (i32) -> (i32), $0, $0
+; CHECK-NEXT:    return_call_indirect (i32) -> (i32), $0, $0
   %a = alloca [64 x i32]
   %v = musttail call i32 %p(ptr %p)
   ret i32 %v
@@ -564,7 +564,7 @@ define i32 @unique_caller(ptr %p) {
 ; SLOW-NEXT:    i64.const $push2=, 0
 ; SLOW-NEXT:    f64.const $push1=, 0x0p0
 ; SLOW-NEXT:    i32.load $push0=, 0($0)
-; SLOW-NEXT:    return_call_indirect  0, (i32, f32, i64, f64) -> (i32), $pop4, $pop3, $pop2, $pop1, $pop0
+; SLOW-NEXT:    return_call_indirect (i32, f32, i64, f64) -> (i32), $pop4, $pop3, $pop2, $pop1, $pop0
 ;
 ; FAST-LABEL: unique_caller:
 ; FAST:         .functype unique_caller (i32) -> (i32)
@@ -576,7 +576,7 @@ define i32 @unique_caller(ptr %p) {
 ; FAST-NEXT:    i32.const $push6=, 0
 ; FAST-NEXT:    f64.convert_i32_s $push4=, $pop6
 ; FAST-NEXT:    i32.load $push5=, 0($0)
-; FAST-NEXT:    call_indirect 0, (i32, f32, i64, f64) -> (i32), $push0=, $pop1, $pop2, $pop3, $pop4, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect (i32, f32, i64, f64) -> (i32), $push0=, $pop1, $pop2, $pop3, $pop4, $pop5 # Invalid depth argument!
 ; FAST-NEXT:    return $pop0
   %f = load ptr, ptr %p
   %v = tail call i32 %f(i32 0, float 0., i64 0, double 0.)

>From 3ee0a2faea96dd9d019c5942edda6db0d420e3b8 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 12 Feb 2026 18:27:10 +0900
Subject: [PATCH 03/12] add test return-call-indirect

---
 .../WebAssembly/return-call-indirect.ll       | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 llvm/test/CodeGen/WebAssembly/return-call-indirect.ll

diff --git a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
new file mode 100644
index 0000000000000..e8375aaedd752
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
@@ -0,0 +1,29 @@
+; RUN: llc < %s -asm-verbose=false -mattr=-reference-types,+tail-call -O2 | FileCheck --check-prefixes=CHECK,NOREF %s
+; RUN: llc < %s -asm-verbose=false -mattr=+reference-types,+tail-call -O2 | FileCheck --check-prefixes=CHECK,REF %s
+; RUN: llc < %s -asm-verbose=false -mattr=+tail-call -O2 --filetype=obj | obj2yaml | FileCheck --check-prefix=OBJ %s
+
+; Test that compilation units with call_indirect but without any
+; function pointer declarations still get a table.
+
+target triple = "wasm32-unknown-unknown"
+
+; CHECK-LABEL: return_call_indirect:
+; CHECK-NEXT: .functype return_call_indirect (i32) -> (i32)
+; CHECK-NEXT: local.get 0
+; REF:       return_call_indirect     __indirect_function_table, () -> (i32)
+; NOREF:     return_call_indirect     __indirect_function_table, () -> (i32)
+; CHECK-NEXT: end_function
+define i32 @return_call_indirect(ptr %callee) {
+  %r = tail call i32 %callee()
+  ret i32 %r
+}
+
+; OBJ:    Imports:
+; OBJ-NEXT:      - Module:          env
+; OBJ-NEXT:        Field:           __linear_memory
+; OBJ-NEXT:        Kind:            MEMORY
+; OBJ-NEXT:        Memory:
+; OBJ-NEXT:          Minimum:         0x0
+; OBJ-NEXT:      - Module:          env
+; OBJ-NEXT:        Field:           __indirect_function_table
+; OBJ-NEXT:        Kind:            TABLE

>From 152693d307d659a9c32441f51e3f21f0ea612abc Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 13 Feb 2026 01:43:55 +0900
Subject: [PATCH 04/12] remove blank line

---
 .../Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index c59291b270ab9..660dab93d18c9 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -48,7 +48,6 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                                        StringRef Annot,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &OS) {
-
   unsigned TypeOperand = 0;
   unsigned TableOperand = 1;
   switch (MI->getOpcode()) {

>From 06bdd8658540f99735f6961040999446c75d1707 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 13 Feb 2026 01:48:41 +0900
Subject: [PATCH 05/12] Fix conflict between printer and parser

When processing the `call_indirect` and `return_call_indirect`
instructions, WebAssemblyAsmParser only parsed the symbol table
when the `+reference-type` feature was present. However,
WebAssemblyInstPrinter always printed the symbol table, creating
a discrepancy. To resolve this, WebAssemblyInstPrinter has been
modified to print the symbol table only when the `+reference-type`
feature is present.
---
 .../Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp | 3 ++-
 llvm/test/CodeGen/WebAssembly/return-call-indirect.ll          | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 660dab93d18c9..963a2783aeba9 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -68,7 +68,8 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
     OS << "\t";
     OS << getMnemonic(*MI).first;
     OS << " ";
-    if (MI->getOperand(TableOperand).isExpr()) {
+    if (MI->getOperand(TableOperand).isExpr() &&
+        STI.checkFeatures("+reference-types")) {
       printOperand(MI, TableOperand, OS);
       OS << ", ";
     }
diff --git a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
index e8375aaedd752..0b4f4882ebcf2 100644
--- a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
+++ b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
@@ -11,7 +11,7 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT: .functype return_call_indirect (i32) -> (i32)
 ; CHECK-NEXT: local.get 0
 ; REF:       return_call_indirect     __indirect_function_table, () -> (i32)
-; NOREF:     return_call_indirect     __indirect_function_table, () -> (i32)
+; NOREF:     return_call_indirect     () -> (i32)
 ; CHECK-NEXT: end_function
 define i32 @return_call_indirect(ptr %callee) {
   %r = tail call i32 %callee()

>From 8ce1f2d3afe988a37af1c62936acb3db5c700eb6 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 13 Feb 2026 12:59:30 +0900
Subject: [PATCH 06/12] update testcases of tailcall.ll

---
 llvm/test/CodeGen/WebAssembly/tailcall.ll | 43 +++++++++++------------
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/llvm/test/CodeGen/WebAssembly/tailcall.ll b/llvm/test/CodeGen/WebAssembly/tailcall.ll
index 8900fe9cff24b..7f6a3ebc2351d 100644
--- a/llvm/test/CodeGen/WebAssembly/tailcall.ll
+++ b/llvm/test/CodeGen/WebAssembly/tailcall.ll
@@ -1,12 +1,10 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc < %s -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mcpu=mvp -mattr=+tail-call | FileCheck --check-prefixes=CHECK,SLOW %s
-; RUN: llc < %s -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel -mcpu=mvp -mattr=+tail-call | FileCheck --check-prefixes=CHECK,FAST %s
-; RUN: llc < %s --filetype=obj -mattr=+tail-call | obj2yaml | FileCheck --check-prefix=YAML %s
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+tail-call | FileCheck --check-prefixes=CHECK,SLOW %s
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel -mattr=+tail-call | FileCheck --check-prefixes=CHECK,FAST %s
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown --filetype=obj -mattr=+tail-call | obj2yaml | FileCheck --check-prefix=YAML %s
 
 ; Test that the tail calls lower correctly
 
-target triple = "wasm32-unknown-unknown"
-
 %fn = type <{ptr}>
 declare i1 @foo(i1)
 declare i1 @bar(i1)
@@ -82,7 +80,7 @@ define i32 @indirect_notail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_notail:
 ; CHECK:         .functype indirect_notail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect __indirect_function_table, (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0
 ; CHECK-NEXT:    return $pop0
   %p = extractvalue %fn %f, 0
   %v = notail call i32 %p(%fn %f, i32 %x, i32 %y)
@@ -93,7 +91,7 @@ define i32 @indirect_musttail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_musttail:
 ; CHECK:         .functype indirect_musttail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    return_call_indirect (i32, i32, i32) -> (i32), $0, $1, $2, $0
+; CHECK-NEXT:    return_call_indirect __indirect_function_table, (i32, i32, i32) -> (i32), $0, $1, $2, $0
   %p = extractvalue %fn %f, 0
   %v = musttail call i32 %p(%fn %f, i32 %x, i32 %y)
   ret i32 %v
@@ -103,7 +101,7 @@ define i32 @indirect_tail(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: indirect_tail:
 ; CHECK:         .functype indirect_tail (i32, i32, i32) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    return_call_indirect (i32, i32, i32) -> (i32), $0, $1, $2, $0
+; CHECK-NEXT:    return_call_indirect __indirect_function_table, (i32, i32, i32) -> (i32), $0, $1, $2, $0
   %p = extractvalue %fn %f, 0
   %v = tail call i32 %p(%fn %f, i32 %x, i32 %y)
   ret i32 %v
@@ -118,7 +116,7 @@ define i1 @choice_notail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    call_indirect (i32) -> (i32), $push5=, $0, $pop4 # Invalid depth argument!
+; SLOW-NEXT:    call_indirect __indirect_function_table, (i32) -> (i32), $push5=, $0, $pop4
 ; SLOW-NEXT:    return $pop5
 ;
 ; FAST-LABEL: choice_notail:
@@ -129,7 +127,7 @@ define i1 @choice_notail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push5=, $pop3, $pop4, $pop2
-; FAST-NEXT:    call_indirect (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect __indirect_function_table, (i32) -> (i32), $push0=, $0, $pop5
 ; FAST-NEXT:    return $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = notail call i1 %p(i1 %x)
@@ -145,7 +143,7 @@ define i1 @choice_musttail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    return_call_indirect (i32) -> (i32), $0, $pop4
+; SLOW-NEXT:    return_call_indirect __indirect_function_table, (i32) -> (i32), $0, $pop4
 ;
 ; FAST-LABEL: choice_musttail:
 ; FAST:         .functype choice_musttail (i32) -> (i32)
@@ -155,7 +153,7 @@ define i1 @choice_musttail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push0=, $pop4, $pop3, $pop2
-; FAST-NEXT:    return_call_indirect (i32) -> (i32), $0, $pop0
+; FAST-NEXT:    return_call_indirect __indirect_function_table, (i32) -> (i32), $0, $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = musttail call i1 %p(i1 %x)
   ret i1 %v
@@ -170,7 +168,7 @@ define i1 @choice_tail(i1 %x) {
 ; SLOW-NEXT:    i32.const $push0=, 1
 ; SLOW-NEXT:    i32.and $push1=, $0, $pop0
 ; SLOW-NEXT:    i32.select $push4=, $pop3, $pop2, $pop1
-; SLOW-NEXT:    return_call_indirect (i32) -> (i32), $0, $pop4
+; SLOW-NEXT:    return_call_indirect __indirect_function_table, (i32) -> (i32), $0, $pop4
 ;
 ; FAST-LABEL: choice_tail:
 ; FAST:         .functype choice_tail (i32) -> (i32)
@@ -180,7 +178,7 @@ define i1 @choice_tail(i1 %x) {
 ; FAST-NEXT:    i32.const $push1=, 1
 ; FAST-NEXT:    i32.and $push2=, $0, $pop1
 ; FAST-NEXT:    i32.select $push5=, $pop3, $pop4, $pop2
-; FAST-NEXT:    call_indirect (i32) -> (i32), $push0=, $0, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect __indirect_function_table, (i32) -> (i32), $push0=, $0, $pop5
 ; FAST-NEXT:    return $pop0
   %p = select i1 %x, ptr @foo, ptr @bar
   %v = tail call i1 %p(i1 %x)
@@ -264,7 +262,7 @@ define void @mismatched_indirect_void(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: mismatched_indirect_void:
 ; CHECK:         .functype mismatched_indirect_void (i32, i32, i32) -> ()
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect (i32, i32, i32) -> (i32), $drop=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect __indirect_function_table, (i32, i32, i32) -> (i32), $drop=, $0, $1, $2, $0
 ; CHECK-NEXT:    return
   %p = extractvalue %fn %f, 0
   %v = tail call i32 %p(%fn %f, i32 %x, i32 %y)
@@ -275,7 +273,7 @@ define float @mismatched_indirect_f32(%fn %f, i32 %x, i32 %y) {
 ; CHECK-LABEL: mismatched_indirect_f32:
 ; CHECK:         .functype mismatched_indirect_f32 (i32, i32, i32) -> (f32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    call_indirect (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0 # Invalid depth argument!
+; CHECK-NEXT:    call_indirect __indirect_function_table, (i32, i32, i32) -> (i32), $push0=, $0, $1, $2, $0
 ; CHECK-NEXT:    f32.reinterpret_i32 $push1=, $pop0
 ; CHECK-NEXT:    return $pop1
   %p = extractvalue %fn %f, 0
@@ -538,7 +536,7 @@ define i32 @indirect_epilogue(ptr %p) {
 ; CHECK-NEXT:    i32.const $push2=, 256
 ; CHECK-NEXT:    i32.add $push3=, $1, $pop2
 ; CHECK-NEXT:    global.set __stack_pointer, $pop3
-; CHECK-NEXT:    return_call_indirect (i32) -> (i32), $0, $0
+; CHECK-NEXT:    return_call_indirect __indirect_function_table, (i32) -> (i32), $0, $0
   %a = alloca [64 x i32]
   %v = musttail call i32 %p(ptr %p)
   ret i32 %v
@@ -564,7 +562,7 @@ define i32 @unique_caller(ptr %p) {
 ; SLOW-NEXT:    i64.const $push2=, 0
 ; SLOW-NEXT:    f64.const $push1=, 0x0p0
 ; SLOW-NEXT:    i32.load $push0=, 0($0)
-; SLOW-NEXT:    return_call_indirect (i32, f32, i64, f64) -> (i32), $pop4, $pop3, $pop2, $pop1, $pop0
+; SLOW-NEXT:    return_call_indirect __indirect_function_table, (i32, f32, i64, f64) -> (i32), $pop4, $pop3, $pop2, $pop1, $pop0
 ;
 ; FAST-LABEL: unique_caller:
 ; FAST:         .functype unique_caller (i32) -> (i32)
@@ -576,7 +574,7 @@ define i32 @unique_caller(ptr %p) {
 ; FAST-NEXT:    i32.const $push6=, 0
 ; FAST-NEXT:    f64.convert_i32_s $push4=, $pop6
 ; FAST-NEXT:    i32.load $push5=, 0($0)
-; FAST-NEXT:    call_indirect (i32, f32, i64, f64) -> (i32), $push0=, $pop1, $pop2, $pop3, $pop4, $pop5 # Invalid depth argument!
+; FAST-NEXT:    call_indirect __indirect_function_table, (i32, f32, i64, f64) -> (i32), $push0=, $pop1, $pop2, $pop3, $pop4, $pop5
 ; FAST-NEXT:    return $pop0
   %f = load ptr, ptr %p
   %v = tail call i32 %f(i32 0, float 0., i64 0, double 0.)
@@ -584,7 +582,6 @@ define i32 @unique_caller(ptr %p) {
 }
 
 ; CHECK-LABEL: .section .custom_section.target_features
-; CHECK-NEXT: .int8 1
-; CHECK-NEXT: .int8 43
-; CHECK-NEXT: .int8 9
-; CHECK-NEXT: .ascii "tail-call"
+; CHECK:       .ascii "reference-types"
+; CHECK:       .ascii "tail-call"
+; CHECK-LABEL: .section .text.unique_caller

>From bb6e312ded9280706b07fca2d3c3dcc28ff582da Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 13 Feb 2026 13:00:19 +0900
Subject: [PATCH 07/12] fix mistypo of return-call-indirect.ll

---
 llvm/test/CodeGen/WebAssembly/return-call-indirect.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
index 0b4f4882ebcf2..7121aece14d08 100644
--- a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
+++ b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
@@ -2,7 +2,7 @@
 ; RUN: llc < %s -asm-verbose=false -mattr=+reference-types,+tail-call -O2 | FileCheck --check-prefixes=CHECK,REF %s
 ; RUN: llc < %s -asm-verbose=false -mattr=+tail-call -O2 --filetype=obj | obj2yaml | FileCheck --check-prefix=OBJ %s
 
-; Test that compilation units with call_indirect but without any
+; Test that compilation units with return_call_indirect but without any
 ; function pointer declarations still get a table.
 
 target triple = "wasm32-unknown-unknown"

>From 821e13d5193587079669be2016c804dc2ea634db Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 13 Feb 2026 13:04:50 +0900
Subject: [PATCH 08/12] fix recover missed assert

---
 .../Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp  | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 963a2783aeba9..7c09d7910c56d 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -72,6 +72,8 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
         STI.checkFeatures("+reference-types")) {
       printOperand(MI, TableOperand, OS);
       OS << ", ";
+    } else {
+      assert(MI->getOperand(TableOperand).getImm() == 0);
     }
     printOperand(MI, TypeOperand, OS);
     if (MI->getOpcode() == WebAssembly::CALL_INDIRECT)

>From 1aaf9cc12e517cd09a6ce7eda617e15badc24853 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 13 Feb 2026 13:27:58 +0900
Subject: [PATCH 09/12] fix wrong condition

---
 .../WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp  | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 7c09d7910c56d..37b58daac644c 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -68,10 +68,11 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
     OS << "\t";
     OS << getMnemonic(*MI).first;
     OS << " ";
-    if (MI->getOperand(TableOperand).isExpr() &&
-        STI.checkFeatures("+reference-types")) {
-      printOperand(MI, TableOperand, OS);
-      OS << ", ";
+    if (MI->getOperand(TableOperand).isExpr()) {
+      if (STI.checkFeatures("+reference-types")) {
+        printOperand(MI, TableOperand, OS);
+        OS << ", ";
+      }
     } else {
       assert(MI->getOperand(TableOperand).getImm() == 0);
     }

>From 41ed5b6a273c52e0f447545c5c519c7c1448bf70 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Sat, 14 Feb 2026 15:39:52 +0900
Subject: [PATCH 10/12] Removing unnecessary test files

---
 .../WebAssembly/return-call-indirect.ll       | 29 -------------------
 1 file changed, 29 deletions(-)
 delete mode 100644 llvm/test/CodeGen/WebAssembly/return-call-indirect.ll

diff --git a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll b/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
deleted file mode 100644
index 7121aece14d08..0000000000000
--- a/llvm/test/CodeGen/WebAssembly/return-call-indirect.ll
+++ /dev/null
@@ -1,29 +0,0 @@
-; RUN: llc < %s -asm-verbose=false -mattr=-reference-types,+tail-call -O2 | FileCheck --check-prefixes=CHECK,NOREF %s
-; RUN: llc < %s -asm-verbose=false -mattr=+reference-types,+tail-call -O2 | FileCheck --check-prefixes=CHECK,REF %s
-; RUN: llc < %s -asm-verbose=false -mattr=+tail-call -O2 --filetype=obj | obj2yaml | FileCheck --check-prefix=OBJ %s
-
-; Test that compilation units with return_call_indirect but without any
-; function pointer declarations still get a table.
-
-target triple = "wasm32-unknown-unknown"
-
-; CHECK-LABEL: return_call_indirect:
-; CHECK-NEXT: .functype return_call_indirect (i32) -> (i32)
-; CHECK-NEXT: local.get 0
-; REF:       return_call_indirect     __indirect_function_table, () -> (i32)
-; NOREF:     return_call_indirect     () -> (i32)
-; CHECK-NEXT: end_function
-define i32 @return_call_indirect(ptr %callee) {
-  %r = tail call i32 %callee()
-  ret i32 %r
-}
-
-; OBJ:    Imports:
-; OBJ-NEXT:      - Module:          env
-; OBJ-NEXT:        Field:           __linear_memory
-; OBJ-NEXT:        Kind:            MEMORY
-; OBJ-NEXT:        Memory:
-; OBJ-NEXT:          Minimum:         0x0
-; OBJ-NEXT:      - Module:          env
-; OBJ-NEXT:        Field:           __indirect_function_table
-; OBJ-NEXT:        Kind:            TABLE

>From 1b24384c901130deccb300ce819c93ec36eed6da Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Sat, 14 Feb 2026 15:53:02 +0900
Subject: [PATCH 11/12] Removal of unnecessary condition checks

---
 .../WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp     | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 37b58daac644c..1bb9bb4b5bda8 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -69,10 +69,8 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
     OS << getMnemonic(*MI).first;
     OS << " ";
     if (MI->getOperand(TableOperand).isExpr()) {
-      if (STI.checkFeatures("+reference-types")) {
-        printOperand(MI, TableOperand, OS);
-        OS << ", ";
-      }
+      printOperand(MI, TableOperand, OS);
+      OS << ", ";
     } else {
       assert(MI->getOperand(TableOperand).getImm() == 0);
     }

>From 55c3f2bb9895cd27c014e5cc5383756933aeb9ea Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Sat, 14 Feb 2026 16:12:59 +0900
Subject: [PATCH 12/12] Changing the method for detecting tail calls in
 target_features

---
 llvm/test/CodeGen/WebAssembly/tailcall.ll | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/WebAssembly/tailcall.ll b/llvm/test/CodeGen/WebAssembly/tailcall.ll
index 7f6a3ebc2351d..df2918f3f4611 100644
--- a/llvm/test/CodeGen/WebAssembly/tailcall.ll
+++ b/llvm/test/CodeGen/WebAssembly/tailcall.ll
@@ -582,6 +582,7 @@ define i32 @unique_caller(ptr %p) {
 }
 
 ; CHECK-LABEL: .section .custom_section.target_features
-; CHECK:       .ascii "reference-types"
-; CHECK:       .ascii "tail-call"
-; CHECK-LABEL: .section .text.unique_caller
+; CHECK: .ascii  "sign-ext"
+; CHECK-NEXT: .int8   43
+; CHECK-NEXT: .int8   9
+; CHECK-NEXT: .ascii  "tail-call"



More information about the llvm-commits mailing list