Skip to content

Commit 72a7231

Browse files
committed
[WebAssembly] Mark @llvm.wasm.shuffle lane indices as immediates
This intrinsic is meant to lower directly to the i8x16.shuffle instruction, which takes its lane index arguments as immmediates. The ISel for the intrinsic assumed that the lane index arguments were constants, so bitcode that "incorrectly" used this intrinsic with non-immediate arguments caused an assertion failure in the backend. Avoid the crash by defining the lane index arguments to be immediates, matching the underlying instruction. Update ISel accordingly. This change means that the bitcode that previously caused a crash will now fail to validate. Fixes llvm#55559. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D149898
1 parent aea866c commit 72a7231

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

llvm/include/llvm/IR/IntrinsicsWebAssembly.td

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,15 @@ def int_wasm_shuffle :
175175
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
176176
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
177177
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
178-
[IntrNoMem, IntrSpeculatable]>;
178+
[IntrNoMem, IntrSpeculatable,
179+
ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>,
180+
ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>,
181+
ImmArg<ArgIndex<6>>, ImmArg<ArgIndex<7>>,
182+
ImmArg<ArgIndex<8>>, ImmArg<ArgIndex<9>>,
183+
ImmArg<ArgIndex<10>>, ImmArg<ArgIndex<11>>,
184+
ImmArg<ArgIndex<12>>, ImmArg<ArgIndex<13>>,
185+
ImmArg<ArgIndex<14>>, ImmArg<ArgIndex<15>>,
186+
ImmArg<ArgIndex<16>>, ImmArg<ArgIndex<17>>]>;
179187
def int_wasm_sub_sat_signed :
180188
DefaultAttrsIntrinsic<[llvm_anyvector_ty],
181189
[LLVMMatchType<0>, LLVMMatchType<0>],

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1823,7 +1823,8 @@ SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
18231823
const SDValue &MaskIdx = Op.getOperand(OpIdx + 1);
18241824
if (MaskIdx.isUndef() ||
18251825
cast<ConstantSDNode>(MaskIdx.getNode())->getZExtValue() >= 32) {
1826-
Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32);
1826+
bool isTarget = MaskIdx.getNode()->getOpcode() == ISD::TargetConstant;
1827+
Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32, isTarget);
18271828
} else {
18281829
Ops[OpIdx++] = MaskIdx;
18291830
}

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,22 @@ defm SHUFFLE :
529529
def wasm_shuffle_t : SDTypeProfile<1, 18, []>;
530530
def wasm_shuffle : SDNode<"WebAssemblyISD::SHUFFLE", wasm_shuffle_t>;
531531
foreach vec = AllVecs in {
532+
// The @llvm.wasm.shuffle intrinsic has immediate arguments that become TargetConstants.
533+
def : Pat<(vec.vt (wasm_shuffle (vec.vt V128:$x), (vec.vt V128:$y),
534+
(i32 timm:$m0), (i32 timm:$m1),
535+
(i32 timm:$m2), (i32 timm:$m3),
536+
(i32 timm:$m4), (i32 timm:$m5),
537+
(i32 timm:$m6), (i32 timm:$m7),
538+
(i32 timm:$m8), (i32 timm:$m9),
539+
(i32 timm:$mA), (i32 timm:$mB),
540+
(i32 timm:$mC), (i32 timm:$mD),
541+
(i32 timm:$mE), (i32 timm:$mF))),
542+
(SHUFFLE $x, $y,
543+
imm:$m0, imm:$m1, imm:$m2, imm:$m3,
544+
imm:$m4, imm:$m5, imm:$m6, imm:$m7,
545+
imm:$m8, imm:$m9, imm:$mA, imm:$mB,
546+
imm:$mC, imm:$mD, imm:$mE, imm:$mF)>;
547+
// Normal shufflevector instructions may have normal constant arguemnts.
532548
def : Pat<(vec.vt (wasm_shuffle (vec.vt V128:$x), (vec.vt V128:$y),
533549
(i32 LaneIdx32:$m0), (i32 LaneIdx32:$m1),
534550
(i32 LaneIdx32:$m2), (i32 LaneIdx32:$m3),

llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,29 +157,16 @@ define <16 x i8> @narrow_unsigned_v16i8(<8 x i16> %low, <8 x i16> %high) {
157157
; CHECK-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0{{$}}
158158
; CHECK-NEXT: return $pop[[R]]{{$}}
159159
declare <16 x i8> @llvm.wasm.shuffle(
160-
<16 x i8>, <16 x i8>, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
161-
i32, i32, i32, i32, i32)
160+
<16 x i8>, <16 x i8>, i32 immarg, i32 immarg, i32 immarg, i32 immarg,
161+
i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg,
162+
i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg)
162163
define <16 x i8> @shuffle_v16i8(<16 x i8> %x, <16 x i8> %y) {
163164
%res = call <16 x i8> @llvm.wasm.shuffle(<16 x i8> %x, <16 x i8> %y,
164165
i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
165166
i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 35)
166167
ret <16 x i8> %res
167168
}
168169

169-
; CHECK-LABEL: shuffle_undef_v16i8:
170-
; NO-CHECK-NOT: i8x16
171-
; CHECK-NEXT: .functype shuffle_undef_v16i8 (v128, v128) -> (v128){{$}}
172-
; CHECK-NEXT: i8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
173-
; CHECK-SAME: 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2{{$}}
174-
; CHECK-NEXT: return $pop[[R]]{{$}}
175-
define <16 x i8> @shuffle_undef_v16i8(<16 x i8> %x, <16 x i8> %y) {
176-
%res = call <16 x i8> @llvm.wasm.shuffle(<16 x i8> %x, <16 x i8> %y,
177-
i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef,
178-
i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef,
179-
i32 undef, i32 undef, i32 undef, i32 2)
180-
ret <16 x i8> %res
181-
}
182-
183170
; CHECK-LABEL: laneselect_v16i8:
184171
; CHECK-NEXT: .functype laneselect_v16i8 (v128, v128, v128) -> (v128){{$}}
185172
; CHECK-NEXT: i8x16.relaxed_laneselect $push[[R:[0-9]+]]=, $0, $1, $2{{$}}

0 commit comments

Comments
 (0)