[llvm] [WebAssembly][FastISel] Make use of `sign-ext` proposals instructions when available (PR #179855)
Demetrius Kanios via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 4 19:55:18 PST 2026
https://github.com/QuantumSegfault created https://github.com/llvm/llvm-project/pull/179855
Enables FastISel to use the dedicated sign-extension instructions (rather than shl, shr) when available.
>From 386a43188c947e2fa0b57aa3dfe2d849e53ffc99 Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Wed, 4 Feb 2026 19:53:42 -0800
Subject: [PATCH] Make use of sign-ext proposal instructions in FastISel
---
.../WebAssembly/WebAssemblyFastISel.cpp | 78 +++++++++++++++----
.../test/CodeGen/WebAssembly/signext-inreg.ll | 7 +-
2 files changed, 65 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index f4860e21e310e..c869164d96945 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -478,8 +478,8 @@ unsigned WebAssemblyFastISel::zeroExtendToI32(unsigned Reg, const Value *V,
.addImm(~(~uint64_t(0) << MVT(From).getSizeInBits()));
Register Result = createResultReg(&WebAssembly::I32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::AND_I32), Result)
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(WebAssembly::AND_I32),
+ Result)
.addReg(Reg)
.addReg(Imm);
@@ -502,14 +502,26 @@ unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
return 0;
}
+ if (Subtarget->hasSignExt()) {
+ if (From == MVT::i8 || From == MVT::i16) {
+ Register Result = createResultReg(&WebAssembly::I32RegClass);
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(From == MVT::i16 ? WebAssembly::I32_EXTEND16_S_I32
+ : WebAssembly::I32_EXTEND8_S_I32),
+ Result)
+ .addReg(Reg);
+ return Result;
+ }
+ }
+
Register Imm = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(WebAssembly::CONST_I32), Imm)
.addImm(32 - MVT(From).getSizeInBits());
Register Left = createResultReg(&WebAssembly::I32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::SHL_I32), Left)
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(WebAssembly::SHL_I32),
+ Left)
.addReg(Reg)
.addReg(Imm);
@@ -551,12 +563,45 @@ unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
if (From == MVT::i64)
return copyValue(Reg);
- Reg = signExtendToI32(Reg, V, From);
-
Register Result = createResultReg(&WebAssembly::I64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
- .addReg(Reg);
+
+ if (Subtarget->hasSignExt()) {
+ if (From != MVT::i32) {
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(WebAssembly::I64_EXTEND_U_I32), Result)
+ .addReg(Reg);
+
+ Reg = Result;
+ Result = createResultReg(&WebAssembly::I64RegClass);
+ }
+
+ switch (From) {
+ case MVT::i8:
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(WebAssembly::I64_EXTEND8_S_I64), Result)
+ .addReg(Reg);
+ return Result;
+ case MVT::i16:
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(WebAssembly::I64_EXTEND16_S_I64), Result)
+ .addReg(Reg);
+ return Result;
+ case MVT::i32:
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
+ .addReg(Reg);
+ return Result;
+ default:
+ break;
+ }
+ } else {
+ Reg = signExtendToI32(Reg, V, From);
+
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
+ .addReg(Reg);
+ }
+
return Result;
}
@@ -597,8 +642,8 @@ unsigned WebAssemblyFastISel::notValue(unsigned Reg) {
assert(MRI.getRegClass(Reg) == &WebAssembly::I32RegClass);
Register NotReg = createResultReg(&WebAssembly::I32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::EQZ_I32), NotReg)
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(WebAssembly::EQZ_I32),
+ NotReg)
.addReg(Reg);
return NotReg;
}
@@ -1210,8 +1255,8 @@ bool WebAssemblyFastISel::selectBitCast(const Instruction *I) {
return true;
}
- Register Reg = fastEmit_ISD_BITCAST_r(VT.getSimpleVT(), RetVT.getSimpleVT(),
- In);
+ Register Reg =
+ fastEmit_ISD_BITCAST_r(VT.getSimpleVT(), RetVT.getSimpleVT(), In);
if (!Reg)
return false;
MachineBasicBlock::iterator Iter = FuncInfo.InsertPt;
@@ -1273,8 +1318,8 @@ bool WebAssemblyFastISel::selectLoad(const Instruction *I) {
materializeLoadStoreOperands(Addr);
Register ResultReg = createResultReg(RC);
- auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
- ResultReg);
+ auto MIB =
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg);
addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Load));
@@ -1422,8 +1467,7 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) {
if (Reg == 0)
return false;
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::RETURN))
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(WebAssembly::RETURN))
.addReg(Reg);
return true;
}
diff --git a/llvm/test/CodeGen/WebAssembly/signext-inreg.ll b/llvm/test/CodeGen/WebAssembly/signext-inreg.ll
index 5778a9418a3d4..2a98b14226ab4 100644
--- a/llvm/test/CodeGen/WebAssembly/signext-inreg.ll
+++ b/llvm/test/CodeGen/WebAssembly/signext-inreg.ll
@@ -1,6 +1,7 @@
-; RUN: llc < %s -mattr=+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=NOSIGNEXT
-
+; RUN: llc < %s -mattr=+sign-ext -fast-isel=0 -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -fast-isel=0 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=NOSIGNEXT
+; RUN: llc < %s -mattr=+sign-ext -fast-isel=1 -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -fast-isel=1 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=NOSIGNEXT
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: i32_extend8_s:
More information about the llvm-commits
mailing list