[llvm] [WebAssembly][FastISel] Make use of `sign-ext` proposals instructions when available (PR #179855)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 4 19:55:52 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly
Author: Demetrius Kanios (QuantumSegfault)
<details>
<summary>Changes</summary>
Enables FastISel to use the dedicated sign-extension instructions (rather than shl, shr) when available.
---
Full diff: https://github.com/llvm/llvm-project/pull/179855.diff
2 Files Affected:
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp (+61-17)
- (modified) llvm/test/CodeGen/WebAssembly/signext-inreg.ll (+4-3)
``````````diff
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:
``````````
</details>
https://github.com/llvm/llvm-project/pull/179855
More information about the llvm-commits
mailing list