; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 ; RUN: llc < %s -mtriple=nvptx64-unknown-unknown | FileCheck %s ; Test llvm.convert.from.arbitrary intrinsic expansion. declare float @llvm.convert.from.arbitrary.fp.f32.i8(i8, metadata) declare float @llvm.convert.from.arbitrary.fp.f32.i6(i6, metadata) declare float @llvm.convert.from.arbitrary.fp.f32.i4(i4, metadata) declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4>, metadata) declare half @llvm.convert.from.arbitrary.fp.f16.i8(i8, metadata) declare double @llvm.convert.from.arbitrary.fp.f64.i8(i8, metadata) ; Float8E5M2 ; Layout: sign(1) exp(5) mant(2), bias=15 ; Supports: Inf, NaN, signed zero, denormals ; Float8E5M2 normal: 0_01111_00 = 1.0 define float @from_f8e5m2_normal() { ; CHECK-LABEL: from_f8e5m2_normal( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1065353216; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 60, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 zero: 0_00000_00 = +0.0 define float @from_f8e5m2_zero() { ; CHECK-LABEL: from_f8e5m2_zero( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 0; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 0, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 negative zero: 1_00000_00 = -0.0 define float @from_f8e5m2_neg_zero() { ; CHECK-LABEL: from_f8e5m2_neg_zero( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], -2147483648; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 -128, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 denorm: 0_00000_01 = 2^(-16) define float @from_f8e5m2_denorm() { ; CHECK-LABEL: from_f8e5m2_denorm( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 931135488; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 1, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 +Inf: 0_11111_00 define float @from_f8e5m2_inf() { ; CHECK-LABEL: from_f8e5m2_inf( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 2139095040; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 124, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 NaN: 0_11111_01 define float @from_f8e5m2_nan() { ; CHECK-LABEL: from_f8e5m2_nan( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 2143289344; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 125, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 max: 0_11110_11 = 57344 define float @from_f8e5m2_max() { ; CHECK-LABEL: from_f8e5m2_max( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1197473792; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 123, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 negative: 1_01111_00 = -1.0 define float @from_f8e5m2_neg() { ; CHECK-LABEL: from_f8e5m2_neg( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], -1082130432; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 -68, metadata !"Float8E5M2") ret float %r } ; Float8E5M2 runtime arg test define float @from_f8e5m2_dynamic(i8 %x) { ; CHECK-LABEL: from_f8e5m2_dynamic( ; CHECK: { ; CHECK-NEXT: .reg .pred %p<6>; ; CHECK-NEXT: .reg .b32 %r<31>; ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: ld.param.b8 %r1, [from_f8e5m2_dynamic_param_0]; ; CHECK-NEXT: shl.b32 %r2, %r1, 24; ; CHECK-NEXT: and.b32 %r3, %r2, -2147483648; ; CHECK-NEXT: and.b32 %r4, %r1, 3; ; CHECK-NEXT: clz.b32 %r5, %r4; ; CHECK-NEXT: sub.s32 %r6, 142, %r5; ; CHECK-NEXT: shl.b32 %r7, %r6, 23; ; CHECK-NEXT: or.b32 %r8, %r3, %r7; ; CHECK-NEXT: sub.s32 %r9, 31, %r5; ; CHECK-NEXT: mov.b32 %r10, 1; ; CHECK-NEXT: shl.b32 %r11, %r10, %r9; ; CHECK-NEXT: xor.b32 %r12, %r4, %r11; ; CHECK-NEXT: add.s32 %r13, %r5, -8; ; CHECK-NEXT: shl.b32 %r14, %r12, %r13; ; CHECK-NEXT: or.b32 %r15, %r8, %r14; ; CHECK-NEXT: bfe.u32 %r16, %r1, 2, 5; ; CHECK-NEXT: shl.b32 %r17, %r16, 23; ; CHECK-NEXT: or.b32 %r18, %r17, %r3; ; CHECK-NEXT: shl.b32 %r19, %r4, 21; ; CHECK-NEXT: or.b32 %r20, %r18, %r19; ; CHECK-NEXT: add.s32 %r21, %r20, 939524096; ; CHECK-NEXT: setp.ne.b32 %p1, %r4, 0; ; CHECK-NEXT: selp.b32 %r22, %r15, %r21, %p1; ; CHECK-NEXT: setp.eq.b32 %p2, %r16, 0; ; CHECK-NEXT: selp.b32 %r23, %r22, %r21, %p2; ; CHECK-NEXT: or.b32 %r24, %r16, %r4; ; CHECK-NEXT: setp.eq.b32 %p3, %r24, 0; ; CHECK-NEXT: selp.b32 %r25, %r3, %r23, %p3; ; CHECK-NEXT: setp.eq.b32 %p4, %r4, 0; ; CHECK-NEXT: or.b32 %r26, %r3, 2139095040; ; CHECK-NEXT: selp.b32 %r27, %r26, %r25, %p4; ; CHECK-NEXT: setp.eq.b32 %p5, %r16, 31; ; CHECK-NEXT: selp.b32 %r28, %r27, %r25, %p5; ; CHECK-NEXT: selp.b32 %r29, 2143289344, %r28, %p1; ; CHECK-NEXT: selp.b32 %r30, %r29, %r28, %p5; ; CHECK-NEXT: st.param.b32 [func_retval0], %r30; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 %x, metadata !"Float8E5M2") ret float %r } ; Float8E4M3FN (NanOnly, NanEncoding=AllOnes) ; Layout: sign(1) exp(4) mant(3), maxExp=8, minExp=-6, bias=7 ; Only 0_1111_111 and 1_1111_111 are NaN; all other exp=15 values are finite. ; Float8E4M3FN normal: 0_0111_000 = 1.0 define float @from_f8e4m3fn_normal() { ; CHECK-LABEL: from_f8e4m3fn_normal( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1065353216; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 56, metadata !"Float8E4M3FN") ret float %r } ; Float8E4M3FN NaN: 0_1111_111 define float @from_f8e4m3fn_nan() { ; CHECK-LABEL: from_f8e4m3fn_nan( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 2143289344; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 127, metadata !"Float8E4M3FN") ret float %r } ; Float8E4M3FN not-NaN: 0_1111_110 = 448 ; Despite exp=all-ones, this is a valid finite number (max value) define float @from_f8e4m3fn_max() { ; CHECK-LABEL: from_f8e4m3fn_max( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1138753536; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 126, metadata !"Float8E4M3FN") ret float %r } ; Float8E4M3FN not-NaN: 0_1111_101 = 416 ; exp=all-ones but mant!=all-ones so this is finite define float @from_f8e4m3fn_not_nan() { ; CHECK-LABEL: from_f8e4m3fn_not_nan( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1137704960; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 125, metadata !"Float8E4M3FN") ret float %r } ; Float8E4M3FN zero: 0_0000_000 = +0.0 define float @from_f8e4m3fn_zero() { ; CHECK-LABEL: from_f8e4m3fn_zero( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 0; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 0, metadata !"Float8E4M3FN") ret float %r } ; Float8E4M3FN denorm: 0_0000_001 = 2^(-9) define float @from_f8e4m3fn_denorm() { ; CHECK-LABEL: from_f8e4m3fn_denorm( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 989855744; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 1, metadata !"Float8E4M3FN") ret float %r } ; Float8E4M3FN runtime arg test define float @from_f8e4m3fn_dynamic(i8 %x) { ; CHECK-LABEL: from_f8e4m3fn_dynamic( ; CHECK: { ; CHECK-NEXT: .reg .pred %p<6>; ; CHECK-NEXT: .reg .b32 %r<28>; ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: ld.param.b8 %r1, [from_f8e4m3fn_dynamic_param_0]; ; CHECK-NEXT: shl.b32 %r2, %r1, 24; ; CHECK-NEXT: and.b32 %r3, %r2, -2147483648; ; CHECK-NEXT: and.b32 %r4, %r1, 7; ; CHECK-NEXT: clz.b32 %r5, %r4; ; CHECK-NEXT: sub.s32 %r6, 149, %r5; ; CHECK-NEXT: shl.b32 %r7, %r6, 23; ; CHECK-NEXT: or.b32 %r8, %r3, %r7; ; CHECK-NEXT: sub.s32 %r9, 31, %r5; ; CHECK-NEXT: mov.b32 %r10, 1; ; CHECK-NEXT: shl.b32 %r11, %r10, %r9; ; CHECK-NEXT: xor.b32 %r12, %r4, %r11; ; CHECK-NEXT: add.s32 %r13, %r5, -8; ; CHECK-NEXT: shl.b32 %r14, %r12, %r13; ; CHECK-NEXT: or.b32 %r15, %r8, %r14; ; CHECK-NEXT: bfe.u32 %r16, %r1, 3, 4; ; CHECK-NEXT: shl.b32 %r17, %r16, 23; ; CHECK-NEXT: or.b32 %r18, %r17, %r3; ; CHECK-NEXT: shl.b32 %r19, %r4, 20; ; CHECK-NEXT: or.b32 %r20, %r18, %r19; ; CHECK-NEXT: add.s32 %r21, %r20, 1006632960; ; CHECK-NEXT: setp.ne.b32 %p1, %r4, 0; ; CHECK-NEXT: selp.b32 %r22, %r15, %r21, %p1; ; CHECK-NEXT: setp.eq.b32 %p2, %r16, 0; ; CHECK-NEXT: selp.b32 %r23, %r22, %r21, %p2; ; CHECK-NEXT: or.b32 %r24, %r16, %r4; ; CHECK-NEXT: setp.eq.b32 %p3, %r24, 0; ; CHECK-NEXT: selp.b32 %r25, %r3, %r23, %p3; ; CHECK-NEXT: setp.eq.b32 %p4, %r4, 7; ; CHECK-NEXT: selp.b32 %r26, 2143289344, %r25, %p4; ; CHECK-NEXT: setp.eq.b32 %p5, %r16, 15; ; CHECK-NEXT: selp.b32 %r27, %r26, %r25, %p5; ; CHECK-NEXT: st.param.b32 [func_retval0], %r27; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 %x, metadata !"Float8E4M3FN") ret float %r } ; Float6E3M2FN (FiniteOnly) ; Layout: sign(1) exp(3) mant(2), bias=3, maxExp=4 ; No Inf, no NaN. All bit patterns are finite. ; Float6E3M2FN normal: 0_011_00 = 1.0 define float @from_f6e3m2fn_normal() { ; CHECK-LABEL: from_f6e3m2fn_normal( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1065353216; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 12, metadata !"Float6E3M2FN") ret float %r } ; Float6E3M2FN max: 0_111_11 = 28.0 define float @from_f6e3m2fn_max() { ; CHECK-LABEL: from_f6e3m2fn_max( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1105199104; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 31, metadata !"Float6E3M2FN") ret float %r } ; Float6E3M2FN denorm: 0_000_01 = 0.0625 define float @from_f6e3m2fn_denorm() { ; CHECK-LABEL: from_f6e3m2fn_denorm( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1031798784; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 1, metadata !"Float6E3M2FN") ret float %r } ; Float6E3M2FN zero: 0_000_00 = +0.0 define float @from_f6e3m2fn_zero() { ; CHECK-LABEL: from_f6e3m2fn_zero( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 0; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 0, metadata !"Float6E3M2FN") ret float %r } ; Float6E3M2FN negative: 1_011_00 = -1.0 define float @from_f6e3m2fn_neg() { ; CHECK-LABEL: from_f6e3m2fn_neg( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], -1082130432; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 -20, metadata !"Float6E3M2FN") ret float %r } ; Float6E3M2FN runtime arg test define float @from_f6e3m2fn_dynamic(i6 %x) { ; CHECK-LABEL: from_f6e3m2fn_dynamic( ; CHECK: { ; CHECK-NEXT: .reg .pred %p<4>; ; CHECK-NEXT: .reg .b16 %rs<5>; ; CHECK-NEXT: .reg .b32 %r<26>; ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: ld.param.b8 %rs1, [from_f6e3m2fn_dynamic_param_0+1]; ; CHECK-NEXT: shl.b16 %rs2, %rs1, 8; ; CHECK-NEXT: ld.param.b8 %rs3, [from_f6e3m2fn_dynamic_param_0]; ; CHECK-NEXT: or.b16 %rs4, %rs2, %rs3; ; CHECK-NEXT: cvt.u32.u16 %r1, %rs4; ; CHECK-NEXT: shl.b32 %r2, %r1, 26; ; CHECK-NEXT: and.b32 %r3, %r2, -2147483648; ; CHECK-NEXT: and.b32 %r4, %r1, 3; ; CHECK-NEXT: clz.b32 %r5, %r4; ; CHECK-NEXT: sub.s32 %r6, 154, %r5; ; CHECK-NEXT: shl.b32 %r7, %r6, 23; ; CHECK-NEXT: or.b32 %r8, %r3, %r7; ; CHECK-NEXT: sub.s32 %r9, 31, %r5; ; CHECK-NEXT: mov.b32 %r10, 1; ; CHECK-NEXT: shl.b32 %r11, %r10, %r9; ; CHECK-NEXT: xor.b32 %r12, %r4, %r11; ; CHECK-NEXT: add.s32 %r13, %r5, -8; ; CHECK-NEXT: shl.b32 %r14, %r12, %r13; ; CHECK-NEXT: or.b32 %r15, %r8, %r14; ; CHECK-NEXT: bfe.u32 %r16, %r1, 2, 3; ; CHECK-NEXT: shl.b32 %r17, %r16, 23; ; CHECK-NEXT: or.b32 %r18, %r17, %r3; ; CHECK-NEXT: shl.b32 %r19, %r4, 21; ; CHECK-NEXT: or.b32 %r20, %r18, %r19; ; CHECK-NEXT: add.s32 %r21, %r20, 1040187392; ; CHECK-NEXT: setp.ne.b32 %p1, %r4, 0; ; CHECK-NEXT: selp.b32 %r22, %r15, %r21, %p1; ; CHECK-NEXT: setp.eq.b32 %p2, %r16, 0; ; CHECK-NEXT: selp.b32 %r23, %r22, %r21, %p2; ; CHECK-NEXT: or.b32 %r24, %r16, %r4; ; CHECK-NEXT: setp.eq.b32 %p3, %r24, 0; ; CHECK-NEXT: selp.b32 %r25, %r3, %r23, %p3; ; CHECK-NEXT: st.param.b32 [func_retval0], %r25; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 %x, metadata !"Float6E3M2FN") ret float %r } ; Float6E2M3FN (FiniteOnly) ; Layout: sign(1) exp(2) mant(3), bias=1, maxExp=2 ; No Inf, no NaN. All bit patterns are finite. ; Float6E2M3FN normal: 0_01_000 = 1.0 define float @from_f6e2m3fn_normal() { ; CHECK-LABEL: from_f6e2m3fn_normal( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1065353216; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 8, metadata !"Float6E2M3FN") ret float %r } ; Float6E2M3FN max: 0_11_111 = 7.5 define float @from_f6e2m3fn_max() { ; CHECK-LABEL: from_f6e2m3fn_max( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1089470464; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 31, metadata !"Float6E2M3FN") ret float %r } ; Float6E2M3FN denorm: 0_00_001 = 0.125 define float @from_f6e2m3fn_denorm() { ; CHECK-LABEL: from_f6e2m3fn_denorm( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1040187392; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 1, metadata !"Float6E2M3FN") ret float %r } ; Float6E2M3FN zero: 0_00_000 = +0.0 define float @from_f6e2m3fn_zero() { ; CHECK-LABEL: from_f6e2m3fn_zero( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 0; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 0, metadata !"Float6E2M3FN") ret float %r } ; Float6E2M3FN runtime arg test define float @from_f6e2m3fn_dynamic(i6 %x) { ; CHECK-LABEL: from_f6e2m3fn_dynamic( ; CHECK: { ; CHECK-NEXT: .reg .pred %p<4>; ; CHECK-NEXT: .reg .b16 %rs<5>; ; CHECK-NEXT: .reg .b32 %r<26>; ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: ld.param.b8 %rs1, [from_f6e2m3fn_dynamic_param_0+1]; ; CHECK-NEXT: shl.b16 %rs2, %rs1, 8; ; CHECK-NEXT: ld.param.b8 %rs3, [from_f6e2m3fn_dynamic_param_0]; ; CHECK-NEXT: or.b16 %rs4, %rs2, %rs3; ; CHECK-NEXT: cvt.u32.u16 %r1, %rs4; ; CHECK-NEXT: shl.b32 %r2, %r1, 26; ; CHECK-NEXT: and.b32 %r3, %r2, -2147483648; ; CHECK-NEXT: and.b32 %r4, %r1, 7; ; CHECK-NEXT: clz.b32 %r5, %r4; ; CHECK-NEXT: sub.s32 %r6, 155, %r5; ; CHECK-NEXT: shl.b32 %r7, %r6, 23; ; CHECK-NEXT: or.b32 %r8, %r3, %r7; ; CHECK-NEXT: sub.s32 %r9, 31, %r5; ; CHECK-NEXT: mov.b32 %r10, 1; ; CHECK-NEXT: shl.b32 %r11, %r10, %r9; ; CHECK-NEXT: xor.b32 %r12, %r4, %r11; ; CHECK-NEXT: add.s32 %r13, %r5, -8; ; CHECK-NEXT: shl.b32 %r14, %r12, %r13; ; CHECK-NEXT: or.b32 %r15, %r8, %r14; ; CHECK-NEXT: bfe.u32 %r16, %r1, 3, 2; ; CHECK-NEXT: shl.b32 %r17, %r16, 23; ; CHECK-NEXT: or.b32 %r18, %r17, %r3; ; CHECK-NEXT: shl.b32 %r19, %r4, 20; ; CHECK-NEXT: or.b32 %r20, %r18, %r19; ; CHECK-NEXT: add.s32 %r21, %r20, 1056964608; ; CHECK-NEXT: setp.ne.b32 %p1, %r4, 0; ; CHECK-NEXT: selp.b32 %r22, %r15, %r21, %p1; ; CHECK-NEXT: setp.eq.b32 %p2, %r16, 0; ; CHECK-NEXT: selp.b32 %r23, %r22, %r21, %p2; ; CHECK-NEXT: or.b32 %r24, %r16, %r4; ; CHECK-NEXT: setp.eq.b32 %p3, %r24, 0; ; CHECK-NEXT: selp.b32 %r25, %r3, %r23, %p3; ; CHECK-NEXT: st.param.b32 [func_retval0], %r25; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i6(i6 %x, metadata !"Float6E2M3FN") ret float %r } ; Float4E2M1FN (FiniteOnly) ; Layout: sign(1) exp(2) mant(1), bias=1, maxExp=2 ; No Inf, no NaN. ; Float4E2M1FN normal: 0_01_0 = 1.0 define float @from_f4e2m1fn_normal() { ; CHECK-LABEL: from_f4e2m1fn_normal( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1065353216; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i4(i4 2, metadata !"Float4E2M1FN") ret float %r } ; Float4E2M1FN denorm: 0_00_1 = 0.5 define float @from_f4e2m1fn_denorm() { ; CHECK-LABEL: from_f4e2m1fn_denorm( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1056964608; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i4(i4 1, metadata !"Float4E2M1FN") ret float %r } ; Float4E2M1FN max: 0_11_1 = 6.0 define float @from_f4e2m1fn_max() { ; CHECK-LABEL: from_f4e2m1fn_max( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b32 [func_retval0], 1086324736; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i4(i4 7, metadata !"Float4E2M1FN") ret float %r } ; Float4E2M1FN runtime arg test define float @from_f4e2m1fn_dynamic(i4 %x) { ; CHECK-LABEL: from_f4e2m1fn_dynamic( ; CHECK: { ; CHECK-NEXT: .reg .pred %p<4>; ; CHECK-NEXT: .reg .b16 %rs<6>; ; CHECK-NEXT: .reg .b32 %r<26>; ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: ld.param.b8 %rs1, [from_f4e2m1fn_dynamic_param_0+1]; ; CHECK-NEXT: shl.b16 %rs2, %rs1, 8; ; CHECK-NEXT: ld.param.b8 %rs3, [from_f4e2m1fn_dynamic_param_0]; ; CHECK-NEXT: or.b16 %rs4, %rs2, %rs3; ; CHECK-NEXT: cvt.u32.u16 %r1, %rs4; ; CHECK-NEXT: shl.b32 %r2, %r1, 28; ; CHECK-NEXT: and.b32 %r3, %r2, -2147483648; ; CHECK-NEXT: and.b32 %r4, %r1, 1; ; CHECK-NEXT: clz.b32 %r5, %r4; ; CHECK-NEXT: sub.s32 %r6, 157, %r5; ; CHECK-NEXT: shl.b32 %r7, %r6, 23; ; CHECK-NEXT: or.b32 %r8, %r3, %r7; ; CHECK-NEXT: sub.s32 %r9, 31, %r5; ; CHECK-NEXT: mov.b32 %r10, 1; ; CHECK-NEXT: shl.b32 %r11, %r10, %r9; ; CHECK-NEXT: xor.b32 %r12, %r4, %r11; ; CHECK-NEXT: add.s32 %r13, %r5, -8; ; CHECK-NEXT: shl.b32 %r14, %r12, %r13; ; CHECK-NEXT: or.b32 %r15, %r8, %r14; ; CHECK-NEXT: bfe.u32 %r16, %r1, 1, 2; ; CHECK-NEXT: shl.b32 %r17, %r16, 23; ; CHECK-NEXT: or.b32 %r18, %r17, %r3; ; CHECK-NEXT: shl.b32 %r19, %r4, 22; ; CHECK-NEXT: or.b32 %r20, %r18, %r19; ; CHECK-NEXT: add.s32 %r21, %r20, 1056964608; ; CHECK-NEXT: and.b16 %rs5, %rs3, 1; ; CHECK-NEXT: setp.ne.b16 %p1, %rs5, 0; ; CHECK-NEXT: selp.b32 %r22, %r15, %r21, %p1; ; CHECK-NEXT: setp.eq.b32 %p2, %r16, 0; ; CHECK-NEXT: selp.b32 %r23, %r22, %r21, %p2; ; CHECK-NEXT: or.b32 %r24, %r16, %r4; ; CHECK-NEXT: setp.eq.b32 %p3, %r24, 0; ; CHECK-NEXT: selp.b32 %r25, %r3, %r23, %p3; ; CHECK-NEXT: st.param.b32 [func_retval0], %r25; ; CHECK-NEXT: ret; %r = call float @llvm.convert.from.arbitrary.fp.f32.i4(i4 %x, metadata !"Float4E2M1FN") ret float %r } ; Float8E5M2 to f16: 1.0 define half @from_f8e5m2_to_f16() { ; CHECK-LABEL: from_f8e5m2_to_f16( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b16 [func_retval0], 0x3C00; ; CHECK-NEXT: ret; %r = call half @llvm.convert.from.arbitrary.fp.f16.i8(i8 60, metadata !"Float8E5M2") ret half %r } ; Float8E5M2 to f64: 1.0 define double @from_f8e5m2_to_f64() { ; CHECK-LABEL: from_f8e5m2_to_f64( ; CHECK: { ; CHECK-EMPTY: ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: st.param.b64 [func_retval0], 4607182418800017408; ; CHECK-NEXT: ret; %r = call double @llvm.convert.from.arbitrary.fp.f64.i8(i8 60, metadata !"Float8E5M2") ret double %r } ; Vector test: Float4E2M1FN <4 x i4> -> <4 x float> define <4 x float> @fp4_to_f32_vec(<4 x i4> %x) { ; CHECK-LABEL: fp4_to_f32_vec( ; CHECK: { ; CHECK-NEXT: .reg .pred %p<13>; ; CHECK-NEXT: .reg .b32 %r<101>; ; CHECK-EMPTY: ; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: ld.param.b16 %r1, [fp4_to_f32_vec_param_0+2]; ; CHECK-NEXT: shl.b32 %r2, %r1, 16; ; CHECK-NEXT: ld.param.b16 %r3, [fp4_to_f32_vec_param_0]; ; CHECK-NEXT: prmt.b32 %r4, %r3, 0, 0x7771U; ; CHECK-NEXT: shl.b32 %r5, %r4, 28; ; CHECK-NEXT: and.b32 %r6, %r5, -2147483648; ; CHECK-NEXT: and.b32 %r7, %r4, 1; ; CHECK-NEXT: clz.b32 %r8, %r7; ; CHECK-NEXT: sub.s32 %r9, 157, %r8; ; CHECK-NEXT: shl.b32 %r10, %r9, 23; ; CHECK-NEXT: or.b32 %r11, %r6, %r10; ; CHECK-NEXT: sub.s32 %r12, 31, %r8; ; CHECK-NEXT: mov.b32 %r13, 1; ; CHECK-NEXT: shl.b32 %r14, %r13, %r12; ; CHECK-NEXT: xor.b32 %r15, %r7, %r14; ; CHECK-NEXT: add.s32 %r16, %r8, -8; ; CHECK-NEXT: shl.b32 %r17, %r15, %r16; ; CHECK-NEXT: or.b32 %r18, %r11, %r17; ; CHECK-NEXT: bfe.u32 %r19, %r4, 1, 2; ; CHECK-NEXT: shl.b32 %r20, %r19, 23; ; CHECK-NEXT: or.b32 %r21, %r20, %r6; ; CHECK-NEXT: shl.b32 %r22, %r7, 22; ; CHECK-NEXT: or.b32 %r23, %r21, %r22; ; CHECK-NEXT: add.s32 %r24, %r23, 1056964608; ; CHECK-NEXT: setp.ne.b32 %p1, %r7, 0; ; CHECK-NEXT: selp.b32 %r25, %r18, %r24, %p1; ; CHECK-NEXT: setp.eq.b32 %p2, %r19, 0; ; CHECK-NEXT: selp.b32 %r26, %r25, %r24, %p2; ; CHECK-NEXT: or.b32 %r27, %r19, %r7; ; CHECK-NEXT: setp.eq.b32 %p3, %r27, 0; ; CHECK-NEXT: selp.b32 %r28, %r6, %r26, %p3; ; CHECK-NEXT: prmt.b32 %r29, %r3, 0, 0x7770U; ; CHECK-NEXT: shl.b32 %r30, %r29, 28; ; CHECK-NEXT: and.b32 %r31, %r30, -2147483648; ; CHECK-NEXT: and.b32 %r32, %r29, 1; ; CHECK-NEXT: clz.b32 %r33, %r32; ; CHECK-NEXT: sub.s32 %r34, 157, %r33; ; CHECK-NEXT: shl.b32 %r35, %r34, 23; ; CHECK-NEXT: or.b32 %r36, %r31, %r35; ; CHECK-NEXT: sub.s32 %r37, 31, %r33; ; CHECK-NEXT: shl.b32 %r38, %r13, %r37; ; CHECK-NEXT: xor.b32 %r39, %r32, %r38; ; CHECK-NEXT: add.s32 %r40, %r33, -8; ; CHECK-NEXT: shl.b32 %r41, %r39, %r40; ; CHECK-NEXT: or.b32 %r42, %r36, %r41; ; CHECK-NEXT: bfe.u32 %r43, %r29, 1, 2; ; CHECK-NEXT: shl.b32 %r44, %r43, 23; ; CHECK-NEXT: or.b32 %r45, %r44, %r31; ; CHECK-NEXT: shl.b32 %r46, %r32, 22; ; CHECK-NEXT: or.b32 %r47, %r45, %r46; ; CHECK-NEXT: add.s32 %r48, %r47, 1056964608; ; CHECK-NEXT: setp.ne.b32 %p4, %r32, 0; ; CHECK-NEXT: selp.b32 %r49, %r42, %r48, %p4; ; CHECK-NEXT: setp.eq.b32 %p5, %r43, 0; ; CHECK-NEXT: selp.b32 %r50, %r49, %r48, %p5; ; CHECK-NEXT: or.b32 %r51, %r43, %r32; ; CHECK-NEXT: setp.eq.b32 %p6, %r51, 0; ; CHECK-NEXT: selp.b32 %r52, %r31, %r50, %p6; ; CHECK-NEXT: prmt.b32 %r53, %r2, 0, 0x7773U; ; CHECK-NEXT: shl.b32 %r54, %r53, 28; ; CHECK-NEXT: and.b32 %r55, %r54, -2147483648; ; CHECK-NEXT: and.b32 %r56, %r53, 1; ; CHECK-NEXT: clz.b32 %r57, %r56; ; CHECK-NEXT: sub.s32 %r58, 157, %r57; ; CHECK-NEXT: shl.b32 %r59, %r58, 23; ; CHECK-NEXT: or.b32 %r60, %r55, %r59; ; CHECK-NEXT: sub.s32 %r61, 31, %r57; ; CHECK-NEXT: shl.b32 %r62, %r13, %r61; ; CHECK-NEXT: xor.b32 %r63, %r56, %r62; ; CHECK-NEXT: add.s32 %r64, %r57, -8; ; CHECK-NEXT: shl.b32 %r65, %r63, %r64; ; CHECK-NEXT: or.b32 %r66, %r60, %r65; ; CHECK-NEXT: bfe.u32 %r67, %r53, 1, 2; ; CHECK-NEXT: shl.b32 %r68, %r67, 23; ; CHECK-NEXT: or.b32 %r69, %r68, %r55; ; CHECK-NEXT: shl.b32 %r70, %r56, 22; ; CHECK-NEXT: or.b32 %r71, %r69, %r70; ; CHECK-NEXT: add.s32 %r72, %r71, 1056964608; ; CHECK-NEXT: setp.ne.b32 %p7, %r56, 0; ; CHECK-NEXT: selp.b32 %r73, %r66, %r72, %p7; ; CHECK-NEXT: setp.eq.b32 %p8, %r67, 0; ; CHECK-NEXT: selp.b32 %r74, %r73, %r72, %p8; ; CHECK-NEXT: or.b32 %r75, %r67, %r56; ; CHECK-NEXT: setp.eq.b32 %p9, %r75, 0; ; CHECK-NEXT: selp.b32 %r76, %r55, %r74, %p9; ; CHECK-NEXT: prmt.b32 %r77, %r2, 0, 0x7772U; ; CHECK-NEXT: shl.b32 %r78, %r77, 28; ; CHECK-NEXT: and.b32 %r79, %r78, -2147483648; ; CHECK-NEXT: and.b32 %r80, %r77, 1; ; CHECK-NEXT: clz.b32 %r81, %r80; ; CHECK-NEXT: sub.s32 %r82, 157, %r81; ; CHECK-NEXT: shl.b32 %r83, %r82, 23; ; CHECK-NEXT: or.b32 %r84, %r79, %r83; ; CHECK-NEXT: sub.s32 %r85, 31, %r81; ; CHECK-NEXT: shl.b32 %r86, %r13, %r85; ; CHECK-NEXT: xor.b32 %r87, %r80, %r86; ; CHECK-NEXT: add.s32 %r88, %r81, -8; ; CHECK-NEXT: shl.b32 %r89, %r87, %r88; ; CHECK-NEXT: or.b32 %r90, %r84, %r89; ; CHECK-NEXT: bfe.u32 %r91, %r77, 1, 2; ; CHECK-NEXT: shl.b32 %r92, %r91, 23; ; CHECK-NEXT: or.b32 %r93, %r92, %r79; ; CHECK-NEXT: shl.b32 %r94, %r80, 22; ; CHECK-NEXT: or.b32 %r95, %r93, %r94; ; CHECK-NEXT: add.s32 %r96, %r95, 1056964608; ; CHECK-NEXT: setp.ne.b32 %p10, %r80, 0; ; CHECK-NEXT: selp.b32 %r97, %r90, %r96, %p10; ; CHECK-NEXT: setp.eq.b32 %p11, %r91, 0; ; CHECK-NEXT: selp.b32 %r98, %r97, %r96, %p11; ; CHECK-NEXT: or.b32 %r99, %r91, %r80; ; CHECK-NEXT: setp.eq.b32 %p12, %r99, 0; ; CHECK-NEXT: selp.b32 %r100, %r79, %r98, %p12; ; CHECK-NEXT: st.param.v4.b32 [func_retval0], {%r52, %r28, %r100, %r76}; ; CHECK-NEXT: ret; %r = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4> %x, metadata !"Float4E2M1FN") ret <4 x float> %r }