[llvm] 928b780 - [WebAssembly] Implement trunc_sat and convert instructions for f16x8. (#95180)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 25 10:39:09 PDT 2024
Author: Brendan Dahl
Date: 2024-06-25T10:39:05-07:00
New Revision: 928b7808406b893b24edb8d8462491dc82f9ce43
URL: https://github.com/llvm/llvm-project/commit/928b7808406b893b24edb8d8462491dc82f9ce43
DIFF: https://github.com/llvm/llvm-project/commit/928b7808406b893b24edb8d8462491dc82f9ce43.diff
LOG: [WebAssembly] Implement trunc_sat and convert instructions for f16x8. (#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
Added:
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
llvm/test/CodeGen/WebAssembly/half-precision.ll
llvm/test/MC/WebAssembly/simd-encodings.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
index 3888175efd115..2ee430c88169d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1320,16 +1320,23 @@ def : Pat<(v8f16 (int_wasm_pmax (v8f16 V128:$lhs), (v8f16 V128:$rhs))),
//===----------------------------------------------------------------------===//
multiclass SIMDConvert<Vec vec, Vec arg, SDPatternOperator op, string name,
- bits<32> simdop> {
+ bits<32> simdop, list<Predicate> reqs = []> {
defm op#_#vec :
SIMD_I<(outs V128:$dst), (ins V128:$vec), (outs), (ins),
[(set (vec.vt V128:$dst), (vec.vt (op (arg.vt V128:$vec))))],
- vec.prefix#"."#name#"\t$dst, $vec", vec.prefix#"."#name, simdop>;
+ vec.prefix#"."#name#"\t$dst, $vec", vec.prefix#"."#name, simdop, reqs>;
+}
+
+multiclass HalfPrecisionConvert<Vec vec, Vec arg, SDPatternOperator op,
+ string name, bits<32> simdop> {
+ defm "" : SIMDConvert<vec, arg, op, name, simdop, [HasHalfPrecision]>;
}
// Floating point to integer with saturation: trunc_sat
defm "" : SIMDConvert<I32x4, F32x4, fp_to_sint, "trunc_sat_f32x4_s", 248>;
defm "" : SIMDConvert<I32x4, F32x4, fp_to_uint, "trunc_sat_f32x4_u", 249>;
+defm "" : HalfPrecisionConvert<I16x8, F16x8, fp_to_sint, "trunc_sat_f16x8_s", 0x148>;
+defm "" : HalfPrecisionConvert<I16x8, F16x8, fp_to_uint, "trunc_sat_f16x8_u", 0x149>;
// Support the saturating variety as well.
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>;
defm "" : SIMDConvert<F32x4, I32x4, uint_to_fp, "convert_i32x4_u", 251>;
defm "" : SIMDConvert<F64x2, I32x4, convert_low_s, "convert_low_i32x4_s", 0xfe>;
defm "" : SIMDConvert<F64x2, I32x4, convert_low_u, "convert_low_i32x4_u", 0xff>;
+defm "" : HalfPrecisionConvert<F16x8, I16x8, sint_to_fp, "convert_i16x8_s", 0x14a>;
+defm "" : HalfPrecisionConvert<F16x8, I16x8, uint_to_fp, "convert_i16x8_u", 0x14b>;
// Extending operations
// TODO: refactor this to be uniform for i64x2 if the numbering is not changed.
diff --git a/llvm/test/CodeGen/WebAssembly/half-precision.ll b/llvm/test/CodeGen/WebAssembly/half-precision.ll
index 0f0a159091514..fa78f5f9591d6 100644
--- a/llvm/test/CodeGen/WebAssembly/half-precision.ll
+++ b/llvm/test/CodeGen/WebAssembly/half-precision.ll
@@ -246,3 +246,39 @@ define <8 x half> @nearest_v8f16_via_roundeven(<8 x half> %a) {
%v = call <8 x half> @llvm.roundeven.v8f16(<8 x half> %a)
ret <8 x half> %v
}
+
+define <8 x half> @convert_s_v8f16(<8 x i16> %x) {
+; CHECK-LABEL: convert_s_v8f16:
+; CHECK: .functype convert_s_v8f16 (v128) -> (v128)
+; CHECK-NEXT: f16x8.convert_i16x8_s $push0=, $0
+; CHECK-NEXT: return $pop[[R]]{{$}}
+ %a = sitofp <8 x i16> %x to <8 x half>
+ ret <8 x half> %a
+}
+
+define <8 x half> @convert_u_v8f16(<8 x i16> %x) {
+; CHECK-LABEL: convert_u_v8f16:
+; CHECK: .functype convert_u_v8f16 (v128) -> (v128)
+; CHECK-NEXT: f16x8.convert_i16x8_u $push0=, $0
+; CHECK-NEXT: return $pop[[R]]{{$}}
+ %a = uitofp <8 x i16> %x to <8 x half>
+ ret <8 x half> %a
+}
+
+define <8 x i16> @trunc_sat_s_v8i16(<8 x half> %x) {
+; CHECK-LABEL: trunc_sat_s_v8i16:
+; CHECK: .functype trunc_sat_s_v8i16 (v128) -> (v128)
+; CHECK-NEXT: i16x8.trunc_sat_f16x8_s $push0=, $0
+; CHECK-NEXT: return $pop[[R]]{{$}}
+ %a = fptosi <8 x half> %x to <8 x i16>
+ ret <8 x i16> %a
+}
+
+define <8 x i16> @trunc_sat_u_v8i16(<8 x half> %x) {
+; CHECK-LABEL: trunc_sat_u_v8i16:
+; CHECK: .functype trunc_sat_u_v8i16 (v128) -> (v128)
+; CHECK-NEXT: i16x8.trunc_sat_f16x8_u $push0=, $0
+; CHECK-NEXT: return $pop[[R]]{{$}}
+ %a = fptoui <8 x half> %x to <8 x i16>
+ ret <8 x i16> %a
+}
diff --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s
index 88c91be9263da..8c3483bfaad7a 100644
--- a/llvm/test/MC/WebAssembly/simd-encodings.s
+++ b/llvm/test/MC/WebAssembly/simd-encodings.s
@@ -920,4 +920,16 @@ main:
# CHECK: f16x8.relaxed_nmadd # encoding: [0xfd,0xc7,0x02]
f16x8.relaxed_nmadd
+ # CHECK: i16x8.trunc_sat_f16x8_s # encoding: [0xfd,0xc8,0x02]
+ i16x8.trunc_sat_f16x8_s
+
+ # CHECK: i16x8.trunc_sat_f16x8_u # encoding: [0xfd,0xc9,0x02]
+ i16x8.trunc_sat_f16x8_u
+
+ # CHECK: f16x8.convert_i16x8_s # encoding: [0xfd,0xca,0x02]
+ f16x8.convert_i16x8_s
+
+ # CHECK: f16x8.convert_i16x8_u # encoding: [0xfd,0xcb,0x02]
+ f16x8.convert_i16x8_u
+
end_function
More information about the llvm-commits
mailing list