From ba8f085c8ed3eedb7360191ab0bf3335a19a2aeb Mon Sep 17 00:00:00 2001 From: XChy Date: Sun, 9 Nov 2025 02:11:33 +0800 Subject: [PATCH 1/3] [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(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 Date: Tue, 11 Nov 2025 02:38:41 +0800 Subject: [PATCH 2/3] 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 Date: Tue, 11 Nov 2025 02:41:40 +0800 Subject: [PATCH 3/3] 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);