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 @@ -971,6 +971,12 @@ def : Pat<(wasm_shr_u (v4i32 V128:$lhs), (and I32:$rhs, 31)), (SHR_U_I32x4 V128:$lhs, I32:$rhs)>; +def : Pat<(wasm_shl (v2i64 V128:$lhs), (and I32:$rhs, 63)), + (SHL_I64x2 V128:$lhs, I32:$rhs)>; +def : Pat<(wasm_shr_s (v2i64 V128:$lhs), (and I32:$rhs, 63)), + (SHR_S_I64x2 V128:$lhs, I32:$rhs)>; +def : Pat<(wasm_shr_u (v2i64 V128:$lhs), (and I32:$rhs, 63)), + (SHR_U_I64x2 V128:$lhs, I32:$rhs)>; def : Pat<(wasm_shl (v2i64 V128:$lhs), (trunc (and I64:$rhs, 63))), (SHL_I64x2 V128:$lhs, (I32_WRAP_I64 I64:$rhs))>; def : Pat<(wasm_shr_s (v2i64 V128:$lhs), (trunc (and I64:$rhs, 63))), diff --git a/llvm/test/CodeGen/WebAssembly/masked-shifts.ll b/llvm/test/CodeGen/WebAssembly/masked-shifts.ll --- a/llvm/test/CodeGen/WebAssembly/masked-shifts.ll +++ b/llvm/test/CodeGen/WebAssembly/masked-shifts.ll @@ -502,3 +502,52 @@ %a = lshr <2 x i64> %v, %m ret <2 x i64> %a } + +define <2 x i64> @shl_v2i64_i32(<2 x i64> %v, i32 %x) { +; CHECK-LABEL: shl_v2i64_i32: +; CHECK: .functype shl_v2i64_i32 (v128, i32) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i64x2.shl +; CHECK-NEXT: # fallthrough-return + %z = and i32 %x, 63 + %m = zext i32 %z to i64 + %t = insertelement <2 x i64> undef, i64 %m, i32 0 + %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> + %a = shl <2 x i64> %v, %s + ret <2 x i64> %a +} + +define <2 x i64> @ashr_v2i64_i32(<2 x i64> %v, i32 %x) { +; CHECK-LABEL: ashr_v2i64_i32: +; CHECK: .functype ashr_v2i64_i32 (v128, i32) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i64x2.shr_s +; CHECK-NEXT: # fallthrough-return + %z = and i32 %x, 63 + %m = zext i32 %z to i64 + %t = insertelement <2 x i64> undef, i64 %m, i32 0 + %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> + %a = ashr <2 x i64> %v, %s + ret <2 x i64> %a +} + +define <2 x i64> @lshr_v2i64_i32(<2 x i64> %v, i32 %x) { +; CHECK-LABEL: lshr_v2i64_i32: +; CHECK: .functype lshr_v2i64_i32 (v128, i32) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i64x2.shr_u +; CHECK-NEXT: # fallthrough-return + %z = and i32 %x, 63 + %m = zext i32 %z to i64 + %t = insertelement <2 x i64> undef, i64 %m, i32 0 + %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> + %a = lshr <2 x i64> %v, %s + ret <2 x i64> %a +} +