diff --git a/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 4c8dd53702b..1bd1d2964dd 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -738,12 +738,31 @@ defm MAX_S : SIMDBinaryIntNoI64x2; defm MAX_U : SIMDBinaryIntNoI64x2; } // isCommutable = 1 +// Integer unsigned rounding average: avgr_u +def avgr_u_v16i8 : + PatFrag<(ops node:$lhs, node:$rhs), + (srl + (add (add node:$lhs, node:$rhs), (splat16 (i32 1))), + (v16i8 (splat16 (i32 1))) + )>; +def avgr_u_v8i16 : + PatFrag<(ops node:$lhs, node:$rhs), + (srl + (add (add node:$lhs, node:$rhs), (splat8 (i32 1))), + (v8i16 (splat8 (i32 1))) + )>; + +let isCommutable = 1, Predicates = [HasUnimplementedSIMD128] in { +defm AVGR_U : SIMDBinary; +defm AVGR_U : SIMDBinary; +} + // Widening dot product: i32x4.dot_i16x8_s let isCommutable = 1 in defm DOT : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs), (outs), (ins), [(set V128:$dst, (int_wasm_dot V128:$lhs, V128:$rhs))], "i32x4.dot_i16x8_s\t$dst, $lhs, $rhs", "i32x4.dot_i16x8_s", - 217>; + 219>; //===----------------------------------------------------------------------===// // Floating-point unary arithmetic diff --git a/test/CodeGen/WebAssembly/simd-arith.ll b/test/CodeGen/WebAssembly/simd-arith.ll index f087249534d..aa19e1e12ec 100644 --- a/test/CodeGen/WebAssembly/simd-arith.ll +++ b/test/CodeGen/WebAssembly/simd-arith.ll @@ -91,6 +91,20 @@ define <16 x i8> @max_u_v16i8(<16 x i8> %x, <16 x i8> %y) { ret <16 x i8> %a } +; CHECK-LABEL: avgr_u_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128-NEXT: .functype avgr_u_v16i8 (v128, v128) -> (v128){{$}} +; SIMD128-NEXT: i8x16.avgr_u $push[[R:[0-9]+]]=, $0, $1{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +define <16 x i8> @avgr_u_v16i8(<16 x i8> %x, <16 x i8> %y) { + %a = add <16 x i8> %x, %y + %b = add <16 x i8> %a, + %c = udiv <16 x i8> %b, + ret <16 x i8> %c +} + ; CHECK-LABEL: neg_v16i8: ; NO-SIMD128-NOT: i8x16 ; SIMD128-NEXT: .functype neg_v16i8 (v128) -> (v128){{$}} @@ -381,6 +395,18 @@ define <8 x i16> @max_u_v8i16(<8 x i16> %x, <8 x i16> %y) { ret <8 x i16> %a } +; CHECK-LABEL: avgr_u_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128-NEXT: .functype avgr_u_v8i16 (v128, v128) -> (v128){{$}} +; SIMD128-NEXT: i16x8.avgr_u $push[[R:[0-9]+]]=, $0, $1{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +define <8 x i16> @avgr_u_v8i16(<8 x i16> %x, <8 x i16> %y) { + %a = add <8 x i16> %x, %y + %b = add <8 x i16> %a, + %c = udiv <8 x i16> %b, + ret <8 x i16> %c +} + ; CHECK-LABEL: neg_v8i16: ; NO-SIMD128-NOT: i16x8 ; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}} diff --git a/test/MC/WebAssembly/simd-encodings.s b/test/MC/WebAssembly/simd-encodings.s index e1cb5feae34..e40de533547 100644 --- a/test/MC/WebAssembly/simd-encodings.s +++ b/test/MC/WebAssembly/simd-encodings.s @@ -571,7 +571,13 @@ main: # CHECK: v128.andnot # encoding: [0xfd,0xd8,0x01] v128.andnot - # CHECK: i32x4.dot_i16x8_s # encoding: [0xfd,0xd9,0x01] + # CHECK: i8x16.avgr_u # encoding: [0xfd,0xd9,0x01] + i8x16.avgr_u + + # CHECK: i16x8.avgr_u # encoding: [0xfd,0xda,0x01] + i16x8.avgr_u + + # CHECK: i32x4.dot_i16x8_s # encoding: [0xfd,0xdb,0x01] i32x4.dot_i16x8_s end_function