diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -175,7 +175,15 @@ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable]>; + [IntrNoMem, IntrSpeculatable, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>, + ImmArg>, ImmArg>]>; def int_wasm_sub_sat_signed : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>], diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -1823,7 +1823,8 @@ const SDValue &MaskIdx = Op.getOperand(OpIdx + 1); if (MaskIdx.isUndef() || cast(MaskIdx.getNode())->getZExtValue() >= 32) { - Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32); + bool isTarget = MaskIdx.getNode()->getOpcode() == ISD::TargetConstant; + Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32, isTarget); } else { Ops[OpIdx++] = MaskIdx; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -529,6 +529,22 @@ def wasm_shuffle_t : SDTypeProfile<1, 18, []>; def wasm_shuffle : SDNode<"WebAssemblyISD::SHUFFLE", wasm_shuffle_t>; foreach vec = AllVecs in { +// The @llvm.wasm.shuffle intrinsic has immediate arguments that become TargetConstants. +def : Pat<(vec.vt (wasm_shuffle (vec.vt V128:$x), (vec.vt V128:$y), + (i32 timm:$m0), (i32 timm:$m1), + (i32 timm:$m2), (i32 timm:$m3), + (i32 timm:$m4), (i32 timm:$m5), + (i32 timm:$m6), (i32 timm:$m7), + (i32 timm:$m8), (i32 timm:$m9), + (i32 timm:$mA), (i32 timm:$mB), + (i32 timm:$mC), (i32 timm:$mD), + (i32 timm:$mE), (i32 timm:$mF))), + (SHUFFLE $x, $y, + imm:$m0, imm:$m1, imm:$m2, imm:$m3, + imm:$m4, imm:$m5, imm:$m6, imm:$m7, + imm:$m8, imm:$m9, imm:$mA, imm:$mB, + imm:$mC, imm:$mD, imm:$mE, imm:$mF)>; +// Normal shufflevector instructions may have normal constant arguemnts. def : Pat<(vec.vt (wasm_shuffle (vec.vt V128:$x), (vec.vt V128:$y), (i32 LaneIdx32:$m0), (i32 LaneIdx32:$m1), (i32 LaneIdx32:$m2), (i32 LaneIdx32:$m3), diff --git a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll --- a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll @@ -157,8 +157,9 @@ ; CHECK-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} declare <16 x i8> @llvm.wasm.shuffle( - <16 x i8>, <16 x i8>, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, - i32, i32, i32, i32, i32) + <16 x i8>, <16 x i8>, i32 immarg, i32 immarg, i32 immarg, i32 immarg, + i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg, + i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg, i32 immarg) define <16 x i8> @shuffle_v16i8(<16 x i8> %x, <16 x i8> %y) { %res = call <16 x i8> @llvm.wasm.shuffle(<16 x i8> %x, <16 x i8> %y, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, @@ -166,20 +167,6 @@ ret <16 x i8> %res } -; CHECK-LABEL: shuffle_undef_v16i8: -; NO-CHECK-NOT: i8x16 -; CHECK-NEXT: .functype shuffle_undef_v16i8 (v128, v128) -> (v128){{$}} -; CHECK-NEXT: i8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, -; CHECK-SAME: 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2{{$}} -; CHECK-NEXT: return $pop[[R]]{{$}} -define <16 x i8> @shuffle_undef_v16i8(<16 x i8> %x, <16 x i8> %y) { - %res = call <16 x i8> @llvm.wasm.shuffle(<16 x i8> %x, <16 x i8> %y, - i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, - i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, - i32 undef, i32 undef, i32 undef, i32 2) - ret <16 x i8> %res -} - ; CHECK-LABEL: laneselect_v16i8: ; CHECK-NEXT: .functype laneselect_v16i8 (v128, v128, v128) -> (v128){{$}} ; CHECK-NEXT: i8x16.relaxed_laneselect $push[[R:[0-9]+]]=, $0, $1, $2{{$}}