diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll index 6981b43244575..89c73c2161e35 100644 --- a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll +++ b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll @@ -1851,300 +1851,6 @@ define void @exp_compr_disabled_inputs_to_undef(<2 x half> %xy, <2 x half> %zw) ret void } -; -------------------------------------------------------------------- -; llvm.amdgcn.fmed3 -; -------------------------------------------------------------------- - -declare float @llvm.amdgcn.fmed3.f32(float, float, float) nounwind readnone - -define float @fmed3_f32(float %x, float %y, float %z) { -; CHECK-LABEL: @fmed3_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float %z) - ret float %med3 -} - -define float @fmed3_canonicalize_x_c0_c1_f32(float %x) { -; CHECK-LABEL: @fmed3_canonicalize_x_c0_c1_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float 0.000000e+00, float 1.000000e+00) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0.0, float 1.0) - ret float %med3 -} - -define float @fmed3_canonicalize_c0_x_c1_f32(float %x) { -; CHECK-LABEL: @fmed3_canonicalize_c0_x_c1_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float 0.000000e+00, float 1.000000e+00) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %x, float 1.0) - ret float %med3 -} - -define float @fmed3_canonicalize_c0_c1_x_f32(float %x) { -; CHECK-LABEL: @fmed3_canonicalize_c0_c1_x_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float 0.000000e+00, float 1.000000e+00) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %x) - ret float %med3 -} - -define float @fmed3_canonicalize_x_y_c_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_canonicalize_x_y_c_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float [[Y:%.*]], float 1.000000e+00) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 1.0) - ret float %med3 -} - -define float @fmed3_canonicalize_x_c_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_canonicalize_x_c_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float [[Y:%.*]], float 1.000000e+00) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 1.0, float %y) - ret float %med3 -} - -define float @fmed3_canonicalize_c_x_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_canonicalize_c_x_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X:%.*]], float [[Y:%.*]], float 1.000000e+00) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %x, float %y) - ret float %med3 -} - -define float @fmed3_undef_x_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_undef_x_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float undef, float %x, float %y) - ret float %med3 -} - -define float @fmed3_fmf_undef_x_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_fmf_undef_x_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call nnan float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call nnan float @llvm.amdgcn.fmed3.f32(float undef, float %x, float %y) - ret float %med3 -} - -define float @fmed3_x_undef_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_x_undef_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float undef, float %y) - ret float %med3 -} - -define float @fmed3_x_y_undef_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_x_y_undef_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float undef) - ret float %med3 -} - -define float @fmed3_qnan0_x_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_qnan0_x_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000000000000, float %x, float %y) - ret float %med3 -} - -define float @fmed3_x_qnan0_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_x_qnan0_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8000000000000, float %y) - ret float %med3 -} - -define float @fmed3_x_y_qnan0_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_x_y_qnan0_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF8000000000000) - ret float %med3 -} - -define float @fmed3_qnan1_x_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_qnan1_x_y_f32( -; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) -; CHECK-NEXT: ret float [[MED3]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000100000000, float %x, float %y) - ret float %med3 -} - -; This can return any of the qnans. -define float @fmed3_qnan0_qnan1_qnan2_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_qnan0_qnan1_qnan2_f32( -; CHECK-NEXT: ret float 0x7FF8030000000000 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000100000000, float 0x7FF8002000000000, float 0x7FF8030000000000) - ret float %med3 -} - -define float @fmed3_constant_src0_0_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_constant_src0_0_f32( -; CHECK-NEXT: ret float 5.000000e-01 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.5, float -1.0, float 4.0) - ret float %med3 -} - -define float @fmed3_constant_src0_1_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_constant_src0_1_f32( -; CHECK-NEXT: ret float 5.000000e-01 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.5, float 4.0, float -1.0) - ret float %med3 -} - -define float @fmed3_constant_src1_0_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_constant_src1_0_f32( -; CHECK-NEXT: ret float 5.000000e-01 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 0.5, float 4.0) - ret float %med3 -} - -define float @fmed3_constant_src1_1_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_constant_src1_1_f32( -; CHECK-NEXT: ret float 5.000000e-01 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 4.0, float 0.5, float -1.0) - ret float %med3 -} - -define float @fmed3_constant_src2_0_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_constant_src2_0_f32( -; CHECK-NEXT: ret float 5.000000e-01 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 4.0, float 0.5) - ret float %med3 -} - -define float @fmed3_constant_src2_1_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_constant_src2_1_f32( -; CHECK-NEXT: ret float 5.000000e-01 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 4.0, float -1.0, float 0.5) - ret float %med3 -} - -define float @fmed3_x_qnan0_qnan1_f32(float %x) { -; CHECK-LABEL: @fmed3_x_qnan0_qnan1_f32( -; CHECK-NEXT: ret float [[X:%.*]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8001000000000, float 0x7FF8002000000000) - ret float %med3 -} - -define float @fmed3_qnan0_x_qnan1_f32(float %x) { -; CHECK-LABEL: @fmed3_qnan0_x_qnan1_f32( -; CHECK-NEXT: ret float [[X:%.*]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float %x, float 0x7FF8002000000000) - ret float %med3 -} - -define float @fmed3_qnan0_qnan1_x_f32(float %x) { -; CHECK-LABEL: @fmed3_qnan0_qnan1_x_f32( -; CHECK-NEXT: ret float [[X:%.*]] -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float 0x7FF8002000000000, float %x) - ret float %med3 -} - -define float @fmed3_nan_0_1_f32() { -; CHECK-LABEL: @fmed3_nan_0_1_f32( -; CHECK-NEXT: ret float 0.000000e+00 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float 0.0, float 1.0) - ret float %med3 -} - -define float @fmed3_0_nan_1_f32() { -; CHECK-LABEL: @fmed3_0_nan_1_f32( -; CHECK-NEXT: ret float 0.000000e+00 -; - %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 0x7FF8001000000000, float 1.0) - ret float %med -} - -define float @fmed3_0_1_nan_f32() { -; CHECK-LABEL: @fmed3_0_1_nan_f32( -; CHECK-NEXT: ret float 1.000000e+00 -; - %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0x7FF8001000000000) - ret float %med -} - -define float @fmed3_undef_0_1_f32() { -; CHECK-LABEL: @fmed3_undef_0_1_f32( -; CHECK-NEXT: ret float 0.000000e+00 -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float undef, float 0.0, float 1.0) - ret float %med3 -} - -define float @fmed3_0_undef_1_f32() { -; CHECK-LABEL: @fmed3_0_undef_1_f32( -; CHECK-NEXT: ret float 0.000000e+00 -; - %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float undef, float 1.0) - ret float %med -} - -define float @fmed3_0_1_undef_f32() { -; CHECK-LABEL: @fmed3_0_1_undef_f32( -; CHECK-NEXT: ret float 1.000000e+00 -; - %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float undef) - ret float %med -} - -define float @fmed3_poison_x_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_poison_x_y_f32( -; CHECK-NEXT: ret float poison -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float poison, float %x, float %y) - ret float %med3 -} - -define float @fmed3_x_poison_y_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_x_poison_y_f32( -; CHECK-NEXT: ret float poison -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float poison, float %y) - ret float %med3 -} - -define float @fmed3_x_y_poison_f32(float %x, float %y) { -; CHECK-LABEL: @fmed3_x_y_poison_f32( -; CHECK-NEXT: ret float poison -; - %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float poison) - ret float %med3 -} - ; -------------------------------------------------------------------- ; llvm.amdgcn.icmp ; -------------------------------------------------------------------- diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/fmed3-fpext-fold.ll b/llvm/test/Transforms/InstCombine/AMDGPU/fmed3-fpext-fold.ll new file mode 100644 index 0000000000000..a31b47b2ca6e7 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/AMDGPU/fmed3-fpext-fold.ll @@ -0,0 +1,613 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; Unknown/default target +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine < %s | FileCheck -check-prefixes=NO-FMED3F16,UNKNOWN %s + +; Known target, no med3_f16 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -passes=instcombine < %s | FileCheck -check-prefixes=NO-FMED3F16,GFX8 %s + +; Has med3_f16 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=instcombine < %s | FileCheck -check-prefixes=GFX9 %s + + +declare float @llvm.fabs.f32(float) #0 +declare half @llvm.fabs.f16(half) #0 +declare float @llvm.amdgcn.fmed3.f32(float, float, float) #0 + +define float @fmed3_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] { +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half [[ARG2]]) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_flags(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_flags +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call nsz float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_flags +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[MED31:%.*]] = call nsz half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half [[ARG2]]) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call nsz float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_k0(half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0 +; NO-FMED3F16-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 2.000000e+00) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0 +; GFX9-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG1]], half [[ARG2]], half 0xH4000) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float 2.0, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_k1(half %arg0, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k1 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 2.000000e+00) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k1 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG2]], half 0xH4000) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float 2.0, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_k2(half %arg0, half %arg1) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k2 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 2.000000e+00) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k2 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half 0xH4000) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float 2.0) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_k0_k1(half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0_k1 +; NO-FMED3F16-SAME: (half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG2_EXT]], float 0.000000e+00, float 1.600000e+01) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0_k1 +; GFX9-SAME: (half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG2]], half 0xH0000, half 0xH4C00) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 16.0, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_k0_k2(half %arg1) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0_k2 +; NO-FMED3F16-SAME: (half [[ARG1:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float 0.000000e+00, float 2.000000e+00) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0_k2 +; GFX9-SAME: (half [[ARG1:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG1]], half 0xH0000, half 0xH4000) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg1.ext = fpext half %arg1 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %arg1.ext, float 2.0) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_fabs(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fabs +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; NO-FMED3F16-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; NO-FMED3F16-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[FABS_ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[FABS_ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[FABS_ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fabs +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; GFX9-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; GFX9-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FABS_ARG0]], half [[FABS_ARG1]], half [[FABS_ARG2]]) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %fabs.arg0 = call half @llvm.fabs.f16(half %arg0) + %fabs.arg1 = call half @llvm.fabs.f16(half %arg1) + %fabs.arg2 = call half @llvm.fabs.f16(half %arg2) + %arg0.ext = fpext half %fabs.arg0 to float + %arg1.ext = fpext half %fabs.arg1 to float + %arg2.ext = fpext half %fabs.arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_fabs_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_fabs_f32_fpext_f16 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; NO-FMED3F16-NEXT: [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float +; NO-FMED3F16-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; NO-FMED3F16-NEXT: [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float +; NO-FMED3F16-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; NO-FMED3F16-NEXT: [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FABS_EXT_ARG0]], float [[FABS_EXT_ARG1]], float [[FABS_EXT_ARG2]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_fabs_f32_fpext_f16 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; GFX9-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; GFX9-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[TMP1]], half [[TMP2]], half [[TMP3]]) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %fabs.ext.arg0 = call float @llvm.fabs.f32(float %arg0.ext) + %fabs.ext.arg1 = call float @llvm.fabs.f32(float %arg1.ext) + %fabs.ext.arg2 = call float @llvm.fabs.f32(float %arg2.ext) + %med3 = call float @llvm.amdgcn.fmed3.f32(float %fabs.ext.arg0, float %fabs.ext.arg1, float %fabs.ext.arg2) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_fneg(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fneg +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[FNEG_ARG0:%.*]] = fneg half [[ARG0]] +; NO-FMED3F16-NEXT: [[FNEG_ARG1:%.*]] = fneg half [[ARG1]] +; NO-FMED3F16-NEXT: [[FNEG_ARG2:%.*]] = fneg half [[ARG2]] +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[FNEG_ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[FNEG_ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[FNEG_ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fneg +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[FNEG_ARG0:%.*]] = fneg half [[ARG0]] +; GFX9-NEXT: [[FNEG_ARG1:%.*]] = fneg half [[ARG1]] +; GFX9-NEXT: [[FNEG_ARG2:%.*]] = fneg half [[ARG2]] +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FNEG_ARG0]], half [[FNEG_ARG1]], half [[FNEG_ARG2]]) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %fneg.arg0 = fneg half %arg0 + %fneg.arg1 = fneg half %arg1 + %fneg.arg2 = fneg half %arg2 + %arg0.ext = fpext half %fneg.arg0 to float + %arg1.ext = fpext half %fneg.arg1 to float + %arg2.ext = fpext half %fneg.arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_fneg_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_fneg_f32_fpext_f16 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[FNEG_EXT_ARG0:%.*]] = fneg float [[ARG0_EXT]] +; NO-FMED3F16-NEXT: [[FNEG_EXT_ARG1:%.*]] = fneg float [[ARG1_EXT]] +; NO-FMED3F16-NEXT: [[FNEG_EXT_ARG2:%.*]] = fneg float [[ARG2_EXT]] +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_EXT_ARG0]], float [[FNEG_EXT_ARG1]], float [[FNEG_EXT_ARG2]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_fneg_f32_fpext_f16 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[FNEG_EXT_ARG0:%.*]] = fneg float [[ARG0_EXT]] +; GFX9-NEXT: [[FNEG_EXT_ARG1:%.*]] = fneg float [[ARG1_EXT]] +; GFX9-NEXT: [[FNEG_EXT_ARG2:%.*]] = fneg float [[ARG2_EXT]] +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_EXT_ARG0]], float [[FNEG_EXT_ARG1]], float [[FNEG_EXT_ARG2]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %fneg.ext.arg0 = fneg float %arg0.ext + %fneg.ext.arg1 = fneg float %arg1.ext + %fneg.ext.arg2 = fneg float %arg2.ext + %med3 = call float @llvm.amdgcn.fmed3.f32(float %fneg.ext.arg0, float %fneg.ext.arg1, float %fneg.ext.arg2) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_fneg_fabs(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fneg_fabs +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; NO-FMED3F16-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; NO-FMED3F16-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; NO-FMED3F16-NEXT: [[FNEG_FABS_ARG0:%.*]] = fneg half [[FABS_ARG0]] +; NO-FMED3F16-NEXT: [[FNEG_FABS_ARG1:%.*]] = fneg half [[FABS_ARG1]] +; NO-FMED3F16-NEXT: [[FNEG_FABS_ARG2:%.*]] = fneg half [[FABS_ARG2]] +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[FNEG_FABS_ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[FNEG_FABS_ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[FNEG_FABS_ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fneg_fabs +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; GFX9-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; GFX9-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; GFX9-NEXT: [[FNEG_FABS_ARG0:%.*]] = fneg half [[FABS_ARG0]] +; GFX9-NEXT: [[FNEG_FABS_ARG1:%.*]] = fneg half [[FABS_ARG1]] +; GFX9-NEXT: [[FNEG_FABS_ARG2:%.*]] = fneg half [[FABS_ARG2]] +; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FNEG_FABS_ARG0]], half [[FNEG_FABS_ARG1]], half [[FNEG_FABS_ARG2]]) +; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float +; GFX9-NEXT: ret float [[MED3]] +; + %fabs.arg0 = call half @llvm.fabs.f16(half %arg0) + %fabs.arg1 = call half @llvm.fabs.f16(half %arg1) + %fabs.arg2 = call half @llvm.fabs.f16(half %arg2) + %fneg.fabs.arg0 = fneg half %fabs.arg0 + %fneg.fabs.arg1 = fneg half %fabs.arg1 + %fneg.fabs.arg2 = fneg half %fabs.arg2 + %arg0.ext = fpext half %fneg.fabs.arg0 to float + %arg1.ext = fpext half %fneg.fabs.arg1 to float + %arg2.ext = fpext half %fneg.fabs.arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_fneg_fabs_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_fneg_fabs_f32_fpext_f16 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; NO-FMED3F16-NEXT: [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float +; NO-FMED3F16-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; NO-FMED3F16-NEXT: [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float +; NO-FMED3F16-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; NO-FMED3F16-NEXT: [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float +; NO-FMED3F16-NEXT: [[FNEG_FABS_EXT_ARG0:%.*]] = fneg float [[FABS_EXT_ARG0]] +; NO-FMED3F16-NEXT: [[FNEG_FABS_EXT_ARG1:%.*]] = fneg float [[FABS_EXT_ARG1]] +; NO-FMED3F16-NEXT: [[FNEG_FABS_EXT_ARG2:%.*]] = fneg float [[FABS_EXT_ARG2]] +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_FABS_EXT_ARG0]], float [[FNEG_FABS_EXT_ARG1]], float [[FNEG_FABS_EXT_ARG2]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_fneg_fabs_f32_fpext_f16 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) +; GFX9-NEXT: [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float +; GFX9-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) +; GFX9-NEXT: [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float +; GFX9-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) +; GFX9-NEXT: [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float +; GFX9-NEXT: [[FNEG_FABS_EXT_ARG0:%.*]] = fneg float [[FABS_EXT_ARG0]] +; GFX9-NEXT: [[FNEG_FABS_EXT_ARG1:%.*]] = fneg float [[FABS_EXT_ARG1]] +; GFX9-NEXT: [[FNEG_FABS_EXT_ARG2:%.*]] = fneg float [[FABS_EXT_ARG2]] +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_FABS_EXT_ARG0]], float [[FNEG_FABS_EXT_ARG1]], float [[FNEG_FABS_EXT_ARG2]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %fabs.ext.arg0 = call float @llvm.fabs.f32(float %arg0.ext) + %fabs.ext.arg1 = call float @llvm.fabs.f32(float %arg1.ext) + %fabs.ext.arg2 = call float @llvm.fabs.f32(float %arg2.ext) + %fneg.fabs.ext.arg0 = fneg float %fabs.ext.arg0 + %fneg.fabs.ext.arg1 = fneg float %fabs.ext.arg1 + %fneg.fabs.ext.arg2 = fneg float %fabs.ext.arg2 + %med3 = call float @llvm.amdgcn.fmed3.f32(float %fneg.fabs.ext.arg0, float %fneg.fabs.ext.arg1, float %fneg.fabs.ext.arg2) + ret float %med3 +} + +; -------------------------------------------------------------------------------- +; Negative tests +; -------------------------------------------------------------------------------- + +define float @fmed3_f32_fpext_f16_multi_use_0(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_0 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: store float [[ARG0_EXT]], ptr addrspace(1) [[PTR]], align 4 +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_0 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: store float [[ARG0_EXT]], ptr addrspace(1) [[PTR]], align 4 +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + store float %arg0.ext, ptr addrspace(1) %ptr + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_multi_use_1(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_1 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: store float [[ARG1_EXT]], ptr addrspace(1) [[PTR]], align 4 +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_1 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: store float [[ARG1_EXT]], ptr addrspace(1) [[PTR]], align 4 +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + store float %arg1.ext, ptr addrspace(1) %ptr + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_multi_use_2(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_2 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: store float [[ARG2_EXT]], ptr addrspace(1) [[PTR]], align 4 +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_2 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: store float [[ARG2_EXT]], ptr addrspace(1) [[PTR]], align 4 +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + store float %arg2.ext, ptr addrspace(1) %ptr + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_bf16(bfloat %arg0, bfloat %arg1, bfloat %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_bf16 +; NO-FMED3F16-SAME: (bfloat [[ARG0:%.*]], bfloat [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_bf16 +; GFX9-SAME: (bfloat [[ARG0:%.*]], bfloat [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext bfloat %arg0 to float + %arg1.ext = fpext bfloat %arg1 to float + %arg2.ext = fpext bfloat %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_bf16_0(bfloat %arg0, half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_0 +; NO-FMED3F16-SAME: (bfloat [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_0 +; GFX9-SAME: (bfloat [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext bfloat %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_bf16_1(half %arg0, bfloat %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_1 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], bfloat [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_1 +; GFX9-SAME: (half [[ARG0:%.*]], bfloat [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext bfloat %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_bf16_2(half %arg0, half %arg1, bfloat %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_2 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_2 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext bfloat %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_unrepresentable_k0(half %arg1, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k0 +; NO-FMED3F16-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k0 +; GFX9-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) +; GFX9-NEXT: ret float [[MED3]] +; + %arg1.ext = fpext half %arg1 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x41f0000000000000, float %arg1.ext, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_unrepresentable_k1(half %arg0, half %arg2) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k1 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k1 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg2.ext = fpext half %arg2 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float 0x41f0000000000000, float %arg2.ext) + ret float %med3 +} + +define float @fmed3_f32_fpext_f16_unrepresentable_k2(half %arg0, half %arg1) #1 { +; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k2 +; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { +; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 0x41F0000000000000) +; NO-FMED3F16-NEXT: ret float [[MED3]] +; +; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k2 +; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { +; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float +; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float +; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 0x41F0000000000000) +; GFX9-NEXT: ret float [[MED3]] +; + %arg0.ext = fpext half %arg0 to float + %arg1.ext = fpext half %arg1 to float + %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float 0x41f0000000000000) + ret float %med3 +} + + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; GFX8: {{.*}} +; UNKNOWN: {{.*}} diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/fmed3.ll b/llvm/test/Transforms/InstCombine/AMDGPU/fmed3.ll index a31b47b2ca6e7..311846b391e2b 100644 --- a/llvm/test/Transforms/InstCombine/AMDGPU/fmed3.ll +++ b/llvm/test/Transforms/InstCombine/AMDGPU/fmed3.ll @@ -1,613 +1,332 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 -; Unknown/default target -; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine < %s | FileCheck -check-prefixes=NO-FMED3F16,UNKNOWN %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine < %s | FileCheck %s +; -------------------------------------------------------------------- +; llvm.amdgcn.fmed3 +; -------------------------------------------------------------------- -; Known target, no med3_f16 -; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -passes=instcombine < %s | FileCheck -check-prefixes=NO-FMED3F16,GFX8 %s - -; Has med3_f16 -; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=instcombine < %s | FileCheck -check-prefixes=GFX9 %s - - -declare float @llvm.fabs.f32(float) #0 -declare half @llvm.fabs.f16(half) #0 declare float @llvm.amdgcn.fmed3.f32(float, float, float) #0 -define float @fmed3_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] { -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half [[ARG2]]) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_f32(float %x, float %y, float %z) #1 { +; CHECK-LABEL: define float @fmed3_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float [[Y]], float [[Z]]) +; CHECK-NEXT: ret float [[MED3]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float %z) ret float %med3 } -define float @fmed3_f32_fpext_f16_flags(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_flags -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call nsz float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_flags -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[MED31:%.*]] = call nsz half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half [[ARG2]]) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call nsz float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_canonicalize_x_c0_c1_f32(float %x) #1 { +; CHECK-LABEL: define float @fmed3_canonicalize_x_c0_c1_f32( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float 0.000000e+00, float 1.000000e+00) +; CHECK-NEXT: ret float [[MED3]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0.0, float 1.0) ret float %med3 } -define float @fmed3_f32_fpext_f16_k0(half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0 -; NO-FMED3F16-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 2.000000e+00) -; NO-FMED3F16-NEXT: ret float [[MED3]] +define float @fmed3_canonicalize_c0_x_c1_f32(float %x) #1 { +; CHECK-LABEL: define float @fmed3_canonicalize_c0_x_c1_f32( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float 0.000000e+00, float 1.000000e+00) +; CHECK-NEXT: ret float [[MED3]] ; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0 -; GFX9-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG1]], half [[ARG2]], half 0xH4000) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %x, float 1.0) + ret float %med3 +} + +define float @fmed3_canonicalize_c0_c1_x_f32(float %x) #1 { +; CHECK-LABEL: define float @fmed3_canonicalize_c0_c1_x_f32( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float 0.000000e+00, float 1.000000e+00) +; CHECK-NEXT: ret float [[MED3]] ; - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float 2.0, float %arg1.ext, float %arg2.ext) + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %x) ret float %med3 } -define float @fmed3_f32_fpext_f16_k1(half %arg0, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k1 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 2.000000e+00) -; NO-FMED3F16-NEXT: ret float [[MED3]] +define float @fmed3_canonicalize_x_y_c_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_canonicalize_x_y_c_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float [[Y]], float 1.000000e+00) +; CHECK-NEXT: ret float [[MED3]] ; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k1 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG2]], half 0xH4000) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 1.0) + ret float %med3 +} + +define float @fmed3_canonicalize_x_c_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_canonicalize_x_c_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float [[Y]], float 1.000000e+00) +; CHECK-NEXT: ret float [[MED3]] ; - %arg0.ext = fpext half %arg0 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float 2.0, float %arg2.ext) + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 1.0, float %y) ret float %med3 } -define float @fmed3_f32_fpext_f16_k2(half %arg0, half %arg1) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k2 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 2.000000e+00) -; NO-FMED3F16-NEXT: ret float [[MED3]] +define float @fmed3_canonicalize_c_x_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_canonicalize_c_x_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float [[Y]], float 1.000000e+00) +; CHECK-NEXT: ret float [[MED3]] ; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k2 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half 0xH4000) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] + %med3 = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %x, float %y) + ret float %med3 +} + +define float @fmed3_undef_x_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_undef_x_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] ; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float 2.0) + %med3 = call float @llvm.amdgcn.fmed3.f32(float undef, float %x, float %y) ret float %med3 } -define float @fmed3_f32_fpext_f16_k0_k1(half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0_k1 -; NO-FMED3F16-SAME: (half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG2_EXT]], float 0.000000e+00, float 1.600000e+01) -; NO-FMED3F16-NEXT: ret float [[MED3]] +define float @fmed3_fmf_undef_x_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_fmf_undef_x_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call nnan float @llvm.minnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] ; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0_k1 -; GFX9-SAME: (half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG2]], half 0xH0000, half 0xH4C00) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] + %med3 = call nnan float @llvm.amdgcn.fmed3.f32(float undef, float %x, float %y) + ret float %med3 +} + +define float @fmed3_x_undef_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_x_undef_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] ; - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 16.0, float %arg2.ext) + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float undef, float %y) ret float %med3 } -define float @fmed3_f32_fpext_f16_k0_k2(half %arg1) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0_k2 -; NO-FMED3F16-SAME: (half [[ARG1:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float 0.000000e+00, float 2.000000e+00) -; NO-FMED3F16-NEXT: ret float [[MED3]] +define float @fmed3_x_y_undef_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_x_y_undef_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] ; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0_k2 -; GFX9-SAME: (half [[ARG1:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG1]], half 0xH0000, half 0xH4000) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float undef) + ret float %med3 +} + +define float @fmed3_qnan0_x_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_qnan0_x_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] ; - %arg1.ext = fpext half %arg1 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %arg1.ext, float 2.0) + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000000000000, float %x, float %y) ret float %med3 } -define float @fmed3_f32_fpext_f16_fabs(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fabs -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; NO-FMED3F16-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; NO-FMED3F16-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[FABS_ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[FABS_ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[FABS_ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fabs -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; GFX9-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; GFX9-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FABS_ARG0]], half [[FABS_ARG1]], half [[FABS_ARG2]]) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] -; - %fabs.arg0 = call half @llvm.fabs.f16(half %arg0) - %fabs.arg1 = call half @llvm.fabs.f16(half %arg1) - %fabs.arg2 = call half @llvm.fabs.f16(half %arg2) - %arg0.ext = fpext half %fabs.arg0 to float - %arg1.ext = fpext half %fabs.arg1 to float - %arg2.ext = fpext half %fabs.arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_x_qnan0_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_x_qnan0_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8000000000000, float %y) ret float %med3 } -define float @fmed3_fabs_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_fabs_f32_fpext_f16 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; NO-FMED3F16-NEXT: [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float -; NO-FMED3F16-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; NO-FMED3F16-NEXT: [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float -; NO-FMED3F16-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; NO-FMED3F16-NEXT: [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FABS_EXT_ARG0]], float [[FABS_EXT_ARG1]], float [[FABS_EXT_ARG2]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_fabs_f32_fpext_f16 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; GFX9-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; GFX9-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[TMP1]], half [[TMP2]], half [[TMP3]]) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %fabs.ext.arg0 = call float @llvm.fabs.f32(float %arg0.ext) - %fabs.ext.arg1 = call float @llvm.fabs.f32(float %arg1.ext) - %fabs.ext.arg2 = call float @llvm.fabs.f32(float %arg2.ext) - %med3 = call float @llvm.amdgcn.fmed3.f32(float %fabs.ext.arg0, float %fabs.ext.arg1, float %fabs.ext.arg2) +define float @fmed3_x_y_qnan0_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_x_y_qnan0_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF8000000000000) ret float %med3 } -define float @fmed3_f32_fpext_f16_fneg(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fneg -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[FNEG_ARG0:%.*]] = fneg half [[ARG0]] -; NO-FMED3F16-NEXT: [[FNEG_ARG1:%.*]] = fneg half [[ARG1]] -; NO-FMED3F16-NEXT: [[FNEG_ARG2:%.*]] = fneg half [[ARG2]] -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[FNEG_ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[FNEG_ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[FNEG_ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fneg -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[FNEG_ARG0:%.*]] = fneg half [[ARG0]] -; GFX9-NEXT: [[FNEG_ARG1:%.*]] = fneg half [[ARG1]] -; GFX9-NEXT: [[FNEG_ARG2:%.*]] = fneg half [[ARG2]] -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FNEG_ARG0]], half [[FNEG_ARG1]], half [[FNEG_ARG2]]) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] -; - %fneg.arg0 = fneg half %arg0 - %fneg.arg1 = fneg half %arg1 - %fneg.arg2 = fneg half %arg2 - %arg0.ext = fpext half %fneg.arg0 to float - %arg1.ext = fpext half %fneg.arg1 to float - %arg2.ext = fpext half %fneg.arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_qnan1_x_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_qnan1_x_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) +; CHECK-NEXT: ret float [[MED3]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000100000000, float %x, float %y) ret float %med3 } -define float @fmed3_fneg_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_fneg_f32_fpext_f16 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[FNEG_EXT_ARG0:%.*]] = fneg float [[ARG0_EXT]] -; NO-FMED3F16-NEXT: [[FNEG_EXT_ARG1:%.*]] = fneg float [[ARG1_EXT]] -; NO-FMED3F16-NEXT: [[FNEG_EXT_ARG2:%.*]] = fneg float [[ARG2_EXT]] -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_EXT_ARG0]], float [[FNEG_EXT_ARG1]], float [[FNEG_EXT_ARG2]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_fneg_f32_fpext_f16 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[FNEG_EXT_ARG0:%.*]] = fneg float [[ARG0_EXT]] -; GFX9-NEXT: [[FNEG_EXT_ARG1:%.*]] = fneg float [[ARG1_EXT]] -; GFX9-NEXT: [[FNEG_EXT_ARG2:%.*]] = fneg float [[ARG2_EXT]] -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_EXT_ARG0]], float [[FNEG_EXT_ARG1]], float [[FNEG_EXT_ARG2]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %fneg.ext.arg0 = fneg float %arg0.ext - %fneg.ext.arg1 = fneg float %arg1.ext - %fneg.ext.arg2 = fneg float %arg2.ext - %med3 = call float @llvm.amdgcn.fmed3.f32(float %fneg.ext.arg0, float %fneg.ext.arg1, float %fneg.ext.arg2) +; This can return any of the qnans. +define float @fmed3_qnan0_qnan1_qnan2_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_qnan0_qnan1_qnan2_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 0x7FF8030000000000 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000100000000, float 0x7FF8002000000000, float 0x7FF8030000000000) ret float %med3 } -define float @fmed3_f32_fpext_f16_fneg_fabs(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fneg_fabs -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; NO-FMED3F16-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; NO-FMED3F16-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; NO-FMED3F16-NEXT: [[FNEG_FABS_ARG0:%.*]] = fneg half [[FABS_ARG0]] -; NO-FMED3F16-NEXT: [[FNEG_FABS_ARG1:%.*]] = fneg half [[FABS_ARG1]] -; NO-FMED3F16-NEXT: [[FNEG_FABS_ARG2:%.*]] = fneg half [[FABS_ARG2]] -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[FNEG_FABS_ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[FNEG_FABS_ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[FNEG_FABS_ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fneg_fabs -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; GFX9-NEXT: [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; GFX9-NEXT: [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; GFX9-NEXT: [[FNEG_FABS_ARG0:%.*]] = fneg half [[FABS_ARG0]] -; GFX9-NEXT: [[FNEG_FABS_ARG1:%.*]] = fneg half [[FABS_ARG1]] -; GFX9-NEXT: [[FNEG_FABS_ARG2:%.*]] = fneg half [[FABS_ARG2]] -; GFX9-NEXT: [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FNEG_FABS_ARG0]], half [[FNEG_FABS_ARG1]], half [[FNEG_FABS_ARG2]]) -; GFX9-NEXT: [[MED3:%.*]] = fpext half [[MED31]] to float -; GFX9-NEXT: ret float [[MED3]] -; - %fabs.arg0 = call half @llvm.fabs.f16(half %arg0) - %fabs.arg1 = call half @llvm.fabs.f16(half %arg1) - %fabs.arg2 = call half @llvm.fabs.f16(half %arg2) - %fneg.fabs.arg0 = fneg half %fabs.arg0 - %fneg.fabs.arg1 = fneg half %fabs.arg1 - %fneg.fabs.arg2 = fneg half %fabs.arg2 - %arg0.ext = fpext half %fneg.fabs.arg0 to float - %arg1.ext = fpext half %fneg.fabs.arg1 to float - %arg2.ext = fpext half %fneg.fabs.arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_constant_src0_0_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_constant_src0_0_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 5.000000e-01 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.5, float -1.0, float 4.0) ret float %med3 } -define float @fmed3_fneg_fabs_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_fneg_fabs_f32_fpext_f16 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; NO-FMED3F16-NEXT: [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float -; NO-FMED3F16-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; NO-FMED3F16-NEXT: [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float -; NO-FMED3F16-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; NO-FMED3F16-NEXT: [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float -; NO-FMED3F16-NEXT: [[FNEG_FABS_EXT_ARG0:%.*]] = fneg float [[FABS_EXT_ARG0]] -; NO-FMED3F16-NEXT: [[FNEG_FABS_EXT_ARG1:%.*]] = fneg float [[FABS_EXT_ARG1]] -; NO-FMED3F16-NEXT: [[FNEG_FABS_EXT_ARG2:%.*]] = fneg float [[FABS_EXT_ARG2]] -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_FABS_EXT_ARG0]], float [[FNEG_FABS_EXT_ARG1]], float [[FNEG_FABS_EXT_ARG2]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_fneg_fabs_f32_fpext_f16 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]]) -; GFX9-NEXT: [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float -; GFX9-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]]) -; GFX9-NEXT: [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float -; GFX9-NEXT: [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]]) -; GFX9-NEXT: [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float -; GFX9-NEXT: [[FNEG_FABS_EXT_ARG0:%.*]] = fneg float [[FABS_EXT_ARG0]] -; GFX9-NEXT: [[FNEG_FABS_EXT_ARG1:%.*]] = fneg float [[FABS_EXT_ARG1]] -; GFX9-NEXT: [[FNEG_FABS_EXT_ARG2:%.*]] = fneg float [[FABS_EXT_ARG2]] -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_FABS_EXT_ARG0]], float [[FNEG_FABS_EXT_ARG1]], float [[FNEG_FABS_EXT_ARG2]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %fabs.ext.arg0 = call float @llvm.fabs.f32(float %arg0.ext) - %fabs.ext.arg1 = call float @llvm.fabs.f32(float %arg1.ext) - %fabs.ext.arg2 = call float @llvm.fabs.f32(float %arg2.ext) - %fneg.fabs.ext.arg0 = fneg float %fabs.ext.arg0 - %fneg.fabs.ext.arg1 = fneg float %fabs.ext.arg1 - %fneg.fabs.ext.arg2 = fneg float %fabs.ext.arg2 - %med3 = call float @llvm.amdgcn.fmed3.f32(float %fneg.fabs.ext.arg0, float %fneg.fabs.ext.arg1, float %fneg.fabs.ext.arg2) +define float @fmed3_constant_src0_1_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_constant_src0_1_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 5.000000e-01 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.5, float 4.0, float -1.0) ret float %med3 } -; -------------------------------------------------------------------------------- -; Negative tests -; -------------------------------------------------------------------------------- - -define float @fmed3_f32_fpext_f16_multi_use_0(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_0 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: store float [[ARG0_EXT]], ptr addrspace(1) [[PTR]], align 4 -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_0 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: store float [[ARG0_EXT]], ptr addrspace(1) [[PTR]], align 4 -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - store float %arg0.ext, ptr addrspace(1) %ptr - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_constant_src1_0_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_constant_src1_0_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 5.000000e-01 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 0.5, float 4.0) ret float %med3 } -define float @fmed3_f32_fpext_f16_multi_use_1(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_1 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: store float [[ARG1_EXT]], ptr addrspace(1) [[PTR]], align 4 -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_1 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: store float [[ARG1_EXT]], ptr addrspace(1) [[PTR]], align 4 -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - store float %arg1.ext, ptr addrspace(1) %ptr - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_constant_src1_1_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_constant_src1_1_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 5.000000e-01 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 4.0, float 0.5, float -1.0) ret float %med3 } -define float @fmed3_f32_fpext_f16_multi_use_2(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_2 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: store float [[ARG2_EXT]], ptr addrspace(1) [[PTR]], align 4 -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_2 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: store float [[ARG2_EXT]], ptr addrspace(1) [[PTR]], align 4 -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - store float %arg2.ext, ptr addrspace(1) %ptr - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_constant_src2_0_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_constant_src2_0_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 5.000000e-01 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 4.0, float 0.5) ret float %med3 } -define float @fmed3_f32_fpext_bf16(bfloat %arg0, bfloat %arg1, bfloat %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_bf16 -; NO-FMED3F16-SAME: (bfloat [[ARG0:%.*]], bfloat [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_bf16 -; GFX9-SAME: (bfloat [[ARG0:%.*]], bfloat [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext bfloat %arg0 to float - %arg1.ext = fpext bfloat %arg1 to float - %arg2.ext = fpext bfloat %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_constant_src2_1_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_constant_src2_1_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float 5.000000e-01 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 4.0, float -1.0, float 0.5) ret float %med3 } -define float @fmed3_f32_fpext_f16_bf16_0(bfloat %arg0, half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_0 -; NO-FMED3F16-SAME: (bfloat [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_0 -; GFX9-SAME: (bfloat [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext bfloat %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_x_qnan0_qnan1_f32(float %x) #1 { +; CHECK-LABEL: define float @fmed3_x_qnan0_qnan1_f32( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float [[X]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8001000000000, float 0x7FF8002000000000) ret float %med3 } -define float @fmed3_f32_fpext_f16_bf16_1(half %arg0, bfloat %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_1 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], bfloat [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_1 -; GFX9-SAME: (half [[ARG0:%.*]], bfloat [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext bfloat %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_qnan0_x_qnan1_f32(float %x) #1 { +; CHECK-LABEL: define float @fmed3_qnan0_x_qnan1_f32( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float [[X]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float %x, float 0x7FF8002000000000) ret float %med3 } -define float @fmed3_f32_fpext_f16_bf16_2(half %arg0, half %arg1, bfloat %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_2 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_2 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]]) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext bfloat %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext) +define float @fmed3_qnan0_qnan1_x_f32(float %x) #1 { +; CHECK-LABEL: define float @fmed3_qnan0_qnan1_x_f32( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float [[X]] +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float 0x7FF8002000000000, float %x) ret float %med3 } -define float @fmed3_f32_fpext_f16_unrepresentable_k0(half %arg1, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k0 -; NO-FMED3F16-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k0 -; GFX9-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) -; GFX9-NEXT: ret float [[MED3]] -; - %arg1.ext = fpext half %arg1 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x41f0000000000000, float %arg1.ext, float %arg2.ext) +define float @fmed3_nan_0_1_f32() #1 { +; CHECK-LABEL: define float @fmed3_nan_0_1_f32( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: ret float 0.000000e+00 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8001000000000, float 0.0, float 1.0) ret float %med3 } -define float @fmed3_f32_fpext_f16_unrepresentable_k1(half %arg0, half %arg2) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k1 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k1 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg2.ext = fpext half %arg2 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float 0x41f0000000000000, float %arg2.ext) +define float @fmed3_0_nan_1_f32() #1 { +; CHECK-LABEL: define float @fmed3_0_nan_1_f32( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: ret float 0.000000e+00 +; + %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 0x7FF8001000000000, float 1.0) + ret float %med +} + +define float @fmed3_0_1_nan_f32() #1 { +; CHECK-LABEL: define float @fmed3_0_1_nan_f32( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: ret float 1.000000e+00 +; + %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0x7FF8001000000000) + ret float %med +} + +define float @fmed3_undef_0_1_f32() #1 { +; CHECK-LABEL: define float @fmed3_undef_0_1_f32( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: ret float 0.000000e+00 +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float undef, float 0.0, float 1.0) ret float %med3 } -define float @fmed3_f32_fpext_f16_unrepresentable_k2(half %arg0, half %arg1) #1 { -; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k2 -; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { -; NO-FMED3F16-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; NO-FMED3F16-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; NO-FMED3F16-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 0x41F0000000000000) -; NO-FMED3F16-NEXT: ret float [[MED3]] -; -; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k2 -; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float -; GFX9-NEXT: [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float -; GFX9-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 0x41F0000000000000) -; GFX9-NEXT: ret float [[MED3]] -; - %arg0.ext = fpext half %arg0 to float - %arg1.ext = fpext half %arg1 to float - %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float 0x41f0000000000000) +define float @fmed3_0_undef_1_f32() #1 { +; CHECK-LABEL: define float @fmed3_0_undef_1_f32( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: ret float 0.000000e+00 +; + %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float undef, float 1.0) + ret float %med +} + +define float @fmed3_0_1_undef_f32() #1 { +; CHECK-LABEL: define float @fmed3_0_1_undef_f32( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: ret float 1.000000e+00 +; + %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float undef) + ret float %med +} + +define float @fmed3_poison_x_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_poison_x_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float poison +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float poison, float %x, float %y) ret float %med3 } +define float @fmed3_x_poison_y_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_x_poison_y_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float poison +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float poison, float %y) + ret float %med3 +} + +define float @fmed3_x_y_poison_f32(float %x, float %y) #1 { +; CHECK-LABEL: define float @fmed3_x_y_poison_f32( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: ret float poison +; + %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float poison) + ret float %med3 +} attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } -attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; GFX8: {{.*}} -; UNKNOWN: {{.*}} +attributes #1 = { nounwind }