Skip to content

Commit 8cea7ba

Browse files
brendandahlAlexisPerry
authored andcommitted
[WebAssembly] Implement trunc_sat and convert instructions for f16x8. (llvm#95180)
These instructions can be generated using regular LL intrinsics. Specified at: https://github.com/WebAssembly/half-precision/blob/29a9b9462c9285d4ccc1a5dc39214ddfd1892658/proposals/half-precision/Overview.md
1 parent 7c30aae commit 8cea7ba

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,16 +1320,23 @@ def : Pat<(v8f16 (int_wasm_pmax (v8f16 V128:$lhs), (v8f16 V128:$rhs))),
13201320
//===----------------------------------------------------------------------===//
13211321

13221322
multiclass SIMDConvert<Vec vec, Vec arg, SDPatternOperator op, string name,
1323-
bits<32> simdop> {
1323+
bits<32> simdop, list<Predicate> reqs = []> {
13241324
defm op#_#vec :
13251325
SIMD_I<(outs V128:$dst), (ins V128:$vec), (outs), (ins),
13261326
[(set (vec.vt V128:$dst), (vec.vt (op (arg.vt V128:$vec))))],
1327-
vec.prefix#"."#name#"\t$dst, $vec", vec.prefix#"."#name, simdop>;
1327+
vec.prefix#"."#name#"\t$dst, $vec", vec.prefix#"."#name, simdop, reqs>;
1328+
}
1329+
1330+
multiclass HalfPrecisionConvert<Vec vec, Vec arg, SDPatternOperator op,
1331+
string name, bits<32> simdop> {
1332+
defm "" : SIMDConvert<vec, arg, op, name, simdop, [HasHalfPrecision]>;
13281333
}
13291334

13301335
// Floating point to integer with saturation: trunc_sat
13311336
defm "" : SIMDConvert<I32x4, F32x4, fp_to_sint, "trunc_sat_f32x4_s", 248>;
13321337
defm "" : SIMDConvert<I32x4, F32x4, fp_to_uint, "trunc_sat_f32x4_u", 249>;
1338+
defm "" : HalfPrecisionConvert<I16x8, F16x8, fp_to_sint, "trunc_sat_f16x8_s", 0x148>;
1339+
defm "" : HalfPrecisionConvert<I16x8, F16x8, fp_to_uint, "trunc_sat_f16x8_u", 0x149>;
13331340

13341341
// Support the saturating variety as well.
13351342
def trunc_s_sat32 : PatFrag<(ops node:$x), (fp_to_sint_sat $x, i32)>;
@@ -1355,6 +1362,8 @@ defm "" : SIMDConvert<F32x4, I32x4, sint_to_fp, "convert_i32x4_s", 250>;
13551362
defm "" : SIMDConvert<F32x4, I32x4, uint_to_fp, "convert_i32x4_u", 251>;
13561363
defm "" : SIMDConvert<F64x2, I32x4, convert_low_s, "convert_low_i32x4_s", 0xfe>;
13571364
defm "" : SIMDConvert<F64x2, I32x4, convert_low_u, "convert_low_i32x4_u", 0xff>;
1365+
defm "" : HalfPrecisionConvert<F16x8, I16x8, sint_to_fp, "convert_i16x8_s", 0x14a>;
1366+
defm "" : HalfPrecisionConvert<F16x8, I16x8, uint_to_fp, "convert_i16x8_u", 0x14b>;
13581367

13591368
// Extending operations
13601369
// TODO: refactor this to be uniform for i64x2 if the numbering is not changed.

llvm/test/CodeGen/WebAssembly/half-precision.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,39 @@ define <8 x half> @nearest_v8f16_via_roundeven(<8 x half> %a) {
246246
%v = call <8 x half> @llvm.roundeven.v8f16(<8 x half> %a)
247247
ret <8 x half> %v
248248
}
249+
250+
define <8 x half> @convert_s_v8f16(<8 x i16> %x) {
251+
; CHECK-LABEL: convert_s_v8f16:
252+
; CHECK: .functype convert_s_v8f16 (v128) -> (v128)
253+
; CHECK-NEXT: f16x8.convert_i16x8_s $push0=, $0
254+
; CHECK-NEXT: return $pop[[R]]{{$}}
255+
%a = sitofp <8 x i16> %x to <8 x half>
256+
ret <8 x half> %a
257+
}
258+
259+
define <8 x half> @convert_u_v8f16(<8 x i16> %x) {
260+
; CHECK-LABEL: convert_u_v8f16:
261+
; CHECK: .functype convert_u_v8f16 (v128) -> (v128)
262+
; CHECK-NEXT: f16x8.convert_i16x8_u $push0=, $0
263+
; CHECK-NEXT: return $pop[[R]]{{$}}
264+
%a = uitofp <8 x i16> %x to <8 x half>
265+
ret <8 x half> %a
266+
}
267+
268+
define <8 x i16> @trunc_sat_s_v8i16(<8 x half> %x) {
269+
; CHECK-LABEL: trunc_sat_s_v8i16:
270+
; CHECK: .functype trunc_sat_s_v8i16 (v128) -> (v128)
271+
; CHECK-NEXT: i16x8.trunc_sat_f16x8_s $push0=, $0
272+
; CHECK-NEXT: return $pop[[R]]{{$}}
273+
%a = fptosi <8 x half> %x to <8 x i16>
274+
ret <8 x i16> %a
275+
}
276+
277+
define <8 x i16> @trunc_sat_u_v8i16(<8 x half> %x) {
278+
; CHECK-LABEL: trunc_sat_u_v8i16:
279+
; CHECK: .functype trunc_sat_u_v8i16 (v128) -> (v128)
280+
; CHECK-NEXT: i16x8.trunc_sat_f16x8_u $push0=, $0
281+
; CHECK-NEXT: return $pop[[R]]{{$}}
282+
%a = fptoui <8 x half> %x to <8 x i16>
283+
ret <8 x i16> %a
284+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,4 +920,16 @@ main:
920920
# CHECK: f16x8.relaxed_nmadd # encoding: [0xfd,0xc7,0x02]
921921
f16x8.relaxed_nmadd
922922

923+
# CHECK: i16x8.trunc_sat_f16x8_s # encoding: [0xfd,0xc8,0x02]
924+
i16x8.trunc_sat_f16x8_s
925+
926+
# CHECK: i16x8.trunc_sat_f16x8_u # encoding: [0xfd,0xc9,0x02]
927+
i16x8.trunc_sat_f16x8_u
928+
929+
# CHECK: f16x8.convert_i16x8_s # encoding: [0xfd,0xca,0x02]
930+
f16x8.convert_i16x8_s
931+
932+
# CHECK: f16x8.convert_i16x8_u # encoding: [0xfd,0xcb,0x02]
933+
f16x8.convert_i16x8_u
934+
923935
end_function

0 commit comments

Comments
 (0)