Skip to content

Commit f1b351e

Browse files
committed
[WebAssembly] Implement SIMD {i8x16,i16x8}.avgr_u instructions
Summary: These instructions were added to the spec proposal in WebAssembly/simd#126. Their semantics are equivalent to `(a + b + 1) / 2`. The opcode for the experimental i32x4.dot_i16x8_s is also bumped due to a collision with the i8x16.avgr_u opcode. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71628
1 parent f827aff commit f1b351e

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,12 +738,31 @@ defm MAX_S : SIMDBinaryIntNoI64x2<smax, "max_s", 96>;
738738
defm MAX_U : SIMDBinaryIntNoI64x2<umax, "max_u", 97>;
739739
} // isCommutable = 1
740740

741+
// Integer unsigned rounding average: avgr_u
742+
def avgr_u_v16i8 :
743+
PatFrag<(ops node:$lhs, node:$rhs),
744+
(srl
745+
(add (add node:$lhs, node:$rhs), (splat16 (i32 1))),
746+
(v16i8 (splat16 (i32 1)))
747+
)>;
748+
def avgr_u_v8i16 :
749+
PatFrag<(ops node:$lhs, node:$rhs),
750+
(srl
751+
(add (add node:$lhs, node:$rhs), (splat8 (i32 1))),
752+
(v8i16 (splat8 (i32 1)))
753+
)>;
754+
755+
let isCommutable = 1, Predicates = [HasUnimplementedSIMD128] in {
756+
defm AVGR_U : SIMDBinary<v16i8, "i8x16", avgr_u_v16i8, "avgr_u", 217>;
757+
defm AVGR_U : SIMDBinary<v8i16, "i16x8", avgr_u_v8i16, "avgr_u", 218>;
758+
}
759+
741760
// Widening dot product: i32x4.dot_i16x8_s
742761
let isCommutable = 1 in
743762
defm DOT : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs), (outs), (ins),
744763
[(set V128:$dst, (int_wasm_dot V128:$lhs, V128:$rhs))],
745764
"i32x4.dot_i16x8_s\t$dst, $lhs, $rhs", "i32x4.dot_i16x8_s",
746-
217>;
765+
219>;
747766

748767
//===----------------------------------------------------------------------===//
749768
// Floating-point unary arithmetic

llvm/test/CodeGen/WebAssembly/simd-arith.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,20 @@ define <16 x i8> @max_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
9191
ret <16 x i8> %a
9292
}
9393

94+
; CHECK-LABEL: avgr_u_v16i8:
95+
; NO-SIMD128-NOT: i8x16
96+
; SIMD128-NEXT: .functype avgr_u_v16i8 (v128, v128) -> (v128){{$}}
97+
; SIMD128-NEXT: i8x16.avgr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
98+
; SIMD128-NEXT: return $pop[[R]]{{$}}
99+
define <16 x i8> @avgr_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
100+
%a = add <16 x i8> %x, %y
101+
%b = add <16 x i8> %a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1,
102+
i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
103+
%c = udiv <16 x i8> %b, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2,
104+
i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2>
105+
ret <16 x i8> %c
106+
}
107+
94108
; CHECK-LABEL: neg_v16i8:
95109
; NO-SIMD128-NOT: i8x16
96110
; 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) {
381395
ret <8 x i16> %a
382396
}
383397

398+
; CHECK-LABEL: avgr_u_v8i16:
399+
; NO-SIMD128-NOT: i16x8
400+
; SIMD128-NEXT: .functype avgr_u_v8i16 (v128, v128) -> (v128){{$}}
401+
; SIMD128-NEXT: i16x8.avgr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
402+
; SIMD128-NEXT: return $pop[[R]]{{$}}
403+
define <8 x i16> @avgr_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
404+
%a = add <8 x i16> %x, %y
405+
%b = add <8 x i16> %a, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
406+
%c = udiv <8 x i16> %b, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>
407+
ret <8 x i16> %c
408+
}
409+
384410
; CHECK-LABEL: neg_v8i16:
385411
; NO-SIMD128-NOT: i16x8
386412
; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}}

llvm/test/MC/WebAssembly/simd-encodings.s

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,13 @@ main:
571571
# CHECK: v128.andnot # encoding: [0xfd,0xd8,0x01]
572572
v128.andnot
573573

574-
# CHECK: i32x4.dot_i16x8_s # encoding: [0xfd,0xd9,0x01]
574+
# CHECK: i8x16.avgr_u # encoding: [0xfd,0xd9,0x01]
575+
i8x16.avgr_u
576+
577+
# CHECK: i16x8.avgr_u # encoding: [0xfd,0xda,0x01]
578+
i16x8.avgr_u
579+
580+
# CHECK: i32x4.dot_i16x8_s # encoding: [0xfd,0xdb,0x01]
575581
i32x4.dot_i16x8_s
576582

577583
end_function

0 commit comments

Comments
 (0)