blob: 994319756db77beb4f26a6dd67efd9b6e1c88e66 [file]
; RUN: llc -mtriple=amdgpu9 < %s | FileCheck %s
; The default gfx9-generic subtarget lacks the mad-mix instructions, so the
; f16 multiply-add is expanded to conversions plus a separate fma.
; CHECK-LABEL: {{^}}target_none:
; CHECK: v_cvt_f32_f16_e32 [[A:v[0-9]+]], v0
; CHECK: v_cvt_f32_f16_e32 [[B:v[0-9]+]], v1
; CHECK: v_cvt_f32_f16_e32 [[C:v[0-9]+]], v2
; CHECK: v_mac_f32_e32 [[C]], [[A]], [[B]]
define float @target_none(half %a, half %b, half %c) #1 {
%ae = fpext half %a to float
%be = fpext half %b to float
%ce = fpext half %c to float
%r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce)
ret float %r
}
; gfx900 has the mad-mix instructions, so the same multiply-add folds the f16
; conversions into a single v_mad_mix_f32.
; CHECK-LABEL: {{^}}target_gfx900:
; CHECK: v_mad_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,1]
define float @target_gfx900(half %a, half %b, half %c) #2 {
%ae = fpext half %a to float
%be = fpext half %b to float
%ce = fpext half %c to float
%r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce)
ret float %r
}
; gfx906 has the fma-mix instructions, so the same multiply-add folds the f16
; conversions into a single v_fma_mix_f32.
; CHECK-LABEL: {{^}}target_gfx906_mad_mix:
; CHECK: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,1]
define float @target_gfx906_mad_mix(half %a, half %b, half %c) #4 {
%ae = fpext half %a to float
%be = fpext half %b to float
%ce = fpext half %c to float
%r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce)
ret float %r
}
; The fdot2 intrinsic is only available on gfx906.
; CHECK-LABEL: {{^}}target_gfx906:
; CHECK: v_dot2_f32_f16
define amdgpu_kernel void @target_gfx906(ptr addrspace(1) %out, <2 x half> %a, <2 x half> %b, float %c) #3 {
%dot = call float @llvm.amdgcn.fdot2(<2 x half> %a, <2 x half> %b, float %c, i1 false)
store float %dot, ptr addrspace(1) %out, align 4
ret void
}
declare float @llvm.fmuladd.f32(float, float, float) #0
declare float @llvm.amdgcn.fdot2(<2 x half>, <2 x half>, float, i1 immarg) #0
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #1 = { nounwind denormal_fpenv(float: preservesign) }
attributes #2 = { nounwind denormal_fpenv(float: preservesign) "target-cpu"="gfx900" }
attributes #3 = { nounwind "target-cpu"="gfx906" }
attributes #4 = { nounwind denormal_fpenv(float: preservesign) "target-cpu"="gfx906" }