[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
Mon Nov 10 10:39:12 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/2] [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/2] 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) {
More information about the llvm-commits
mailing list