From dd65e6655de4a66789ad543f578ef397005f672c Mon Sep 17 00:00:00 2001 From: XChy Date: Sun, 9 Nov 2025 22:45:57 +0800 Subject: [PATCH] [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(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> , <2 x i32> + %conv.i = trunc <2 x i32> %shuffle3.i to <2 x i8> + ret <2 x i8> %conv.i +}