blob: aff1bd385308dc33c88baf24b87392ef3e7c2b23 [file] [log] [blame] [edit]
; 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
}