[llvm] 7d9d392 - [WebAssembly] Fix SELECT_CC lowering for reference types (#181622)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 19 09:14:33 PST 2026


Author: Hood Chatham
Date: 2026-02-19T09:14:29-08:00
New Revision: 7d9d392a1fa225950d5813a1355effb4f2c8a7f7

URL: https://github.com/llvm/llvm-project/commit/7d9d392a1fa225950d5813a1355effb4f2c8a7f7
DIFF: https://github.com/llvm/llvm-project/commit/7d9d392a1fa225950d5813a1355effb4f2c8a7f7.diff

LOG: [WebAssembly] Fix SELECT_CC lowering for reference types (#181622)

SELECT_CC nodes with externref or funcref return types were not being
expanded, causing "Cannot select" errors during instruction selection.

This adds SELECT_CC to the list of operations that should be expanded
for reference types, similar to how it's already handled for scalar
types (i32, i64, f32, f64). This allows the SELECT_CC to be lowered to a
SELECT node, which already has instruction patterns defined in
WebAssemblyInstrRef.td.

Added: 
    llvm/test/CodeGen/WebAssembly/select-reftype.ll

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 1cacdb04fa74d..fdf98902b68bd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -666,6 +666,12 @@ void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
   case WebAssembly::ARGUMENT_v2f64_S:
   case WebAssembly::ARGUMENT_v8f16:
   case WebAssembly::ARGUMENT_v8f16_S:
+  case WebAssembly::ARGUMENT_externref:
+  case WebAssembly::ARGUMENT_externref_S:
+  case WebAssembly::ARGUMENT_funcref:
+  case WebAssembly::ARGUMENT_funcref_S:
+  case WebAssembly::ARGUMENT_exnref:
+  case WebAssembly::ARGUMENT_exnref_S:
     // These represent values which are live into the function entry, so there's
     // no instruction to emit.
     break;

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 2799b0ee0c804..faea931aeccdc 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -271,11 +271,6 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
     // There is no i8x16.mul instruction
     setOperationAction(ISD::MUL, MVT::v16i8, Expand);
 
-    // There is no vector conditional select instruction
-    for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
-                   MVT::v2f64})
-      setOperationAction(ISD::SELECT_CC, T, Expand);
-
     // Expand integer operations supported for scalars but not SIMD
     for (auto Op :
          {ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM, ISD::ROTL, ISD::ROTR})
@@ -370,6 +365,16 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
     for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
       setOperationAction(Op, T, Expand);
 
+  if (Subtarget->hasReferenceTypes())
+    for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
+      for (auto T : {MVT::externref, MVT::funcref})
+        setOperationAction(Op, T, Expand);
+
+  // There is no vector conditional select instruction
+  for (auto T :
+       {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64, MVT::v2f64})
+    setOperationAction(ISD::SELECT_CC, T, Expand);
+
   // We have custom switch handling.
   setOperationAction(ISD::BR_JT, MVT::Other, Custom);
 

diff  --git a/llvm/test/CodeGen/WebAssembly/select-reftype.ll b/llvm/test/CodeGen/WebAssembly/select-reftype.ll
new file mode 100644
index 0000000000000..baca3ca6258a3
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/select-reftype.ll
@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -mattr=+reference-types -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s
+
+; Test that wasm select instruction works with reference types.
+
+target triple = "wasm32-unknown-unknown"
+
+define ptr addrspace(10) @select_externref_eq(i32 %a, ptr addrspace(10) %b, ptr addrspace(10) %c) {
+; CHECK-LABEL: select_externref_eq:
+; CHECK:         .functype select_externref_eq (i32, externref, externref) -> (externref)
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    externref.select $push0=, $2, $1, $0
+; CHECK-NEXT:    return $pop0
+  %cmp = icmp eq i32 %a, 0
+  %cond = select i1 %cmp, ptr addrspace(10) %b, ptr addrspace(10) %c
+  ret ptr addrspace(10) %cond
+}
+
+define ptr addrspace(10) @select_externref_ne(i32 %a, ptr addrspace(10) %b, ptr addrspace(10) %c) {
+; CHECK-LABEL: select_externref_ne:
+; CHECK:         .functype select_externref_ne (i32, externref, externref) -> (externref)
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    externref.select $push0=, $1, $2, $0
+; CHECK-NEXT:    return $pop0
+  %cmp = icmp ne i32 %a, 0
+  %cond = select i1 %cmp, ptr addrspace(10) %b, ptr addrspace(10) %c
+  ret ptr addrspace(10) %cond
+}
+
+define ptr addrspace(20) @select_funcref_eq(i32 %a, ptr addrspace(20) %b, ptr addrspace(20) %c) {
+; CHECK-LABEL: select_funcref_eq:
+; CHECK:         .functype select_funcref_eq (i32, funcref, funcref) -> (funcref)
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    funcref.select $push0=, $2, $1, $0
+; CHECK-NEXT:    return $pop0
+  %cmp = icmp eq i32 %a, 0
+  %cond = select i1 %cmp, ptr addrspace(20) %b, ptr addrspace(20) %c
+  ret ptr addrspace(20) %cond
+}
+
+define ptr addrspace(20) @select_funcref_ne(i32 %a, ptr addrspace(20) %b, ptr addrspace(20) %c) {
+; CHECK-LABEL: select_funcref_ne:
+; CHECK:         .functype select_funcref_ne (i32, funcref, funcref) -> (funcref)
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    funcref.select $push0=, $1, $2, $0
+; CHECK-NEXT:    return $pop0
+  %cmp = icmp ne i32 %a, 0
+  %cond = select i1 %cmp, ptr addrspace(20) %b, ptr addrspace(20) %c
+  ret ptr addrspace(20) %cond
+}


        


More information about the llvm-commits mailing list