[llvm] [WebAssembly][FastISel] Fix sext i1 to i64 with +sign-ext (#213734) (PR #214007)
Gauarv Chaudhary via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 4 22:11:27 PDT 2026
https://github.com/ANAMASGARD updated https://github.com/llvm/llvm-project/pull/214007
>From a867410bf73a965e8afa9f3d9f46bded0f4bf7cd Mon Sep 17 00:00:00 2001
From: Gaurav Chaudhary <chaudharygaurav2004 at gmail.com>
Date: Tue, 4 Aug 2026 22:14:33 +0530
Subject: [PATCH] =?UTF-8?q?[WebAssembly][FastISel]=20Fix=20sext=20i1=20to?=
=?UTF-8?q?=20i64=20with=20+sign-ext=20(#213734)=20When=20the=20sign-ext?=
=?UTF-8?q?=20feature=20is=20enabled,=20signExtend()=20for=20i1=E2=86=92i6?=
=?UTF-8?q?4=20fell=20through=20the=20switch=20without=20emitting=20any=20?=
=?UTF-8?q?instruction,=20returning=20an=20undefined=20register.=20This=20?=
=?UTF-8?q?broke=20floor-division=20patterns=20that=20adjust=20the=20quoti?=
=?UTF-8?q?ent=20via=20sext=20i1,=20producing=20wrong=20results=20at=20-O0?=
=?UTF-8?q?.=20Restructure=20the=20i64=20sign-extend=20path=20so=20i8,=20i?=
=?UTF-8?q?16,=20and=20i32=20use=20their=20native=20extend=20sequences,=20?=
=?UTF-8?q?while=20i1=20uses=20the=20generic=20signExtendToI32=20+=20i64.e?=
=?UTF-8?q?xtend=5Fi32=5Fs=20fallback.=20Unsupported=20types=20return=200?=
=?UTF-8?q?=20from=20signExtendToI32()=20and=20fail=20FastISel=20cleanly.?=
=?UTF-8?q?=20Fixes=20#213734?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Gaurav Chaudhary <chaudharygaurav2004 at gmail.com>
---
.../WebAssembly/WebAssemblyFastISel.cpp | 35 ++++++++-----------
.../test/CodeGen/WebAssembly/signext-inreg.ll | 25 +++++++++++--
2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 95f4367f76cdf..cbfca984c3679 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -583,26 +583,20 @@ unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
Register Result = createResultReg(&WebAssembly::I64RegClass);
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:
+ case MVT::i16: {
+ Register Tmp = createResultReg(&WebAssembly::I64RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::I64_EXTEND8_S_I64), Result)
+ TII.get(WebAssembly::I64_EXTEND_U_I32), Tmp)
.addReg(Reg);
- return Result;
- case MVT::i16:
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::I64_EXTEND16_S_I64), Result)
- .addReg(Reg);
+ TII.get(From == MVT::i8 ? WebAssembly::I64_EXTEND8_S_I64
+ : WebAssembly::I64_EXTEND16_S_I64),
+ Result)
+ .addReg(Tmp);
return Result;
+ }
case MVT::i32:
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
@@ -611,14 +605,15 @@ unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
default:
break;
}
- } else {
- Reg = signExtendToI32(Reg, V, From);
-
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
- TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
- .addReg(Reg);
}
+ Reg = signExtendToI32(Reg, V, From);
+ if (Reg == 0)
+ return 0;
+
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
+ TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
+ .addReg(Reg);
return Result;
}
diff --git a/llvm/test/CodeGen/WebAssembly/signext-inreg.ll b/llvm/test/CodeGen/WebAssembly/signext-inreg.ll
index c56ee860082c8..7b4a00cfc9f05 100644
--- a/llvm/test/CodeGen/WebAssembly/signext-inreg.ll
+++ b/llvm/test/CodeGen/WebAssembly/signext-inreg.ll
@@ -1,6 +1,6 @@
-; 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 -mattr=+sign-ext -fast-isel=0 -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes=CHECK,SLOW
; RUN: llc < %s -mattr=-sign-ext -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 -mattr=+sign-ext -fast-isel=1 -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes=CHECK,FAST
; RUN: llc < %s -mattr=-sign-ext -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"
@@ -63,3 +63,24 @@ define i64 @i64_extend32_s(i32 %x) {
%a = sext i32 %x to i64
ret i64 %a
}
+
+; CHECK-LABEL: i64_extend1_s:
+; CHECK-NEXT: .functype i64_extend1_s (i32) -> (i64){{$}}
+; SLOW-NEXT: i64.const $push[[NUM3:[0-9]+]]=, 0{{$}}
+; SLOW-NEXT: i64.extend_i32_u $push[[NUM0:[0-9]+]]=, $0{{$}}
+; SLOW-NEXT: i64.const $push[[NUM1:[0-9]+]]=, 1{{$}}
+; SLOW-NEXT: i64.and $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
+; SLOW-NEXT: i64.sub $push[[NUM4:[0-9]+]]=, $pop[[NUM3]], $pop[[NUM2]]{{$}}
+; SLOW-NEXT: return $pop[[NUM4]]{{$}}
+; FAST-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 31{{$}}
+; FAST-NEXT: i32.shl $push[[NUM0:[0-9]+]]=, $0, $pop[[NUM1]]{{$}}
+; FAST-NEXT: i32.const $push[[NUM4:[0-9]+]]=, 31{{$}}
+; FAST-NEXT: i32.shr_s $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM4]]{{$}}
+; FAST-NEXT: i64.extend_i32_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]]{{$}}
+; FAST-NEXT: return $pop[[NUM3]]{{$}}
+
+; NOSIGNEXT-LABEL: i64_extend1_s
+define i64 @i64_extend1_s(i1 %x) {
+ %a = sext i1 %x to i64
+ ret i64 %a
+}
More information about the llvm-commits
mailing list