[llvm] [WebAssembly][FastISel] Bail out on meeting non-integer type in selectTrunc (PR #167165)

Hongyu Chen via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 11 05:11:02 PST 2025


https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/167165

>From ba8f085c8ed3eedb7360191ab0bf3335a19a2aeb Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 9 Nov 2025 02:11:33 +0800
Subject: [PATCH 1/4] [WebAssembly] Bail out in selectTrunc for non-simple
 types

---
 .../WebAssembly/WebAssemblyFastISel.cpp       | 46 +++++++++++++------
 .../CodeGen/WebAssembly/fast-isel-pr138479.ll |  5 +-
 .../CodeGen/WebAssembly/fast-isel-simd128.ll  | 23 ++++++++++
 3 files changed, 59 insertions(+), 15 deletions(-)
 create mode 100644 llvm/test/CodeGen/WebAssembly/fast-isel-simd128.ll

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 66ed8b078b808..54c2cc238fa53 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -157,6 +157,8 @@ class WebAssemblyFastISel final : public FastISel {
                             MachineMemOperand *MMO);
   unsigned maskI1Value(unsigned Reg, const Value *V);
   unsigned getRegForI1Value(const Value *V, const BasicBlock *BB, bool &Not);
+  unsigned truncate(unsigned Reg, const Value *V, MVT::SimpleValueType From,
+                      MVT::SimpleValueType To);
   unsigned zeroExtendToI32(unsigned Reg, const Value *V,
                            MVT::SimpleValueType From);
   unsigned signExtendToI32(unsigned Reg, const Value *V,
@@ -519,6 +521,28 @@ unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
   return Right;
 }
 
+unsigned WebAssemblyFastISel::truncate(unsigned Reg, const Value *V,
+                                    MVT::SimpleValueType From,
+                                    MVT::SimpleValueType To) {
+  if (From == MVT::i64) {
+    if (To == MVT::i64)
+      return copyValue(Reg);
+
+    if (To == MVT::i1 || To == MVT::i8 || To == MVT::i16 || To == MVT::i32) {
+      Register Result = createResultReg(&WebAssembly::I32RegClass);
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+              TII.get(WebAssembly::I32_WRAP_I64), Result)
+          .addReg(Reg);
+      return Result;
+    }
+  }
+
+  if (From == MVT::i32)
+    return copyValue(Reg);
+
+  return 0;
+}
+
 unsigned WebAssemblyFastISel::zeroExtend(unsigned Reg, const Value *V,
                                          MVT::SimpleValueType From,
                                          MVT::SimpleValueType To) {
@@ -988,23 +1012,17 @@ bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
 bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
   const auto *Trunc = cast<TruncInst>(I);
 
-  Register Reg = getRegForValue(Trunc->getOperand(0));
+  const Value *Op = Trunc->getOperand(0);
+  MVT::SimpleValueType From = getSimpleType(Op->getType());
+  MVT::SimpleValueType To = getLegalType(getSimpleType(Trunc->getType()));
+  Register In = getRegForValue(Op);
+  if (In == 0)
+    return false;
+  unsigned Reg = truncate(In, Op, From, To);
   if (Reg == 0)
     return false;
 
-  unsigned FromBitWidth = Trunc->getOperand(0)->getType()->getIntegerBitWidth();
-  unsigned ToBitWidth = Trunc->getType()->getIntegerBitWidth();
-
-  if (ToBitWidth <= 32 && (32 < FromBitWidth && FromBitWidth <= 64)) {
-    Register Result = createResultReg(&WebAssembly::I32RegClass);
-    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
-            TII.get(WebAssembly::I32_WRAP_I64), Result)
-        .addReg(Reg);
-    Reg = Result;
-  }
-
-  updateValueMap(Trunc, Reg);
-  return true;
+  updateValueMap(Trunc, Reg);  return true;
 }
 
 bool WebAssemblyFastISel::selectZExt(const Instruction *I) {
diff --git a/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll b/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll
index 2676000b968c3..1eb50d5f9564a 100644
--- a/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll
+++ b/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll
@@ -1,4 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=0 -verify-machineinstrs | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
 
@@ -13,3 +14,5 @@ define void @call_trunc_i64_to_i48(i64 %x) {
   call void @extern48(i48 %x48)
   ret void
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/CodeGen/WebAssembly/fast-isel-simd128.ll b/llvm/test/CodeGen/WebAssembly/fast-isel-simd128.ll
new file mode 100644
index 0000000000000..df14e1054d91b
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/fast-isel-simd128.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -fast-isel -fast-isel-abort=0 -mattr=+simd128 -verify-machineinstrs | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define i8 @pr165438(<4 x i32> %0) {
+; CHECK-LABEL: pr165438:
+; CHECK:         .functype pr165438 (v128) -> (i32)
+; CHECK-NEXT:  # %bb.0: # %entry
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    i8x16.shuffle 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+; CHECK-NEXT:    i8x16.extract_lane_u 0
+; CHECK-NEXT:    # fallthrough-return
+entry:
+  %conv = trunc <4 x i32> %0 to <4 x i8>
+  br label %cond.true
+
+
+cond.true:                                        ; preds = %entry
+  %vecext = extractelement <4 x i8> %conv, i32 0
+  ret i8 %vecext
+}

>From 064581ddb68ba9301d8cfb30fa1c5a9515040791 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Tue, 11 Nov 2025 02:38:41 +0800
Subject: [PATCH 2/4] format

---
 llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 54c2cc238fa53..9eae226377391 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -1022,7 +1022,8 @@ bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
   if (Reg == 0)
     return false;
 
-  updateValueMap(Trunc, Reg);  return true;
+  updateValueMap(Trunc, Reg);
+  return true;
 }
 
 bool WebAssemblyFastISel::selectZExt(const Instruction *I) {

>From 1a7ce63c522b8d4f8aaad6cca6ece28f8d197fa9 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Tue, 11 Nov 2025 02:41:40 +0800
Subject: [PATCH 3/4] format

---
 llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 9eae226377391..a5153f577ca04 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -158,7 +158,7 @@ class WebAssemblyFastISel final : public FastISel {
   unsigned maskI1Value(unsigned Reg, const Value *V);
   unsigned getRegForI1Value(const Value *V, const BasicBlock *BB, bool &Not);
   unsigned truncate(unsigned Reg, const Value *V, MVT::SimpleValueType From,
-                      MVT::SimpleValueType To);
+                    MVT::SimpleValueType To);
   unsigned zeroExtendToI32(unsigned Reg, const Value *V,
                            MVT::SimpleValueType From);
   unsigned signExtendToI32(unsigned Reg, const Value *V,
@@ -522,8 +522,8 @@ unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
 }
 
 unsigned WebAssemblyFastISel::truncate(unsigned Reg, const Value *V,
-                                    MVT::SimpleValueType From,
-                                    MVT::SimpleValueType To) {
+                                       MVT::SimpleValueType From,
+                                       MVT::SimpleValueType To) {
   if (From == MVT::i64) {
     if (To == MVT::i64)
       return copyValue(Reg);

>From 8c43521ce8c12f484c0d3a24dbf6c07f955583c2 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Tue, 11 Nov 2025 21:10:41 +0800
Subject: [PATCH 4/4] refactor

---
 .../WebAssembly/WebAssemblyFastISel.cpp       | 47 +++++++++----------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index a5153f577ca04..9d8e09c09e9ea 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -157,8 +157,6 @@ class WebAssemblyFastISel final : public FastISel {
                             MachineMemOperand *MMO);
   unsigned maskI1Value(unsigned Reg, const Value *V);
   unsigned getRegForI1Value(const Value *V, const BasicBlock *BB, bool &Not);
-  unsigned truncate(unsigned Reg, const Value *V, MVT::SimpleValueType From,
-                    MVT::SimpleValueType To);
   unsigned zeroExtendToI32(unsigned Reg, const Value *V,
                            MVT::SimpleValueType From);
   unsigned signExtendToI32(unsigned Reg, const Value *V,
@@ -521,28 +519,6 @@ unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
   return Right;
 }
 
-unsigned WebAssemblyFastISel::truncate(unsigned Reg, const Value *V,
-                                       MVT::SimpleValueType From,
-                                       MVT::SimpleValueType To) {
-  if (From == MVT::i64) {
-    if (To == MVT::i64)
-      return copyValue(Reg);
-
-    if (To == MVT::i1 || To == MVT::i8 || To == MVT::i16 || To == MVT::i32) {
-      Register Result = createResultReg(&WebAssembly::I32RegClass);
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
-              TII.get(WebAssembly::I32_WRAP_I64), Result)
-          .addReg(Reg);
-      return Result;
-    }
-  }
-
-  if (From == MVT::i32)
-    return copyValue(Reg);
-
-  return 0;
-}
-
 unsigned WebAssemblyFastISel::zeroExtend(unsigned Reg, const Value *V,
                                          MVT::SimpleValueType From,
                                          MVT::SimpleValueType To) {
@@ -1018,7 +994,28 @@ bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
   Register In = getRegForValue(Op);
   if (In == 0)
     return false;
-  unsigned Reg = truncate(In, Op, From, To);
+
+  auto Truncate = [&](Register Reg) -> unsigned {
+    if (From == MVT::i64) {
+      if (To == MVT::i64)
+        return copyValue(Reg);
+
+      if (To == MVT::i1 || To == MVT::i8 || To == MVT::i16 || To == MVT::i32) {
+        Register Result = createResultReg(&WebAssembly::I32RegClass);
+        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+                TII.get(WebAssembly::I32_WRAP_I64), Result)
+            .addReg(Reg);
+        return Result;
+      }
+    }
+
+    if (From == MVT::i32)
+      return copyValue(Reg);
+
+    return 0;
+  };
+
+  unsigned Reg = Truncate(In);
   if (Reg == 0)
     return false;
 



More information about the llvm-commits mailing list