[llvm] [WebAssembly][FastISel] Omit redundant AND for zext of i8/i16 loads (PR #182240)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 19 01:48:57 PST 2026
https://github.com/ParkHanbum created https://github.com/llvm/llvm-project/pull/182240
When zero-extending an i8 or i16 load to i32, FastISel previously emitted an explicit AND instruction to mask the upper bits. This is redundant because WebAssembly's native unsigned load instructions (load8_u and load16_u) inherently zero-extend the loaded values.
Fixes #180783
>From 25077f5e99569fb6f90144063b5d3c02b65738de Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 19 Feb 2026 18:46:07 +0900
Subject: [PATCH] [WebAssembly][FastISel] Omit redundant AND for zext of i8/i16
loads
When zero-extending an i8 or i16 load to i32, FastISel previously
emitted an explicit AND instruction to mask the upper bits. This is
redundant because WebAssembly's native unsigned load instructions
(load8_u and load16_u) inherently zero-extend the loaded values.
Fixes #180783
---
.../Target/WebAssembly/WebAssemblyFastISel.cpp | 2 ++
llvm/test/CodeGen/WebAssembly/load-ext.ll | 16 ++++------------
llvm/test/CodeGen/WebAssembly/offset-fastisel.ll | 4 +---
3 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index c869164d96945..fcadfd1f70871 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -465,6 +465,8 @@ unsigned WebAssemblyFastISel::zeroExtendToI32(unsigned Reg, const Value *V,
break;
case MVT::i8:
case MVT::i16:
+ if (isa<LoadInst>(V))
+ return copyValue(Reg);
break;
case MVT::i32:
return copyValue(Reg);
diff --git a/llvm/test/CodeGen/WebAssembly/load-ext.ll b/llvm/test/CodeGen/WebAssembly/load-ext.ll
index c3460f7916c30..5f93017b1e078 100644
--- a/llvm/test/CodeGen/WebAssembly/load-ext.ll
+++ b/llvm/test/CodeGen/WebAssembly/load-ext.ll
@@ -21,9 +21,7 @@ define i32 @sext_i8_i32(ptr %p) {
; DAG: i32.load8_u $push0=, 0($0){{$}}
; DAG-NEXT: return $pop0{{$}}
; FAST: i32.load8_u $push[[L:[0-9]+]]=, 0($0)
-; FAST-NEXT: i32.const $push[[C:[0-9]+]]=, 255
-; FAST-NEXT: i32.and $push[[R:[0-9]+]]=, $pop[[L]], $pop[[C]]
-; FAST-NEXT: return $pop[[R]]
+; FAST-NEXT: return $pop[[L]]
define i32 @zext_i8_i32(ptr %p) {
%v = load i8, ptr %p
%e = zext i8 %v to i32
@@ -46,9 +44,7 @@ define i32 @sext_i16_i32(ptr %p) {
; DAG: i32.load16_u $push0=, 0($0){{$}}
; DAG-NEXT: return $pop0{{$}}
; FAST: i32.load16_u $push[[L:[0-9]+]]=, 0($0)
-; FAST-NEXT: i32.const $push[[C:[0-9]+]]=, 65535
-; FAST-NEXT: i32.and $push[[R:[0-9]+]]=, $pop[[L]], $pop[[C]]
-; FAST-NEXT: return $pop[[R]]
+; FAST-NEXT: return $pop[[L]]
define i32 @zext_i16_i32(ptr %p) {
%v = load i16, ptr %p
%e = zext i16 %v to i32
@@ -72,9 +68,7 @@ define i64 @sext_i8_i64(ptr %p) {
; DAG: i64.load8_u $push0=, 0($0){{$}}
; DAG-NEXT: return $pop0{{$}}
; FAST: i32.load8_u $push[[L:[0-9]+]]=, 0($0)
-; FAST-NEXT: i32.const $push[[C:[0-9]+]]=, 255
-; FAST-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[L]], $pop[[C]]
-; FAST-NEXT: i64.extend_i32_u $push[[EXT:[0-9]+]]=, $pop[[AND]]
+; FAST-NEXT: i64.extend_i32_u $push[[EXT:[0-9]+]]=, $pop[[L]]
; FAST-NEXT: return $pop[[EXT]]
define i64 @zext_i8_i64(ptr %p) {
%v = load i8, ptr %p
@@ -99,9 +93,7 @@ define i64 @sext_i16_i64(ptr %p) {
; DAG: i64.load16_u $push0=, 0($0){{$}}
; DAG-NEXT: return $pop0{{$}}
; FAST: i32.load16_u $push[[L:[0-9]+]]=, 0($0)
-; FAST-NEXT: i32.const $push[[C:[0-9]+]]=, 65535
-; FAST-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[L]], $pop[[C]]
-; FAST-NEXT: i64.extend_i32_u $push[[EXT:[0-9]+]]=, $pop[[AND]]
+; FAST-NEXT: i64.extend_i32_u $push[[EXT:[0-9]+]]=, $pop[[L]]
; FAST-NEXT: return $pop[[EXT]]
define i64 @zext_i16_i64(ptr %p) {
%v = load i16, ptr %p
diff --git a/llvm/test/CodeGen/WebAssembly/offset-fastisel.ll b/llvm/test/CodeGen/WebAssembly/offset-fastisel.ll
index c004410f18122..4b5faa723cf0c 100644
--- a/llvm/test/CodeGen/WebAssembly/offset-fastisel.ll
+++ b/llvm/test/CodeGen/WebAssembly/offset-fastisel.ll
@@ -104,9 +104,7 @@ define i32 @load_i8_u_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_i8_u_with_folded_offset:
; CHECK: .functype load_i8_u_with_folded_offset (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: i32.load8_u $push2=, 24($0)
-; CHECK-NEXT: i32.const $push0=, 255
-; CHECK-NEXT: i32.and $push1=, $pop2, $pop0
+; CHECK-NEXT: i32.load8_u $push0=, 24($0)
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 24
More information about the llvm-commits
mailing list