Skip to content

Commit 63e6373

Browse files
authored
[WebAssembly] Truncate extra bits of large elements in BUILD_VECTOR (#167223)
Fixes #165713 This patch handles out-of-bound vector elements and truncates extra bits.
1 parent bdae26f commit 63e6373

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,18 +2603,12 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
26032603
// Values may need to be fixed so that they will sign extend to be
26042604
// within the expected range during ISel. Check whether the value is in
26052605
// bounds based on the lane bit width and if it is out of bounds, lop
2606-
// off the extra bits and subtract 2^n to reflect giving the high bit
2607-
// value -2^(n-1) rather than +2^(n-1). Skip the i64 case because it
2608-
// cannot possibly be out of range.
2609-
auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode());
2610-
int64_t Val = Const ? Const->getSExtValue() : 0;
2606+
// off the extra bits.
26112607
uint64_t LaneBits = 128 / Lanes;
2612-
assert((LaneBits == 64 || Val >= -(1ll << (LaneBits - 1))) &&
2613-
"Unexpected out of bounds negative value");
2614-
if (Const && LaneBits != 64 && Val > (1ll << (LaneBits - 1)) - 1) {
2615-
uint64_t Mask = (1ll << LaneBits) - 1;
2616-
auto NewVal = (((uint64_t)Val & Mask) - (1ll << LaneBits)) & Mask;
2617-
ConstLanes.push_back(DAG.getConstant(NewVal, SDLoc(Lane), LaneT));
2608+
if (auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode())) {
2609+
ConstLanes.push_back(DAG.getConstant(
2610+
Const->getAPIntValue().trunc(LaneBits).getZExtValue(),
2611+
SDLoc(Lane), LaneT));
26182612
} else {
26192613
ConstLanes.push_back(Lane);
26202614
}

llvm/test/CodeGen/WebAssembly/simd-build-vector.ll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ define <8 x i16> @different_const_one_replaced_i16x8(i16 %x) {
2525
; CHECK-LABEL: different_const_one_replaced_i16x8:
2626
; CHECK: .functype different_const_one_replaced_i16x8 (i32) -> (v128)
2727
; CHECK-NEXT: # %bb.0:
28-
; CHECK-NEXT: v128.const $push0=, 1, -2, 3, -4, 5, 0, 7, -8
28+
; CHECK-NEXT: v128.const $push0=, 1, 65534, 3, 65532, 5, 0, 7, 65528
2929
; CHECK-NEXT: i16x8.replace_lane $push1=, $pop0, 5, $0
3030
; CHECK-NEXT: return $pop1
3131
%v = insertelement
@@ -523,3 +523,14 @@ define <2 x double> @load_zero_lane_f64x2(ptr %addr.a, ptr %addr.b) {
523523
ret <2 x double> %v.1
524524
}
525525

526+
define <2 x i8> @pr165713() {
527+
; CHECK-LABEL: pr165713:
528+
; CHECK: .functype pr165713 () -> (v128)
529+
; CHECK-NEXT: # %bb.0: # %entry
530+
; CHECK-NEXT: v128.const $push0=, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
531+
; CHECK-NEXT: return $pop0
532+
entry:
533+
%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>
534+
%conv.i = trunc <2 x i32> %shuffle3.i to <2 x i8>
535+
ret <2 x i8> %conv.i
536+
}

0 commit comments

Comments
 (0)