blob: 25dc1efedfb9509db1e473e5ea8a4b8f147b09fb [file] [log] [blame] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple=wasm32 -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s
define <8 x i32> @sext_mul_v8i8(<8 x i8> %a, <8 x i8> %b) {
; CHECK-LABEL: sext_mul_v8i8:
; CHECK: .functype sext_mul_v8i8 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extmul_low_i8x16_s $push3=, $1, $1
; CHECK-NEXT: local.tee $push2=, $1=, $pop3
; CHECK-NEXT: i32x4.extend_high_i16x8_s $push0=, $pop2
; CHECK-NEXT: v128.store 16($0), $pop0
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push1=, $1
; CHECK-NEXT: v128.store 0($0), $pop1
; CHECK-NEXT: return
%wide.a = sext <8 x i8> %a to <8 x i32>
%wide.b = sext <8 x i8> %a to <8 x i32>
%mul = mul <8 x i32> %wide.a, %wide.b
ret <8 x i32> %mul
}
define <16 x i32> @sext_mul_v16i8(<16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: sext_mul_v16i8:
; CHECK: .functype sext_mul_v16i8 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extmul_high_i8x16_s $push7=, $1, $1
; CHECK-NEXT: local.tee $push6=, $3=, $pop7
; CHECK-NEXT: i32x4.extend_high_i16x8_s $push0=, $pop6
; CHECK-NEXT: v128.store 48($0), $pop0
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push1=, $3
; CHECK-NEXT: v128.store 32($0), $pop1
; CHECK-NEXT: i16x8.extmul_low_i8x16_s $push5=, $1, $1
; CHECK-NEXT: local.tee $push4=, $1=, $pop5
; CHECK-NEXT: i32x4.extend_high_i16x8_s $push2=, $pop4
; CHECK-NEXT: v128.store 16($0), $pop2
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push3=, $1
; CHECK-NEXT: v128.store 0($0), $pop3
; CHECK-NEXT: return
%wide.a = sext <16 x i8> %a to <16 x i32>
%wide.b = sext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %wide.a, %wide.b
ret <16 x i32> %mul
}
define <8 x i32> @sext_mul_v8i16(<8 x i16> %a, <8 x i16> %b) {
; CHECK-LABEL: sext_mul_v8i16:
; CHECK: .functype sext_mul_v8i16 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32x4.extmul_high_i16x8_s $push0=, $1, $1
; CHECK-NEXT: v128.store 16($0), $pop0
; CHECK-NEXT: i32x4.extmul_low_i16x8_s $push1=, $1, $1
; CHECK-NEXT: v128.store 0($0), $pop1
; CHECK-NEXT: return
%wide.a = sext <8 x i16> %a to <8 x i32>
%wide.b = sext <8 x i16> %a to <8 x i32>
%mul = mul <8 x i32> %wide.a, %wide.b
ret <8 x i32> %mul
}
define <8 x i32> @zext_mul_v8i8(<8 x i8> %a, <8 x i8> %b) {
; CHECK-LABEL: zext_mul_v8i8:
; CHECK: .functype zext_mul_v8i8 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extmul_low_i8x16_u $push3=, $1, $1
; CHECK-NEXT: local.tee $push2=, $1=, $pop3
; CHECK-NEXT: i32x4.extend_high_i16x8_u $push0=, $pop2
; CHECK-NEXT: v128.store 16($0), $pop0
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push1=, $1
; CHECK-NEXT: v128.store 0($0), $pop1
; CHECK-NEXT: return
%wide.a = zext <8 x i8> %a to <8 x i32>
%wide.b = zext <8 x i8> %a to <8 x i32>
%mul = mul <8 x i32> %wide.a, %wide.b
ret <8 x i32> %mul
}
define <16 x i32> @zext_mul_v16i8(<16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: zext_mul_v16i8:
; CHECK: .functype zext_mul_v16i8 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extmul_high_i8x16_u $push7=, $1, $1
; CHECK-NEXT: local.tee $push6=, $3=, $pop7
; CHECK-NEXT: i32x4.extend_high_i16x8_u $push0=, $pop6
; CHECK-NEXT: v128.store 48($0), $pop0
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push1=, $3
; CHECK-NEXT: v128.store 32($0), $pop1
; CHECK-NEXT: i16x8.extmul_low_i8x16_u $push5=, $1, $1
; CHECK-NEXT: local.tee $push4=, $1=, $pop5
; CHECK-NEXT: i32x4.extend_high_i16x8_u $push2=, $pop4
; CHECK-NEXT: v128.store 16($0), $pop2
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push3=, $1
; CHECK-NEXT: v128.store 0($0), $pop3
; CHECK-NEXT: return
%wide.a = zext <16 x i8> %a to <16 x i32>
%wide.b = zext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %wide.a, %wide.b
ret <16 x i32> %mul
}
define <8 x i32> @zext_mul_v8i16(<8 x i16> %a, <8 x i16> %b) {
; CHECK-LABEL: zext_mul_v8i16:
; CHECK: .functype zext_mul_v8i16 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32x4.extmul_high_i16x8_u $push0=, $1, $1
; CHECK-NEXT: v128.store 16($0), $pop0
; CHECK-NEXT: i32x4.extmul_low_i16x8_u $push1=, $1, $1
; CHECK-NEXT: v128.store 0($0), $pop1
; CHECK-NEXT: return
%wide.a = zext <8 x i16> %a to <8 x i32>
%wide.b = zext <8 x i16> %a to <8 x i32>
%mul = mul <8 x i32> %wide.a, %wide.b
ret <8 x i32> %mul
}
define <8 x i32> @sext_zext_mul_v8i8(<8 x i8> %a, <8 x i8> %b) {
; CHECK-LABEL: sext_zext_mul_v8i8:
; CHECK: .functype sext_zext_mul_v8i8 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push2=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push3=, $pop2
; CHECK-NEXT: i16x8.extend_low_i8x16_u $push0=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push1=, $pop0
; CHECK-NEXT: i32x4.mul $push4=, $pop3, $pop1
; CHECK-NEXT: v128.store 0($0), $pop4
; CHECK-NEXT: i8x16.shuffle $push11=, $1, $1, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.tee $push10=, $1=, $pop11
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push7=, $pop10
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push8=, $pop7
; CHECK-NEXT: i16x8.extend_low_i8x16_u $push5=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push6=, $pop5
; CHECK-NEXT: i32x4.mul $push9=, $pop8, $pop6
; CHECK-NEXT: v128.store 16($0), $pop9
; CHECK-NEXT: return
%wide.a = sext <8 x i8> %a to <8 x i32>
%wide.b = zext <8 x i8> %a to <8 x i32>
%mul = mul <8 x i32> %wide.a, %wide.b
ret <8 x i32> %mul
}
define <16 x i32> @sext_zext_mul_v16i8(<16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: sext_zext_mul_v16i8:
; CHECK: .functype sext_zext_mul_v16i8 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push2=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push3=, $pop2
; CHECK-NEXT: i16x8.extend_low_i8x16_u $push0=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push1=, $pop0
; CHECK-NEXT: i32x4.mul $push4=, $pop3, $pop1
; CHECK-NEXT: v128.store 0($0), $pop4
; CHECK-NEXT: i8x16.shuffle $push25=, $1, $1, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.tee $push24=, $3=, $pop25
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push7=, $pop24
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push8=, $pop7
; CHECK-NEXT: i16x8.extend_low_i8x16_u $push5=, $3
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push6=, $pop5
; CHECK-NEXT: i32x4.mul $push9=, $pop8, $pop6
; CHECK-NEXT: v128.store 48($0), $pop9
; CHECK-NEXT: i8x16.shuffle $push23=, $1, $1, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.tee $push22=, $3=, $pop23
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push12=, $pop22
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push13=, $pop12
; CHECK-NEXT: i16x8.extend_low_i8x16_u $push10=, $3
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push11=, $pop10
; CHECK-NEXT: i32x4.mul $push14=, $pop13, $pop11
; CHECK-NEXT: v128.store 32($0), $pop14
; CHECK-NEXT: i8x16.shuffle $push21=, $1, $1, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.tee $push20=, $1=, $pop21
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push17=, $pop20
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push18=, $pop17
; CHECK-NEXT: i16x8.extend_low_i8x16_u $push15=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push16=, $pop15
; CHECK-NEXT: i32x4.mul $push19=, $pop18, $pop16
; CHECK-NEXT: v128.store 16($0), $pop19
; CHECK-NEXT: return
%wide.a = sext <16 x i8> %a to <16 x i32>
%wide.b = zext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %wide.a, %wide.b
ret <16 x i32> %mul
}
define <8 x i32> @zext_sext_mul_v8i16(<8 x i16> %a, <8 x i16> %b) {
; CHECK-LABEL: zext_sext_mul_v8i16:
; CHECK: .functype zext_sext_mul_v8i16 (i32, v128, v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32x4.extend_high_i16x8_u $push1=, $1
; CHECK-NEXT: i32x4.extend_high_i16x8_s $push0=, $1
; CHECK-NEXT: i32x4.mul $push2=, $pop1, $pop0
; CHECK-NEXT: v128.store 16($0), $pop2
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push4=, $1
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push3=, $1
; CHECK-NEXT: i32x4.mul $push5=, $pop4, $pop3
; CHECK-NEXT: v128.store 0($0), $pop5
; CHECK-NEXT: return
%wide.a = zext <8 x i16> %a to <8 x i32>
%wide.b = sext <8 x i16> %a to <8 x i32>
%mul = mul <8 x i32> %wide.a, %wide.b
ret <8 x i32> %mul
}
define <4 x i32> @sext_mul_v8i16_with_symmetric_constant_vector(<8 x i16> %v) {
; CHECK-LABEL: sext_mul_v8i16_with_symmetric_constant_vector:
; CHECK: .functype sext_mul_v8i16_with_symmetric_constant_vector (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const $push0=, 4096, 1, 4096, 1, 4096, 1, 4096, 1
; CHECK-NEXT: i32x4.dot_i16x8_s $push1=, $0, $pop0
; CHECK-NEXT: return $pop1
%sext = sext <8 x i16> %v to <8 x i32>
%1 = mul nsw <8 x i32> %sext, <i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1>
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %2, %3
ret <4 x i32> %4
}
define <4 x i32> @sext_mul_v8i16_with_symmetric_constant_vector_comm(<8 x i16> %v) {
; CHECK-LABEL: sext_mul_v8i16_with_symmetric_constant_vector_comm:
; CHECK: .functype sext_mul_v8i16_with_symmetric_constant_vector_comm (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const $push0=, 4096, 1, 4096, 1, 4096, 1, 4096, 1
; CHECK-NEXT: i32x4.dot_i16x8_s $push1=, $0, $pop0
; CHECK-NEXT: return $pop1
%sext = sext <8 x i16> %v to <8 x i32>
%1 = mul nsw <8 x i32> <i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1>, %sext
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %3, %2
ret <4 x i32> %4
}
define <4 x i32> @sext_mul_v8i16_with_constant(<8 x i16> %v) {
; CHECK-LABEL: sext_mul_v8i16_with_constant:
; CHECK: .functype sext_mul_v8i16_with_constant (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const $push0=, 4096, 1, 4096, 1, 4096, 1, 4096, 1
; CHECK-NEXT: i32x4.dot_i16x8_s $push1=, $0, $pop0
; CHECK-NEXT: return $pop1
%sext = sext <8 x i16> %v to <8 x i32>
%1 = mul nsw <8 x i32> %sext, <i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1>
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %2, %3
ret <4 x i32> %4
}
define <4 x i32> @sext_mul_v8i16_with_constant_comm(<8 x i16> %v) {
; CHECK-LABEL: sext_mul_v8i16_with_constant_comm:
; CHECK: .functype sext_mul_v8i16_with_constant_comm (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const $push0=, 4096, 1, 4096, 1, 4096, 1, 4096, 1
; CHECK-NEXT: i32x4.dot_i16x8_s $push1=, $0, $pop0
; CHECK-NEXT: return $pop1
%sext = sext <8 x i16> %v to <8 x i32>
%1 = mul nsw <8 x i32> <i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1, i32 4096, i32 1>, %sext
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %3, %2
ret <4 x i32> %4
}
; Negative - unsupported type
define <4 x i32> @sext_mul_v8i1_pow2(<8 x i1> %v) {
; CHECK-LABEL: sext_mul_v8i1_pow2:
; CHECK: .functype sext_mul_v8i1_pow2 (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push3=, $0
; CHECK-NEXT: i32.const $push1=, 31
; CHECK-NEXT: i32x4.shl $push4=, $pop3, $pop1
; CHECK-NEXT: i32.const $push14=, 31
; CHECK-NEXT: i32x4.shr_s $push13=, $pop4, $pop14
; CHECK-NEXT: local.tee $push12=, $1=, $pop13
; CHECK-NEXT: i32x4.extend_high_i16x8_u $push0=, $0
; CHECK-NEXT: i32.const $push11=, 31
; CHECK-NEXT: i32x4.shl $push2=, $pop0, $pop11
; CHECK-NEXT: i32.const $push10=, 31
; CHECK-NEXT: i32x4.shr_s $push9=, $pop2, $pop10
; CHECK-NEXT: local.tee $push8=, $0=, $pop9
; CHECK-NEXT: i8x16.shuffle $push6=, $pop12, $pop8, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
; CHECK-NEXT: i8x16.shuffle $push5=, $1, $0, 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
; CHECK-NEXT: i32x4.add $push7=, $pop6, $pop5
; CHECK-NEXT: return $pop7
%sext = sext <8 x i1> %v to <8 x i32>
%1 = mul nsw <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, %sext
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %3, %2
ret <4 x i32> %4
}
; Negative - unsupported type
define <4 x i32> @sext_mul_v8i8_pow2(<8 x i8> %v) {
; CHECK-LABEL: sext_mul_v8i8_pow2:
; CHECK: .functype sext_mul_v8i8_pow2 (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push17=, $0
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push18=, $pop17
; CHECK-NEXT: v128.const $push19=, 0, 1, 2, 4
; CHECK-NEXT: i32x4.mul $push28=, $pop18, $pop19
; CHECK-NEXT: local.tee $push27=, $1=, $pop28
; CHECK-NEXT: i8x16.shuffle $push0=, $0, $0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: i16x8.extend_low_i8x16_s $push1=, $pop0
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push26=, $pop1
; CHECK-NEXT: local.tee $push25=, $0=, $pop26
; CHECK-NEXT: i32x4.extract_lane $push5=, $pop25, 0
; CHECK-NEXT: i32.const $push6=, 3
; CHECK-NEXT: i32.shl $push7=, $pop5, $pop6
; CHECK-NEXT: i32x4.splat $push8=, $pop7
; CHECK-NEXT: i32x4.extract_lane $push2=, $0, 1
; CHECK-NEXT: i32.const $push3=, 4
; CHECK-NEXT: i32.shl $push4=, $pop2, $pop3
; CHECK-NEXT: i32x4.replace_lane $push9=, $pop8, 1, $pop4
; CHECK-NEXT: i32x4.extract_lane $push10=, $0, 2
; CHECK-NEXT: i32.const $push11=, 5
; CHECK-NEXT: i32.shl $push12=, $pop10, $pop11
; CHECK-NEXT: i32x4.replace_lane $push13=, $pop9, 2, $pop12
; CHECK-NEXT: i32x4.extract_lane $push14=, $0, 3
; CHECK-NEXT: i32.const $push15=, 6
; CHECK-NEXT: i32.shl $push16=, $pop14, $pop15
; CHECK-NEXT: i32x4.replace_lane $push24=, $pop13, 3, $pop16
; CHECK-NEXT: local.tee $push23=, $0=, $pop24
; CHECK-NEXT: i8x16.shuffle $push21=, $pop27, $pop23, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
; CHECK-NEXT: i8x16.shuffle $push20=, $1, $0, 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
; CHECK-NEXT: i32x4.add $push22=, $pop21, $pop20
; CHECK-NEXT: return $pop22
%sext = sext <8 x i8> %v to <8 x i32>
%1 = mul nsw <8 x i32> <i32 0, i32 1, i32 2, i32 4, i32 8, i32 16, i32 32, i32 64>, %sext
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %3, %2
ret <4 x i32> %4
}
; Negative - shifts by 15 overflow
define <4 x i32> @combine_with_shl_signed_non_overflow(<8 x i16> %v) {
; CHECK-LABEL: combine_with_shl_signed_non_overflow:
; CHECK: .functype combine_with_shl_signed_non_overflow (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32x4.extend_low_i16x8_s $push24=, $0
; CHECK-NEXT: local.tee $push23=, $1=, $pop24
; CHECK-NEXT: i32x4.extract_lane $push8=, $1, 1
; CHECK-NEXT: i32.const $push1=, 15
; CHECK-NEXT: i32.shl $push9=, $pop8, $pop1
; CHECK-NEXT: i32x4.replace_lane $push10=, $pop23, 1, $pop9
; CHECK-NEXT: i32x4.extract_lane $push6=, $1, 3
; CHECK-NEXT: i32.const $push22=, 15
; CHECK-NEXT: i32.shl $push7=, $pop6, $pop22
; CHECK-NEXT: i32x4.replace_lane $push21=, $pop10, 3, $pop7
; CHECK-NEXT: local.tee $push20=, $1=, $pop21
; CHECK-NEXT: i32x4.extend_high_i16x8_s $push19=, $0
; CHECK-NEXT: local.tee $push18=, $0=, $pop19
; CHECK-NEXT: i32x4.extract_lane $push3=, $0, 1
; CHECK-NEXT: i32.const $push17=, 15
; CHECK-NEXT: i32.shl $push4=, $pop3, $pop17
; CHECK-NEXT: i32x4.replace_lane $push5=, $pop18, 1, $pop4
; CHECK-NEXT: i32x4.extract_lane $push0=, $0, 3
; CHECK-NEXT: i32.const $push16=, 15
; CHECK-NEXT: i32.shl $push2=, $pop0, $pop16
; CHECK-NEXT: i32x4.replace_lane $push15=, $pop5, 3, $pop2
; CHECK-NEXT: local.tee $push14=, $0=, $pop15
; CHECK-NEXT: i8x16.shuffle $push12=, $pop20, $pop14, 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
; CHECK-NEXT: i8x16.shuffle $push11=, $1, $0, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
; CHECK-NEXT: i32x4.add $push13=, $pop12, $pop11
; CHECK-NEXT: return $pop13
%sext = sext <8 x i16> %v to <8 x i32>
%1 = mul <8 x i32> %sext, <i32 1, i32 32768, i32 1, i32 32768, i32 1, i32 32768, i32 1, i32 32768>
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %2, %3
ret <4 x i32> %4
}
; Negative - shifts by 16 overflow
define <4 x i32> @combine_with_shl_unsigned_non_overflow(<8 x i16> %v) {
; CHECK-LABEL: combine_with_shl_unsigned_non_overflow:
; CHECK: .functype combine_with_shl_unsigned_non_overflow (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32x4.extend_low_i16x8_u $push24=, $0
; CHECK-NEXT: local.tee $push23=, $1=, $pop24
; CHECK-NEXT: i32x4.extract_lane $push8=, $1, 1
; CHECK-NEXT: i32.const $push1=, 16
; CHECK-NEXT: i32.shl $push9=, $pop8, $pop1
; CHECK-NEXT: i32x4.replace_lane $push10=, $pop23, 1, $pop9
; CHECK-NEXT: i32x4.extract_lane $push6=, $1, 3
; CHECK-NEXT: i32.const $push22=, 16
; CHECK-NEXT: i32.shl $push7=, $pop6, $pop22
; CHECK-NEXT: i32x4.replace_lane $push21=, $pop10, 3, $pop7
; CHECK-NEXT: local.tee $push20=, $1=, $pop21
; CHECK-NEXT: i32x4.extend_high_i16x8_u $push19=, $0
; CHECK-NEXT: local.tee $push18=, $0=, $pop19
; CHECK-NEXT: i32x4.extract_lane $push3=, $0, 1
; CHECK-NEXT: i32.const $push17=, 16
; CHECK-NEXT: i32.shl $push4=, $pop3, $pop17
; CHECK-NEXT: i32x4.replace_lane $push5=, $pop18, 1, $pop4
; CHECK-NEXT: i32x4.extract_lane $push0=, $0, 3
; CHECK-NEXT: i32.const $push16=, 16
; CHECK-NEXT: i32.shl $push2=, $pop0, $pop16
; CHECK-NEXT: i32x4.replace_lane $push15=, $pop5, 3, $pop2
; CHECK-NEXT: local.tee $push14=, $0=, $pop15
; CHECK-NEXT: i8x16.shuffle $push12=, $pop20, $pop14, 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
; CHECK-NEXT: i8x16.shuffle $push11=, $1, $0, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
; CHECK-NEXT: v128.or $push13=, $pop12, $pop11
; CHECK-NEXT: return $pop13
%zext = zext <8 x i16> %v to <8 x i32>
%1 = mul <8 x i32> %zext, <i32 1, i32 65536, i32 1, i32 65536, i32 1, i32 65536, i32 1, i32 65536>
%2 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%3 = shufflevector <8 x i32> %1, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%4 = add <4 x i32> %2, %3
ret <4 x i32> %4
}