[llvm] [WebAssembly] Truncate extra bits of large elements in BUILD_VECTOR (PR #167223)
Hongyu Chen via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 17 02:06:47 PST 2025
https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/167223
>From dd65e6655de4a66789ad543f578ef397005f672c Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 9 Nov 2025 22:45:57 +0800
Subject: [PATCH 1/2] [WebAssembly] Truncate extra bits of large elements in
BUILD_VECTOR
---
.../WebAssembly/WebAssemblyISelLowering.cpp | 15 +++++----------
.../test/CodeGen/WebAssembly/simd-build-vector.ll | 13 ++++++++++++-
2 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index fc6c2903471a8..ba686e7148267 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -2603,18 +2603,13 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
// Values may need to be fixed so that they will sign extend to be
// within the expected range during ISel. Check whether the value is in
// bounds based on the lane bit width and if it is out of bounds, lop
- // off the extra bits and subtract 2^n to reflect giving the high bit
- // value -2^(n-1) rather than +2^(n-1). Skip the i64 case because it
- // cannot possibly be out of range.
+ // off the extra bits.
auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode());
- int64_t Val = Const ? Const->getSExtValue() : 0;
uint64_t LaneBits = 128 / Lanes;
- assert((LaneBits == 64 || Val >= -(1ll << (LaneBits - 1))) &&
- "Unexpected out of bounds negative value");
- if (Const && LaneBits != 64 && Val > (1ll << (LaneBits - 1)) - 1) {
- uint64_t Mask = (1ll << LaneBits) - 1;
- auto NewVal = (((uint64_t)Val & Mask) - (1ll << LaneBits)) & Mask;
- ConstLanes.push_back(DAG.getConstant(NewVal, SDLoc(Lane), LaneT));
+ if (Const) {
+ ConstLanes.push_back(DAG.getConstant(
+ Const->getAPIntValue().trunc(LaneBits).getZExtValue(),
+ SDLoc(Lane), LaneT));
} else {
ConstLanes.push_back(Lane);
}
diff --git a/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll b/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
index cfbec78b9d17f..a499354129bc5 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
@@ -25,7 +25,7 @@ define <8 x i16> @different_const_one_replaced_i16x8(i16 %x) {
; CHECK-LABEL: different_const_one_replaced_i16x8:
; CHECK: .functype different_const_one_replaced_i16x8 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: v128.const $push0=, 1, -2, 3, -4, 5, 0, 7, -8
+; CHECK-NEXT: v128.const $push0=, 1, 65534, 3, 65532, 5, 0, 7, 65528
; CHECK-NEXT: i16x8.replace_lane $push1=, $pop0, 5, $0
; CHECK-NEXT: return $pop1
%v = insertelement
@@ -523,3 +523,14 @@ define <2 x double> @load_zero_lane_f64x2(ptr %addr.a, ptr %addr.b) {
ret <2 x double> %v.1
}
+define <2 x i8> @pr165713() {
+; CHECK-LABEL: pr165713:
+; CHECK: .functype pr165713 () -> (v128)
+; CHECK-NEXT: # %bb.0: # %entry
+; CHECK-NEXT: v128.const $push0=, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+; CHECK-NEXT: return $pop0
+entry:
+ %shuffle3.i = shufflevector <32 x i32> zeroinitializer, <32 x i32> <i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 -62880201, i32 poison, i32 poison, i32 poison>, <2 x i32> <i32 17, i32 60>
+ %conv.i = trunc <2 x i32> %shuffle3.i to <2 x i8>
+ ret <2 x i8> %conv.i
+}
>From 053a4fc9e35c455c7ce0c5327f17137d1c7878ff Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Mon, 17 Nov 2025 18:06:30 +0800
Subject: [PATCH 2/2] resolve comment
---
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index ba686e7148267..ad70d1b7e0a1e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -2604,9 +2604,8 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
// within the expected range during ISel. Check whether the value is in
// bounds based on the lane bit width and if it is out of bounds, lop
// off the extra bits.
- auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode());
uint64_t LaneBits = 128 / Lanes;
- if (Const) {
+ if (auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode())) {
ConstLanes.push_back(DAG.getConstant(
Const->getAPIntValue().trunc(LaneBits).getZExtValue(),
SDLoc(Lane), LaneT));
More information about the llvm-commits
mailing list