Skip to content

[WebAssembly] Implement trunc_sat and convert instructions for f16x8. #95180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
Original file line number Diff line number Diff line change
Expand Up @@ -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)>;
Expand All @@ -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.
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/CodeGen/WebAssembly/half-precision.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
12 changes: 12 additions & 0 deletions llvm/test/MC/WebAssembly/simd-encodings.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading