| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 |
| ; RUN: llc -mtriple=amdgcn -mcpu=gfx1250 < %s | FileCheck -check-prefix=GFX1250 %s |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_bf16lo(bfloat %src0, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16hi_bf16hi_bf16hi_int(i32 %src0, i32 %src1, i32 %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16hi_bf16hi_bf16hi_int: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel:[1,1,1] op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.hi = lshr i32 %src0, 16 |
| %src1.hi = lshr i32 %src1, 16 |
| %src2.hi = lshr i32 %src2, 16 |
| %src0.i16 = trunc i32 %src0.hi to i16 |
| %src1.i16 = trunc i32 %src1.hi to i16 |
| %src2.i16 = trunc i32 %src2.hi to i16 |
| %src0.fp16 = bitcast i16 %src0.i16 to bfloat |
| %src1.fp16 = bitcast i16 %src1.i16 to bfloat |
| %src2.fp16 = bitcast i16 %src2.i16 to bfloat |
| %src0.ext = fpext bfloat %src0.fp16 to float |
| %src1.ext = fpext bfloat %src1.fp16 to float |
| %src2.ext = fpext bfloat %src2.fp16 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16hi_bf16hi_bf16hi_elt(<2 x bfloat> %src0, <2 x bfloat> %src1, <2 x bfloat> %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16hi_bf16hi_bf16hi_elt: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel:[1,1,1] op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.hi = extractelement <2 x bfloat> %src0, i32 1 |
| %src1.hi = extractelement <2 x bfloat> %src1, i32 1 |
| %src2.hi = extractelement <2 x bfloat> %src2, i32 1 |
| %src0.ext = fpext bfloat %src0.hi to float |
| %src1.ext = fpext bfloat %src1.hi to float |
| %src2.ext = fpext bfloat %src2.hi to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define <2 x float> @v_mad_mix_v2f32(<2 x bfloat> %src0, <2 x bfloat> %src1, <2 x bfloat> %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_v2f32: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_and_b32_e32 v5, 0xffff0000, v0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v4, 16, v0 :: v_dual_lshlrev_b32 v6, 16, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v7, 0xffff0000, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v1, 0xffff0000, v2 |
| ; GFX1250-NEXT: v_lshlrev_b32_e32 v0, 16, v2 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) |
| ; GFX1250-NEXT: v_pk_fma_f32 v[0:1], v[4:5], v[6:7], v[0:1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext <2 x bfloat> %src0 to <2 x float> |
| %src1.ext = fpext <2 x bfloat> %src1 to <2 x float> |
| %src2.ext = fpext <2 x bfloat> %src2 to <2 x float> |
| %result = tail call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %src0.ext, <2 x float> %src1.ext, <2 x float> %src2.ext) |
| ret <2 x float> %result |
| } |
| |
| define <2 x float> @v_mad_mix_v2f32_shuffle(<2 x bfloat> %src0, <2 x bfloat> %src1, <2 x bfloat> %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_v2f32_shuffle: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v5, 16, v0 :: v_dual_lshlrev_b32 v6, 16, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v4, 0xffff0000, v0 |
| ; GFX1250-NEXT: v_and_b32_e32 v7, 0xffff0000, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v0, 0xffff0000, v2 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) |
| ; GFX1250-NEXT: v_pk_fma_f32 v[0:1], v[4:5], v[6:7], v[0:1] op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.shuf = shufflevector <2 x bfloat> %src0, <2 x bfloat> undef, <2 x i32> <i32 1, i32 0> |
| %src1.shuf = shufflevector <2 x bfloat> %src1, <2 x bfloat> undef, <2 x i32> <i32 0, i32 1> |
| %src2.shuf = shufflevector <2 x bfloat> %src2, <2 x bfloat> undef, <2 x i32> <i32 1, i32 1> |
| %src0.ext = fpext <2 x bfloat> %src0.shuf to <2 x float> |
| %src1.ext = fpext <2 x bfloat> %src1.shuf to <2 x float> |
| %src2.ext = fpext <2 x bfloat> %src2.shuf to <2 x float> |
| %result = tail call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %src0.ext, <2 x float> %src1.ext, <2 x float> %src2.ext) |
| ret <2 x float> %result |
| } |
| |
| define float @v_mad_mix_f32_negbf16lo_bf16lo_bf16lo(bfloat %src0, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_negbf16lo_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, -v0, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %src0.ext.neg = fneg float %src0.ext |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext.neg, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_absbf16lo_bf16lo_bf16lo(bfloat %src0, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_absbf16lo_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, |v0|, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %src0.ext.abs = call float @llvm.fabs.f32(float %src0.ext) |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext.abs, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_negabsbf16lo_bf16lo_bf16lo(bfloat %src0, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_negabsbf16lo_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, -|v0|, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %src0.ext.abs = call float @llvm.fabs.f32(float %src0.ext) |
| %src0.ext.neg.abs = fneg float %src0.ext.abs |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext.neg.abs, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_f32(bfloat %src0, bfloat %src1, float %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_f32: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_negf32(bfloat %src0, bfloat %src1, float %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_negf32: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, -v2 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.neg = fneg float %src2 |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.neg) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_absf32(bfloat %src0, bfloat %src1, float %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_absf32: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, |v2| op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.abs = call float @llvm.fabs.f32(float %src2) |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.abs) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_negabsf32(bfloat %src0, bfloat %src1, float %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_negabsf32: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, -|v2| op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.abs = call float @llvm.fabs.f32(float %src2) |
| %src2.neg.abs = fneg float %src2.abs |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.neg.abs) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_f32imm1(bfloat %src0, bfloat %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_f32imm1: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: s_mov_b32 s0, 1.0 |
| ; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, s0 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float 1.0) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_f32imminv2pi(bfloat %src0, bfloat %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_f32imminv2pi: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: s_mov_b32 s0, 0.15915494 |
| ; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, s0 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float 0x3FC45F3060000000) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_cvtbf16imminv2pi(bfloat %src0, bfloat %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_cvtbf16imminv2pi: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: s_mov_b32 s0, 0x3e230000 |
| ; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, s0 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2 = fpext bfloat 0xR3e23 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_cvtbf16imm63(bfloat %src0, bfloat %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_cvtbf16imm63: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: s_mov_b32 s0, 0x367c0000 |
| ; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, s0 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2 = fpext bfloat 0xR367c to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2) |
| ret float %result |
| } |
| |
| define <2 x float> @v_mad_mix_v2f32_f32imm1(<2 x bfloat> %src0, <2 x bfloat> %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_v2f32_f32imm1: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_and_b32_e32 v3, 0xffff0000, v0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v2, 16, v0 :: v_dual_lshlrev_b32 v4, 16, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v5, 0xffff0000, v1 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) |
| ; GFX1250-NEXT: v_pk_fma_f32 v[0:1], v[2:3], v[4:5], 1.0 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext <2 x bfloat> %src0 to <2 x float> |
| %src1.ext = fpext <2 x bfloat> %src1 to <2 x float> |
| %result = tail call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %src0.ext, <2 x float> %src1.ext, <2 x float> <float 1.0, float 1.0>) |
| ret <2 x float> %result |
| } |
| |
| define <2 x float> @v_mad_mix_v2f32_cvtbf16imminv2pi(<2 x bfloat> %src0, <2 x bfloat> %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_v2f32_cvtbf16imminv2pi: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_and_b32_e32 v3, 0xffff0000, v0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v2, 16, v0 :: v_dual_lshlrev_b32 v4, 16, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v5, 0xffff0000, v1 |
| ; GFX1250-NEXT: s_mov_b32 s0, 0x3e230000 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1) |
| ; GFX1250-NEXT: v_pk_fma_f32 v[0:1], v[2:3], v[4:5], s[0:1] op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext <2 x bfloat> %src0 to <2 x float> |
| %src1.ext = fpext <2 x bfloat> %src1 to <2 x float> |
| %src2 = fpext <2 x bfloat> <bfloat 0xR3e23, bfloat 0xR3e23> to <2 x float> |
| %result = tail call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %src0.ext, <2 x float> %src1.ext, <2 x float> %src2) |
| ret <2 x float> %result |
| } |
| |
| define <2 x float> @v_mad_mix_v2f32_f32imminv2pi(<2 x bfloat> %src0, <2 x bfloat> %src1) #0 { |
| ; GFX1250-LABEL: v_mad_mix_v2f32_f32imminv2pi: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_and_b32_e32 v3, 0xffff0000, v0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v2, 16, v0 :: v_dual_lshlrev_b32 v4, 16, v1 |
| ; GFX1250-NEXT: v_and_b32_e32 v5, 0xffff0000, v1 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) |
| ; GFX1250-NEXT: v_pk_fma_f32 v[0:1], v[2:3], v[4:5], 0.15915494 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext <2 x bfloat> %src0 to <2 x float> |
| %src1.ext = fpext <2 x bfloat> %src1 to <2 x float> |
| %src2 = fpext <2 x bfloat> <bfloat 0xR3e23, bfloat 0xR3e23> to <2 x float> |
| %result = tail call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %src0.ext, <2 x float> %src1.ext, <2 x float> <float 0x3FC45F3060000000, float 0x3FC45F3060000000>) |
| ret <2 x float> %result |
| } |
| |
| define float @v_mad_mix_clamp_f32_bf16hi_bf16hi_bf16hi_elt(<2 x bfloat> %src0, <2 x bfloat> %src1, <2 x bfloat> %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_clamp_f32_bf16hi_bf16hi_bf16hi_elt: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel:[1,1,1] op_sel_hi:[1,1,1] clamp |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.hi = extractelement <2 x bfloat> %src0, i32 1 |
| %src1.hi = extractelement <2 x bfloat> %src1, i32 1 |
| %src2.hi = extractelement <2 x bfloat> %src2, i32 1 |
| %src0.ext = fpext bfloat %src0.hi to float |
| %src1.ext = fpext bfloat %src1.hi to float |
| %src2.ext = fpext bfloat %src2.hi to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| %max = call float @llvm.maxnum.f32(float %result, float 0.0) |
| %clamp = call float @llvm.minnum.f32(float %max, float 1.0) |
| ret float %clamp |
| } |
| |
| define float @no_mix_simple(float %src0, float %src1, float %src2) #0 { |
| ; GFX1250-LABEL: no_mix_simple: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_f32 v0, v0, v1, v2 |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %result = call float @llvm.fmuladd.f32(float %src0, float %src1, float %src2) |
| ret float %result |
| } |
| |
| define float @no_mix_simple_fabs(float %src0, float %src1, float %src2) #0 { |
| ; GFX1250-LABEL: no_mix_simple_fabs: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_f32 v0, |v0|, v1, v2 |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.fabs = call float @llvm.fabs.f32(float %src0) |
| %result = call float @llvm.fmuladd.f32(float %src0.fabs, float %src1, float %src2) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_bf16lo_f32_denormals(bfloat %src0, bfloat %src1, bfloat %src2) #1 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_bf16lo_f32_denormals: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_f32_denormals(bfloat %src0, bfloat %src1, float %src2) #1 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_f32_denormals: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_bf16lo_f32_denormals_fmulfadd(bfloat %src0, bfloat %src1, bfloat %src2) #1 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_bf16lo_f32_denormals_fmulfadd: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v0, 16, v0 :: v_dual_lshlrev_b32 v1, 16, v1 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v2, 16, v2 :: v_dual_mul_f32 v0, v0, v1 |
| ; GFX1250-NEXT: v_add_f32_e32 v0, v0, v2 |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %mul = fmul float %src0.ext, %src1.ext |
| %result = fadd float %mul, %src2.ext |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_f32_denormals_fmulfadd(bfloat %src0, bfloat %src1, float %src2) #1 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_f32_denormals_fmulfadd: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v0, 16, v0 :: v_dual_lshlrev_b32 v1, 16, v1 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) |
| ; GFX1250-NEXT: v_mul_f32_e32 v0, v0, v1 |
| ; GFX1250-NEXT: v_add_f32_e32 v0, v0, v2 |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %mul = fmul float %src0.ext, %src1.ext |
| %result = fadd float %mul, %src2 |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_bf16lo_f32_flush_fmulfadd(bfloat %src0, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_bf16lo_f32_flush_fmulfadd: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %mul = fmul contract float %src0.ext, %src1.ext |
| %result = fadd contract float %mul, %src2.ext |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_f32_flush_fmulfadd(bfloat %src0, bfloat %src1, float %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_f32_flush_fmulfadd: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[1,1,0] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %mul = fmul contract float %src0.ext, %src1.ext |
| %result = fadd contract float %mul, %src2 |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_negprecvtbf16lo_bf16lo_bf16lo(i32 %src0.arg, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_negprecvtbf16lo_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, -v0, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.arg.bc = bitcast i32 %src0.arg to <2 x bfloat> |
| %src0 = extractelement <2 x bfloat> %src0.arg.bc, i32 0 |
| %src0.neg = fneg bfloat %src0 |
| %src0.ext = fpext bfloat %src0.neg to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_precvtnegbf16hi_abs_bf16lo_bf16lo(i32 %src0.arg, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_precvtnegbf16hi_abs_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_lshrrev_b32_e32 v0, 16, v0 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) |
| ; GFX1250-NEXT: v_xor_b32_e32 v0, 0x8000, v0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, |v0|, v1, v2 op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.arg.bc = bitcast i32 %src0.arg to <2 x bfloat> |
| %src0 = extractelement <2 x bfloat> %src0.arg.bc, i32 1 |
| %src0.neg = fneg bfloat %src0 |
| %src0.ext = fpext bfloat %src0.neg to float |
| %src0.ext.abs = call float @llvm.fabs.f32(float %src0.ext) |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext.abs, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_precvtabsbf16hi_bf16lo_bf16lo(i32 %src0.arg, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_precvtabsbf16hi_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, |v0|, v1, v2 op_sel:[1,0,0] op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.arg.bc = bitcast i32 %src0.arg to <2 x bfloat> |
| %src0 = extractelement <2 x bfloat> %src0.arg.bc, i32 1 |
| %src0.abs = call bfloat @llvm.fabs.bf16(bfloat %src0) |
| %src0.ext = fpext bfloat %src0.abs to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_preextractfneg_bf16hi_bf16lo_bf16lo(i32 %src0.arg, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_preextractfneg_bf16hi_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, -v0, v1, v2 op_sel:[1,0,0] op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.arg.bc = bitcast i32 %src0.arg to <2 x bfloat> |
| %fneg = fneg <2 x bfloat> %src0.arg.bc |
| %src0 = extractelement <2 x bfloat> %fneg, i32 1 |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_preextractfabs_bf16hi_bf16lo_bf16lo(i32 %src0.arg, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_preextractfabs_bf16hi_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, |v0|, v1, v2 op_sel:[1,0,0] op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.arg.bc = bitcast i32 %src0.arg to <2 x bfloat> |
| %fabs = call <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat> %src0.arg.bc) |
| %src0 = extractelement <2 x bfloat> %fabs, i32 1 |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_preextractfabsfneg_bf16hi_bf16lo_bf16lo(i32 %src0.arg, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_preextractfabsfneg_bf16hi_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, -|v0|, v1, v2 op_sel:[1,0,0] op_sel_hi:[1,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.arg.bc = bitcast i32 %src0.arg to <2 x bfloat> |
| %fabs = call <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat> %src0.arg.bc) |
| %fneg.fabs = fneg <2 x bfloat> %fabs |
| %src0 = extractelement <2 x bfloat> %fneg.fabs, i32 1 |
| %src0.ext = fpext bfloat %src0 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_bf16lo_bf16lo_all_cast_from_half(half %src0, half %src1, half %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_bf16lo_bf16lo_all_cast_from_half: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_dual_lshlrev_b32 v3, 16, v0 :: v_dual_lshlrev_b32 v1, 16, v1 |
| ; GFX1250-NEXT: v_lshlrev_b32_e32 v0, 16, v2 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) |
| ; GFX1250-NEXT: v_fmac_f32_e32 v0, v3, v1 |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.bf16 = bitcast half %src0 to bfloat |
| %src1.bf16 = bitcast half %src1 to bfloat |
| %src2.bf16 = bitcast half %src2 to bfloat |
| %src0.ext = fpext bfloat %src0.bf16 to float |
| %src1.ext = fpext bfloat %src1.bf16 to float |
| %src2.ext = fpext bfloat %src2.bf16 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define float @v_mad_mix_f32_bf16lo_cast_from_half_bf16lo_bf16lo(half %src0, bfloat %src1, bfloat %src2) #0 { |
| ; GFX1250-LABEL: v_mad_mix_f32_bf16lo_cast_from_half_bf16lo_bf16lo: |
| ; GFX1250: ; %bb.0: |
| ; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_lshlrev_b32_e32 v0, 16, v0 |
| ; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, v0, v1, v2 op_sel_hi:[0,1,1] |
| ; GFX1250-NEXT: s_set_pc_i64 s[30:31] |
| %src0.bf16 = bitcast half %src0 to bfloat |
| %src0.ext = fpext bfloat %src0.bf16 to float |
| %src1.ext = fpext bfloat %src1 to float |
| %src2.ext = fpext bfloat %src2 to float |
| %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext) |
| ret float %result |
| } |
| |
| define amdgpu_kernel void @test_fma_mix_f32_bf16_src2_bf16lo(float %x, i32 %y, ptr addrspace(1) %out) { |
| ; GFX1250-LABEL: test_fma_mix_f32_bf16_src2_bf16lo: |
| ; GFX1250: ; %bb.0: ; %entry |
| ; GFX1250-NEXT: s_load_b128 s[0:3], s[4:5], 0x24 |
| ; GFX1250-NEXT: s_wait_kmcnt 0x0 |
| ; GFX1250-NEXT: v_fma_mix_f32_bf16 v0, s0, 0, s1 op_sel_hi:[0,0,1] |
| ; GFX1250-NEXT: s_mov_b32 s0, 0 |
| ; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_2) |
| ; GFX1250-NEXT: v_dual_mov_b32 v2, 0 :: v_dual_mov_b32 v1, s0 |
| ; GFX1250-NEXT: v_cmp_u_f32_e32 vcc_lo, v0, v0 |
| ; GFX1250-NEXT: v_cndmask_b32_e64 v0, 0, 1, vcc_lo |
| ; GFX1250-NEXT: global_store_b64 v2, v[0:1], s[2:3] |
| ; GFX1250-NEXT: s_endpgm |
| entry: |
| %v0 = shl i32 %y, 16 |
| %v1 = bitcast i32 %v0 to float |
| %mul7 = fmul contract float %x, 0.000000e+00 |
| %add2 = fadd contract float %mul7, %v1 |
| %v2 = fcmp uno float %add2, 0.000000e+00 |
| %v3 = select i1 %v2, i64 1, i64 0 |
| store i64 %v3, ptr addrspace(1) %out, align 8 |
| ret void |
| } |
| |
| declare bfloat @llvm.fabs.bf16(bfloat) #2 |
| declare <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat>) #2 |
| declare float @llvm.fabs.f32(float) #2 |
| declare float @llvm.minnum.f32(float, float) #2 |
| declare float @llvm.maxnum.f32(float, float) #2 |
| declare float @llvm.fmuladd.f32(float, float, float) #2 |
| declare <2 x float> @llvm.fmuladd.v2f32(<2 x float>, <2 x float>, <2 x float>) #2 |
| |
| attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign,preserve-sign" } |
| attributes #1 = { nounwind "denormal-fp-math-f32"="ieee,ieee" } |
| attributes #2 = { nounwind readnone speculatable } |