| ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s |
| ; Test valid scalar and vector conversions for arbitrary FP intrinsics |
| |
| declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1) |
| declare <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f16(<4 x half>, metadata, metadata, i1) |
| declare <8 x i8> @llvm.convert.to.arbitrary.fp.v8i8.v8f16(<8 x half>, metadata, metadata, i1) |
| declare <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float>, metadata, metadata, i1) |
| |
| declare half @llvm.convert.from.arbitrary.fp.f16.i8(i8, metadata) |
| declare <4 x half> @llvm.convert.from.arbitrary.fp.v4f16.v4i8(<4 x i8>, metadata) |
| declare <8 x half> @llvm.convert.from.arbitrary.fp.v8f16.v8i8(<8 x i8>, metadata) |
| declare float @llvm.convert.from.arbitrary.fp.f32.i8(i8, metadata) |
| declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8(<4 x i8>, metadata) |
| |
| ; Scalar conversions to arbitrary FP |
| ; CHECK-LABEL: @good_half_to_fp8( |
| define i8 @good_half_to_fp8(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E5M2", metadata !"round.towardzero", i1 true) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_half_to_fp8_fnuz( |
| define i8 @good_half_to_fp8_fnuz(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E4M3FNUZ", metadata !"round.tonearest", i1 false) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_half_to_fp8_fn( |
| define i8 @good_half_to_fp8_fn(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false) |
| ret i8 %r |
| } |
| |
| ; Scalar conversions from arbitrary FP |
| ; CHECK-LABEL: @good_fp8_to_half( |
| define half @good_fp8_to_half(i8 %v) { |
| %r = call half @llvm.convert.from.arbitrary.fp.f16.i8( |
| i8 %v, metadata !"Float8E4M3") |
| ret half %r |
| } |
| |
| ; CHECK-LABEL: @good_fp8_e5m2_to_half( |
| define half @good_fp8_e5m2_to_half(i8 %v) { |
| %r = call half @llvm.convert.from.arbitrary.fp.f16.i8( |
| i8 %v, metadata !"Float8E5M2") |
| ret half %r |
| } |
| |
| ; CHECK-LABEL: @good_fp8_to_float( |
| define float @good_fp8_to_float(i8 %v) { |
| %r = call float @llvm.convert.from.arbitrary.fp.f32.i8( |
| i8 %v, metadata !"Float8E4M3") |
| ret float %r |
| } |
| |
| ; Vector conversions to arbitrary FP |
| ; CHECK-LABEL: @good_vec4_half_to_fp8( |
| define <4 x i8> @good_vec4_half_to_fp8(<4 x half> %v) { |
| %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f16( |
| <4 x half> %v, metadata !"Float8E4M3FN", metadata !"round.towardzero", i1 true) |
| ret <4 x i8> %r |
| } |
| |
| ; CHECK-LABEL: @good_vec8_half_to_fp8( |
| define <8 x i8> @good_vec8_half_to_fp8(<8 x half> %v) { |
| %r = call <8 x i8> @llvm.convert.to.arbitrary.fp.v8i8.v8f16( |
| <8 x half> %v, metadata !"Float8E5M2FNUZ", metadata !"round.tonearest", i1 false) |
| ret <8 x i8> %r |
| } |
| |
| ; CHECK-LABEL: @good_vec4_float_to_fp8( |
| define <4 x i8> @good_vec4_float_to_fp8(<4 x float> %v) { |
| %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32( |
| <4 x float> %v, metadata !"Float8E4M3B11FNUZ", metadata !"round.tonearest", i1 false) |
| ret <4 x i8> %r |
| } |
| |
| ; Vector conversions from arbitrary FP |
| ; CHECK-LABEL: @good_vec4_fp8_to_half( |
| define <4 x half> @good_vec4_fp8_to_half(<4 x i8> %v) { |
| %r = call <4 x half> @llvm.convert.from.arbitrary.fp.v4f16.v4i8( |
| <4 x i8> %v, metadata !"Float8E4M3") |
| ret <4 x half> %r |
| } |
| |
| ; CHECK-LABEL: @good_vec8_fp8_to_half( |
| define <8 x half> @good_vec8_fp8_to_half(<8 x i8> %v) { |
| %r = call <8 x half> @llvm.convert.from.arbitrary.fp.v8f16.v8i8( |
| <8 x i8> %v, metadata !"Float8E5M2") |
| ret <8 x half> %r |
| } |
| |
| ; CHECK-LABEL: @good_vec4_fp8_to_float( |
| define <4 x float> @good_vec4_fp8_to_float(<4 x i8> %v) { |
| %r = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8( |
| <4 x i8> %v, metadata !"Float8E4M3B11FNUZ") |
| ret <4 x float> %r |
| } |
| |
| ; Test different rounding modes |
| ; CHECK-LABEL: @good_rounding_towardzero( |
| define i8 @good_rounding_towardzero(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E4M3", metadata !"round.towardzero", i1 false) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_rounding_upward( |
| define i8 @good_rounding_upward(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E4M3", metadata !"round.upward", i1 false) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_rounding_downward( |
| define i8 @good_rounding_downward(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E4M3", metadata !"round.downward", i1 false) |
| ret i8 %r |
| } |
| |
| ; Test all supported formats |
| ; CHECK-LABEL: @good_float8_e5m2_fnuz( |
| define i8 @good_float8_e5m2_fnuz(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E5M2FNUZ", metadata !"round.tonearest", i1 false) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_float8_e3m4( |
| define i8 @good_float8_e3m4(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E3M4", metadata !"round.tonearest", i1 false) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_float8_e8m0fnu( |
| define i8 @good_float8_e8m0fnu(half %v) { |
| %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16( |
| half %v, metadata !"Float8E8M0FNU", metadata !"round.tonearest", i1 false) |
| ret i8 %r |
| } |
| |
| ; CHECK-LABEL: @good_float6_e3m2fn( |
| define i6 @good_float6_e3m2fn(half %v) { |
| %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f16( |
| half %v, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false) |
| ret i6 %r |
| } |
| |
| ; CHECK-LABEL: @good_float6_e2m3fn( |
| define i6 @good_float6_e2m3fn(half %v) { |
| %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f16( |
| half %v, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false) |
| ret i6 %r |
| } |
| |
| ; CHECK-LABEL: @good_float4_e2m1fn( |
| define i4 @good_float4_e2m1fn(half %v) { |
| %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f16( |
| half %v, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false) |
| ret i4 %r |
| } |
| |
| declare i6 @llvm.convert.to.arbitrary.fp.i6.f16(half, metadata, metadata, i1) |
| declare i4 @llvm.convert.to.arbitrary.fp.i4.f16(half, metadata, metadata, i1) |