defm SHR_S : SIMDShiftInt<sra, "shr_s", 85>;
defm SHR_U : SIMDShiftInt<srl, "shr_u", 86>;
-// Truncate i64 shift operands to i32s
-foreach shifts = [[shl, SHL_v2i64], [sra, SHR_S_v2i64], [srl, SHR_U_v2i64]] in
+// Truncate i64 shift operands to i32s, except if they are already i32s
+foreach shifts = [[shl, SHL_v2i64], [sra, SHR_S_v2i64], [srl, SHR_U_v2i64]] in {
+def : Pat<(v2i64 (shifts[0]
+ (v2i64 V128:$vec),
+ (v2i64 (splat2 (i64 (sext I32:$x))))
+ )),
+ (v2i64 (shifts[1] (v2i64 V128:$vec), (i32 I32:$x)))>;
def : Pat<(v2i64 (shifts[0] (v2i64 V128:$vec), (v2i64 (splat2 I64:$x)))),
(v2i64 (shifts[1] (v2i64 V128:$vec), (I32_WRAP_I64 I64:$x)))>;
+}
// 2xi64 shifts with constant shift amounts are custom lowered to avoid wrapping
def wasm_shift_t : SDTypeProfile<1, 2,
ret <2 x i64> %a
}
-; CHECK-LABEL: shl_nozext_v2i64:
+; CHECK-LABEL: shl_sext_v2i64:
; NO-SIMD128-NOT: i64x2
-; SIMD128-NEXT: .functype shl_nozext_v2i64 (v128, i64) -> (v128){{$}}
+; SIMD128-NEXT: .functype shl_sext_v2i64 (v128, i32) -> (v128){{$}}
+; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @shl_sext_v2i64(<2 x i64> %v, i32 %x) {
+ %x2 = sext i32 %x to i64
+ %t = insertelement <2 x i64> undef, i64 %x2, i32 0
+ %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+ %a = shl <2 x i64> %v, %s
+ ret <2 x i64> %a
+}
+
+; CHECK-LABEL: shl_noext_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-NEXT: .functype shl_noext_v2i64 (v128, i64) -> (v128){{$}}
; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
-define <2 x i64> @shl_nozext_v2i64(<2 x i64> %v, i64 %x) {
+define <2 x i64> @shl_noext_v2i64(<2 x i64> %v, i64 %x) {
%t = insertelement <2 x i64> undef, i64 %x, i32 0
%s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
%a = shl <2 x i64> %v, %s
ret <2 x i64> %a
}
-; CHECK-LABEL: shr_s_nozext_v2i64:
+; CHECK-LABEL: shr_s_sext_v2i64:
; NO-SIMD128-NOT: i64x2
-; SIMD128-NEXT: .functype shr_s_nozext_v2i64 (v128, i64) -> (v128){{$}}
+; SIMD128-NEXT: .functype shr_s_sext_v2i64 (v128, i32) -> (v128){{$}}
+; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @shr_s_sext_v2i64(<2 x i64> %v, i32 %x) {
+ %x2 = sext i32 %x to i64
+ %t = insertelement <2 x i64> undef, i64 %x2, i32 0
+ %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+ %a = ashr <2 x i64> %v, %s
+ ret <2 x i64> %a
+}
+
+; CHECK-LABEL: shr_s_noext_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-NEXT: .functype shr_s_noext_v2i64 (v128, i64) -> (v128){{$}}
; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
-define <2 x i64> @shr_s_nozext_v2i64(<2 x i64> %v, i64 %x) {
+define <2 x i64> @shr_s_noext_v2i64(<2 x i64> %v, i64 %x) {
%t = insertelement <2 x i64> undef, i64 %x, i32 0
%s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
%a = ashr <2 x i64> %v, %s
ret <2 x i64> %a
}
-; CHECK-LABEL: shr_u_nozext_v2i64:
+; CHECK-LABEL: shr_u_sext_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-NEXT: .functype shr_u_sext_v2i64 (v128, i32) -> (v128){{$}}
+; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @shr_u_sext_v2i64(<2 x i64> %v, i32 %x) {
+ %x2 = sext i32 %x to i64
+ %t = insertelement <2 x i64> undef, i64 %x2, i32 0
+ %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+ %a = lshr <2 x i64> %v, %s
+ ret <2 x i64> %a
+}
+
+; CHECK-LABEL: shr_u_noext_v2i64:
; NO-SIMD128-NOT: i64x2
-; SIMD128-NEXT: .functype shr_u_nozext_v2i64 (v128, i64) -> (v128){{$}}
+; SIMD128-NEXT: .functype shr_u_noext_v2i64 (v128, i64) -> (v128){{$}}
; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
-define <2 x i64> @shr_u_nozext_v2i64(<2 x i64> %v, i64 %x) {
+define <2 x i64> @shr_u_noext_v2i64(<2 x i64> %v, i64 %x) {
%t = insertelement <2 x i64> undef, i64 %x, i32 0
%s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
%a = lshr <2 x i64> %v, %s