| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: llc < %s -mcpu=sm_50 -mattr=+ptx32 -nvptx-approx-log2f32 | FileCheck --check-prefixes=CHECK %s |
| ; RUN: %if ptxas-sm_50 && ptxas-isa-3.2 %{ llc < %s -mcpu=sm_50 -mattr=+ptx32 -nvptx-approx-log2f32 | %ptxas-verify -arch=sm_50 %} |
| target triple = "nvptx64-nvidia-cuda" |
| |
| ; CHECK-LABEL: log2_test |
| define float @log2_test(float %in) { |
| ; CHECK-LABEL: log2_test( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .b32 %r<3>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.b32 %r1, [log2_test_param_0]; |
| ; CHECK-NEXT: lg2.approx.f32 %r2, %r1; |
| ; CHECK-NEXT: st.param.b32 [func_retval0], %r2; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call float @llvm.log2.f32(float %in) |
| ret float %log2 |
| } |
| |
| ; CHECK-LABEL: log2_ftz_test |
| define float @log2_ftz_test(float %in) #0 { |
| ; CHECK-LABEL: log2_ftz_test( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .b32 %r<3>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.b32 %r1, [log2_ftz_test_param_0]; |
| ; CHECK-NEXT: lg2.approx.ftz.f32 %r2, %r1; |
| ; CHECK-NEXT: st.param.b32 [func_retval0], %r2; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call float @llvm.log2.f32(float %in) |
| ret float %log2 |
| } |
| |
| ; CHECK-LABEL: log2_test_v |
| define <2 x float> @log2_test_v(<2 x float> %in) { |
| ; CHECK-LABEL: log2_test_v( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .b32 %r<5>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.v2.b32 {%r1, %r2}, [log2_test_v_param_0]; |
| ; CHECK-NEXT: lg2.approx.f32 %r3, %r2; |
| ; CHECK-NEXT: lg2.approx.f32 %r4, %r1; |
| ; CHECK-NEXT: st.param.v2.b32 [func_retval0], {%r4, %r3}; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call <2 x float> @llvm.log2.v2f32(<2 x float> %in) |
| ret <2 x float> %log2 |
| } |
| |
| ; --- f16 --- |
| |
| ; CHECK-LABEL: log2_f16_test |
| define half @log2_f16_test(half %in) { |
| ; CHECK-LABEL: log2_f16_test( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .b16 %rs<3>; |
| ; CHECK-NEXT: .reg .b32 %r<3>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.b16 %rs1, [log2_f16_test_param_0]; |
| ; CHECK-NEXT: cvt.f32.f16 %r1, %rs1; |
| ; CHECK-NEXT: lg2.approx.f32 %r2, %r1; |
| ; CHECK-NEXT: cvt.rn.f16.f32 %rs2, %r2; |
| ; CHECK-NEXT: st.param.b16 [func_retval0], %rs2; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call half @llvm.log2.f16(half %in) |
| ret half %log2 |
| } |
| |
| ; CHECK-LABEL: log2_f16_ftz_test |
| define half @log2_f16_ftz_test(half %in) #0 { |
| ; CHECK-LABEL: log2_f16_ftz_test( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .b16 %rs<3>; |
| ; CHECK-NEXT: .reg .b32 %r<3>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.b16 %rs1, [log2_f16_ftz_test_param_0]; |
| ; CHECK-NEXT: cvt.ftz.f32.f16 %r1, %rs1; |
| ; CHECK-NEXT: lg2.approx.ftz.f32 %r2, %r1; |
| ; CHECK-NEXT: cvt.rn.f16.f32 %rs2, %r2; |
| ; CHECK-NEXT: st.param.b16 [func_retval0], %rs2; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call half @llvm.log2.f16(half %in) |
| ret half %log2 |
| } |
| |
| ; CHECK-LABEL: log2_f16_test_v |
| define <2 x half> @log2_f16_test_v(<2 x half> %in) { |
| ; CHECK-LABEL: log2_f16_test_v( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .b16 %rs<5>; |
| ; CHECK-NEXT: .reg .b32 %r<6>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.v2.b16 {%rs1, %rs2}, [log2_f16_test_v_param_0]; |
| ; CHECK-NEXT: cvt.f32.f16 %r1, %rs2; |
| ; CHECK-NEXT: lg2.approx.f32 %r2, %r1; |
| ; CHECK-NEXT: cvt.rn.f16.f32 %rs3, %r2; |
| ; CHECK-NEXT: cvt.f32.f16 %r3, %rs1; |
| ; CHECK-NEXT: lg2.approx.f32 %r4, %r3; |
| ; CHECK-NEXT: cvt.rn.f16.f32 %rs4, %r4; |
| ; CHECK-NEXT: mov.b32 %r5, {%rs4, %rs3}; |
| ; CHECK-NEXT: st.param.b32 [func_retval0], %r5; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call <2 x half> @llvm.log2.v2f16(<2 x half> %in) |
| ret <2 x half> %log2 |
| } |
| |
| ; --- bf16 --- |
| |
| ; CHECK-LABEL: log2_bf16_test |
| define bfloat @log2_bf16_test(bfloat %in) { |
| ; CHECK-LABEL: log2_bf16_test( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .pred %p<2>; |
| ; CHECK-NEXT: .reg .b32 %r<10>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.b16 %r1, [log2_bf16_test_param_0]; |
| ; CHECK-NEXT: shl.b32 %r2, %r1, 16; |
| ; CHECK-NEXT: lg2.approx.f32 %r3, %r2; |
| ; CHECK-NEXT: bfe.u32 %r4, %r3, 16, 1; |
| ; CHECK-NEXT: add.s32 %r5, %r4, %r3; |
| ; CHECK-NEXT: add.s32 %r6, %r5, 32767; |
| ; CHECK-NEXT: setp.nan.f32 %p1, %r3, %r3; |
| ; CHECK-NEXT: or.b32 %r7, %r3, 4194304; |
| ; CHECK-NEXT: selp.b32 %r8, %r7, %r6, %p1; |
| ; CHECK-NEXT: shr.u32 %r9, %r8, 16; |
| ; CHECK-NEXT: st.param.b16 [func_retval0], %r9; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call bfloat @llvm.log2.bf16(bfloat %in) |
| ret bfloat %log2 |
| } |
| |
| ; CHECK-LABEL: log2_bf16_ftz_test |
| define bfloat @log2_bf16_ftz_test(bfloat %in) #0 { |
| ; CHECK-LABEL: log2_bf16_ftz_test( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .pred %p<2>; |
| ; CHECK-NEXT: .reg .b32 %r<10>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.b16 %r1, [log2_bf16_ftz_test_param_0]; |
| ; CHECK-NEXT: shl.b32 %r2, %r1, 16; |
| ; CHECK-NEXT: lg2.approx.ftz.f32 %r3, %r2; |
| ; CHECK-NEXT: bfe.u32 %r4, %r3, 16, 1; |
| ; CHECK-NEXT: add.s32 %r5, %r4, %r3; |
| ; CHECK-NEXT: add.s32 %r6, %r5, 32767; |
| ; CHECK-NEXT: setp.nan.ftz.f32 %p1, %r3, %r3; |
| ; CHECK-NEXT: or.b32 %r7, %r3, 4194304; |
| ; CHECK-NEXT: selp.b32 %r8, %r7, %r6, %p1; |
| ; CHECK-NEXT: shr.u32 %r9, %r8, 16; |
| ; CHECK-NEXT: st.param.b16 [func_retval0], %r9; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call bfloat @llvm.log2.bf16(bfloat %in) |
| ret bfloat %log2 |
| } |
| |
| ; CHECK-LABEL: log2_bf16_test_v |
| define <2 x bfloat> @log2_bf16_test_v(<2 x bfloat> %in) { |
| ; CHECK-LABEL: log2_bf16_test_v( |
| ; CHECK: { |
| ; CHECK-NEXT: .reg .pred %p<3>; |
| ; CHECK-NEXT: .reg .b16 %rs<3>; |
| ; CHECK-NEXT: .reg .b32 %r<18>; |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: // %bb.0: // %entry |
| ; CHECK-NEXT: ld.param.v2.b16 {%rs1, %rs2}, [log2_bf16_test_v_param_0]; |
| ; CHECK-NEXT: cvt.u32.u16 %r1, %rs2; |
| ; CHECK-NEXT: shl.b32 %r2, %r1, 16; |
| ; CHECK-NEXT: lg2.approx.f32 %r3, %r2; |
| ; CHECK-NEXT: bfe.u32 %r4, %r3, 16, 1; |
| ; CHECK-NEXT: add.s32 %r5, %r4, %r3; |
| ; CHECK-NEXT: add.s32 %r6, %r5, 32767; |
| ; CHECK-NEXT: setp.nan.f32 %p1, %r3, %r3; |
| ; CHECK-NEXT: or.b32 %r7, %r3, 4194304; |
| ; CHECK-NEXT: selp.b32 %r8, %r7, %r6, %p1; |
| ; CHECK-NEXT: cvt.u32.u16 %r9, %rs1; |
| ; CHECK-NEXT: shl.b32 %r10, %r9, 16; |
| ; CHECK-NEXT: lg2.approx.f32 %r11, %r10; |
| ; CHECK-NEXT: bfe.u32 %r12, %r11, 16, 1; |
| ; CHECK-NEXT: add.s32 %r13, %r12, %r11; |
| ; CHECK-NEXT: add.s32 %r14, %r13, 32767; |
| ; CHECK-NEXT: setp.nan.f32 %p2, %r11, %r11; |
| ; CHECK-NEXT: or.b32 %r15, %r11, 4194304; |
| ; CHECK-NEXT: selp.b32 %r16, %r15, %r14, %p2; |
| ; CHECK-NEXT: prmt.b32 %r17, %r16, %r8, 0x7632U; |
| ; CHECK-NEXT: st.param.b32 [func_retval0], %r17; |
| ; CHECK-NEXT: ret; |
| entry: |
| %log2 = call <2 x bfloat> @llvm.log2.v2bf16(<2 x bfloat> %in) |
| ret <2 x bfloat> %log2 |
| } |
| |
| declare float @llvm.log2.f32(float %val) |
| |
| declare <2 x float> @llvm.log2.v2f32(<2 x float> %val) |
| |
| declare half @llvm.log2.f16(half %val) |
| |
| declare <2 x half> @llvm.log2.v2f16(<2 x half> %val) |
| |
| declare bfloat @llvm.log2.bf16(bfloat %val) |
| |
| declare <2 x bfloat> @llvm.log2.v2bf16(<2 x bfloat> %val) |
| |
| attributes #0 = {"denormal-fp-math"="preserve-sign"} |