| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| |
| ; Test with "amdgpu-ieee" set to true and false |
| ; RUN: opt -S -mtriple=amdgpu6.00-amd-amdhsa -passes=instcombine < %s | FileCheck -check-prefixes=CHECK,IEEE1,HAS-IEEE-BIT1 %s |
| ; RUN: sed 's/\"true\"/\"false\"/g' %s | opt -S -mtriple=amdgpu6.00-amd-amdhsa -passes=instcombine | FileCheck -check-prefixes=CHECK,IEEE0 %s |
| |
| ; Test with gfx12 since there is no ieee bit anymore and the attribute is ignored. |
| ; RUN: opt -S -mtriple=amdgpu12.00-amd-amdhsa -passes=instcombine < %s | FileCheck -check-prefixes=CHECK,IEEE1,NO-IEEE-BIT %s |
| ; RUN: sed 's/\"true\"/\"false\"/g' %s | opt -S -mtriple=amdgpu12.00-amd-amdhsa -passes=instcombine | FileCheck -check-prefixes=CHECK,IEEE1,NO-IEEE-BIT %s |
| |
| ; -------------------------------------------------------------------- |
| ; llvm.amdgcn.fmed3 |
| ; -------------------------------------------------------------------- |
| |
| declare float @llvm.amdgcn.fmed3.f32(float, float, float) #0 |
| |
| 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_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_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]] |
| ; |
| %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]] |
| ; |
| %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) #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]] |
| ; |
| %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]] |
| ; |
| %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) #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]] |
| ; |
| %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 { |
| ; IEEE1-LABEL: define float @fmed3_undef_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_undef_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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) #1 { |
| ; IEEE1-LABEL: define float @fmed3_fmf_undef_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call nnan float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_fmf_undef_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call nnan float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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 { |
| ; IEEE1-LABEL: define float @fmed3_x_undef_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_undef_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_y_undef_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_y_undef_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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 { |
| ; IEEE1-LABEL: define float @fmed3_qnan0_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_qnan0_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_qnan0_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_qnan0_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_y_qnan0_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_y_qnan0_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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) #1 { |
| ; IEEE1-LABEL: define float @fmed3_qnan1_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_qnan1_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-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) #1 { |
| ; CHECK-LABEL: define float @fmed3_qnan0_qnan1_qnan2_f32( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float +nan(0x1800) |
| ; |
| %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) #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_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 |
| } |
| |
| 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_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_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_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 |
| } |
| |
| ; fmed3(-0, -0, +0) should match hardware median, -0 (sorted: {-0, -0, +0}, middle = -0). |
| define float @fmed3_neg0_neg0_pos0_f32() #1 { |
| ; CHECK-LABEL: define float @fmed3_neg0_neg0_pos0_f32( |
| ; CHECK-SAME: ) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float -0.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -0.0, float -0.0, float 0.0) |
| ret float %med3 |
| } |
| |
| ; fmed3(-0, +0, -0): exercises the second arm of fmed3AMDGCN (Src1 is max). |
| define float @fmed3_neg0_pos0_neg0_f32() #1 { |
| ; CHECK-LABEL: define float @fmed3_neg0_pos0_neg0_f32( |
| ; CHECK-SAME: ) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float -0.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -0.0, float 0.0, float -0.0) |
| ret float %med3 |
| } |
| |
| ; fmed3(+0, -0, -0): exercises the third arm of fmed3AMDGCN (Src2 is max). |
| define float @fmed3_pos0_neg0_neg0_f32() #1 { |
| ; CHECK-LABEL: define float @fmed3_pos0_neg0_neg0_f32( |
| ; CHECK-SAME: ) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float -0.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float -0.0, float -0.0) |
| ret float %med3 |
| } |
| |
| ; fmed3(N, -0, +0) sorted: {N, -0, +0}, median = -0. |
| define float @fmed3_negone_neg0_pos0_f32() #1 { |
| ; CHECK-LABEL: define float @fmed3_negone_neg0_pos0_f32( |
| ; CHECK-SAME: ) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float -0.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float -0.0, float 0.0) |
| ret float %med3 |
| } |
| |
| ; fmed3(-0, N, +0) sorted: {N, -0, +0}, median = -0. |
| define float @fmed3_neg0_negone_pos0_f32() #1 { |
| ; CHECK-LABEL: define float @fmed3_neg0_negone_pos0_f32( |
| ; CHECK-SAME: ) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float -0.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -0.0, float -1.0, float 0.0) |
| ret float %med3 |
| } |
| |
| ; fmed3(-0, +0, N) sorted: {N, -0, +0}, median = -0. |
| define float @fmed3_neg0_pos0_negone_f32() #1 { |
| ; CHECK-LABEL: define float @fmed3_neg0_pos0_negone_f32( |
| ; CHECK-SAME: ) #[[ATTR1]] { |
| ; CHECK-NEXT: ret float -0.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -0.0, float 0.0, float -1.0) |
| ret float %med3 |
| } |
| |
| 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_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_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_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_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 0.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_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 0.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 |
| } |
| |
| define float @fmed3_snan1_x_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_snan1_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float [[Y]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_snan1_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF4000000000000, float %x, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_snan1_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_snan1_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float [[Y]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_snan1_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF4000000000000, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_snan1_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_y_snan1_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float +nan(0x200000) |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_y_snan1_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF4000000000000) |
| ret float %med3 |
| } |
| |
| define float @fmed3_snan1_x_snan2_f32(float %x) #1 { |
| ; IEEE1-LABEL: define float @fmed3_snan1_x_snan2_f32( |
| ; IEEE1-SAME: float [[X:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float +snan(0x2) |
| ; |
| ; IEEE0-LABEL: define float @fmed3_snan1_x_snan2_f32( |
| ; IEEE0-SAME: float [[X:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: ret float [[X]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF0000020000000, float %x, float 0x7FF0000040000000) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_snan1_snan2_f32(float %x) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_snan1_snan2_f32( |
| ; IEEE1-SAME: float [[X:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float +snan(0x2) |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_snan1_snan2_f32( |
| ; IEEE0-SAME: float [[X:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: ret float [[X]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF0000020000000, float 0x7FF0000040000000) |
| ret float %med3 |
| } |
| |
| define float @fmed3_snan1_snan2_snan3_f32(float %x) #1 { |
| ; IEEE1-LABEL: define float @fmed3_snan1_snan2_snan3_f32( |
| ; IEEE1-SAME: float [[X:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float +snan(0x2) |
| ; |
| ; IEEE0-LABEL: define float @fmed3_snan1_snan2_snan3_f32( |
| ; IEEE0-SAME: float [[X:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: ret float +nan(0x2) |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF4000000000000, float 0x7FF0000020000000, float 0x7FF0000040000000) |
| ret float %med3 |
| } |
| |
| define float @fmed3_snan1_1_2_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_snan1_1_2_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float 2.000000e+00 |
| ; |
| ; IEEE0-LABEL: define float @fmed3_snan1_1_2_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: ret float 1.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF4000000000000, float 1.0, float 2.0) |
| ret float %med3 |
| } |
| |
| define float @fmed3_snan1_neg1_2_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_snan1_neg1_2_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float 2.000000e+00 |
| ; |
| ; IEEE0-LABEL: define float @fmed3_snan1_neg1_2_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: ret float -1.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -1.0, float 0x7FF4000000000000, float 2.0) |
| ret float %med3 |
| } |
| |
| define float @fmed3_neg2_3_snan1_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_neg2_3_snan1_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float +nan(0x200000) |
| ; |
| ; IEEE0-LABEL: define float @fmed3_neg2_3_snan1_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: ret float -2.000000e+00 |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float -2.0, float 3.0, float 0x7FF4000000000000) |
| ret float %med3 |
| } |
| |
| define float @fmed3_inf_x_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_inf_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_inf_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF0000000000000, float %x, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_inf_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_inf_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_inf_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF0000000000000, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_inf_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_y_inf_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_y_inf_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF0000000000000) |
| ret float %med3 |
| } |
| |
| define float @fmed3_ninf_x_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_ninf_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_ninf_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0xFFF0000000000000, float %x, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_ninf_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_ninf_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_ninf_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0xFFF0000000000000, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_ninf_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_y_ninf_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_y_ninf_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0xFFF0000000000000) |
| ret float %med3 |
| } |
| |
| ; -------------------------------------------------------------------- |
| ; llvm.amdgcn.fmed3 with default mode implied by shader CC |
| ; -------------------------------------------------------------------- |
| |
| define amdgpu_ps float @amdgpu_ps_default_fmed3_snan1_x_y_f32(float %x, float %y) { |
| ; HAS-IEEE-BIT1-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_snan1_x_y_f32( |
| ; HAS-IEEE-BIT1-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; HAS-IEEE-BIT1-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; HAS-IEEE-BIT1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_snan1_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| ; NO-IEEE-BIT-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_snan1_x_y_f32( |
| ; NO-IEEE-BIT-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; NO-IEEE-BIT-NEXT: ret float [[Y]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF4000000000000, float %x, float %y) |
| ret float %med3 |
| } |
| |
| define amdgpu_ps float @amdgpu_ps_default_fmed3_x_snan1_y_f32(float %x, float %y) { |
| ; HAS-IEEE-BIT1-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_x_snan1_y_f32( |
| ; HAS-IEEE-BIT1-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; HAS-IEEE-BIT1-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; HAS-IEEE-BIT1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_x_snan1_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| ; NO-IEEE-BIT-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_x_snan1_y_f32( |
| ; NO-IEEE-BIT-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; NO-IEEE-BIT-NEXT: ret float [[Y]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF4000000000000, float %y) |
| ret float %med3 |
| } |
| |
| define amdgpu_ps float @amdgpu_ps_default_fmed3_x_y_snan1_f32(float %x, float %y) { |
| ; HAS-IEEE-BIT1-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_x_y_snan1_f32( |
| ; HAS-IEEE-BIT1-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; HAS-IEEE-BIT1-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; HAS-IEEE-BIT1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_x_y_snan1_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| ; NO-IEEE-BIT-LABEL: define amdgpu_ps float @amdgpu_ps_default_fmed3_x_y_snan1_f32( |
| ; NO-IEEE-BIT-SAME: float [[X:%.*]], float [[Y:%.*]]) { |
| ; NO-IEEE-BIT-NEXT: ret float +nan(0x200000) |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF4000000000000) |
| ret float %med3 |
| } |
| ; -------------------------------------------------------------------- |
| ; llvm.amdgcn.fmed3 with default mode shader cc and amdgpu-ieee |
| ; -------------------------------------------------------------------- |
| |
| define amdgpu_ps float @amdgpu_ps_attr_fmed3_snan1_x_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define amdgpu_ps float @amdgpu_ps_attr_fmed3_snan1_x_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float [[Y]] |
| ; |
| ; IEEE0-LABEL: define amdgpu_ps float @amdgpu_ps_attr_fmed3_snan1_x_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF4000000000000, float %x, float %y) |
| ret float %med3 |
| } |
| |
| define amdgpu_ps float @amdgpu_ps_attr_fmed3_x_snan1_y_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define amdgpu_ps float @amdgpu_ps_attr_fmed3_x_snan1_y_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float [[Y]] |
| ; |
| ; IEEE0-LABEL: define amdgpu_ps float @amdgpu_ps_attr_fmed3_x_snan1_y_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF4000000000000, float %y) |
| ret float %med3 |
| } |
| |
| define amdgpu_ps float @amdgpu_ps_attr_fmed3_x_y_snan1_f32(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define amdgpu_ps float @amdgpu_ps_attr_fmed3_x_y_snan1_f32( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: ret float +nan(0x200000) |
| ; |
| ; IEEE0-LABEL: define amdgpu_ps float @amdgpu_ps_attr_fmed3_x_y_snan1_f32( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF4000000000000) |
| ret float %med3 |
| } |
| |
| ; -------------------------------------------------------------------- |
| ; llvm.amdgcn.fmed3 with strictfp calls |
| ; -------------------------------------------------------------------- |
| |
| define float @fmed3_qnan0_x_y_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_qnan0_x_y_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2:[0-9]+]] { |
| ; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float +qnan, float [[X]], float [[Y]]) #[[ATTR3:[0-9]+]] |
| ; CHECK-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF8000000000000, float %x, float %y) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_qnan0_y_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_x_qnan0_y_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float +qnan, float [[Y]]) #[[ATTR3]] |
| ; CHECK-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8000000000000, float %y) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_qnan0_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_x_y_qnan0_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float [[Y]], float +qnan) #[[ATTR3]] |
| ; CHECK-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF8000000000000) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_snan1_x_y_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_snan1_x_y_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float +snan(0x200000), float [[X]], float [[Y]]) #[[ATTR3]] |
| ; CHECK-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x7FF4000000000000, float %x, float %y) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_snan1_y_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_x_snan1_y_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float +snan(0x200000), float [[Y]]) #[[ATTR3]] |
| ; CHECK-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF4000000000000, float %y) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_snan1_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_x_y_snan1_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[X]], float [[Y]], float +snan(0x200000)) #[[ATTR3]] |
| ; CHECK-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF4000000000000) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_poison_x_y_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_poison_x_y_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: ret float poison |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float poison, float %x, float %y) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_poison_y_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_x_poison_y_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: ret float poison |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float poison, float %y) strictfp |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_poison_f32_strictfp(float %x, float %y) #2 { |
| ; CHECK-LABEL: define float @fmed3_x_y_poison_f32_strictfp( |
| ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] { |
| ; CHECK-NEXT: ret float poison |
| ; |
| %med3 = call float @llvm.amdgcn.fmed3.f32(float %x, float %y, float poison) strictfp |
| ret float %med3 |
| } |
| |
| ; -------------------------------------------------------------------- |
| ; llvm.amdgcn.fmed3 with flags |
| ; -------------------------------------------------------------------- |
| |
| define float @fmed3_qnan0_x_y_f32_flags(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_qnan0_x_y_f32_flags( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call ninf nsz float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_qnan0_x_y_f32_flags( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call ninf nsz float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call nsz ninf float @llvm.amdgcn.fmed3.f32(float 0x7FF8000000000000, float %x, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_qnan0_y_f32_flags(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_qnan0_y_f32_flags( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call ninf nsz float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_qnan0_y_f32_flags( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call ninf nsz float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call nsz ninf float @llvm.amdgcn.fmed3.f32(float %x, float 0x7FF8000000000000, float %y) |
| ret float %med3 |
| } |
| |
| define float @fmed3_x_y_qnan0_f32_flags(float %x, float %y) #1 { |
| ; IEEE1-LABEL: define float @fmed3_x_y_qnan0_f32_flags( |
| ; IEEE1-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE1-NEXT: [[MED3:%.*]] = call ninf nsz float @llvm.minnum.f32(float [[X]], float [[Y]]) |
| ; IEEE1-NEXT: ret float [[MED3]] |
| ; |
| ; IEEE0-LABEL: define float @fmed3_x_y_qnan0_f32_flags( |
| ; IEEE0-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1]] { |
| ; IEEE0-NEXT: [[MED3:%.*]] = call ninf nsz float @llvm.minimumnum.f32(float [[X]], float [[Y]]) |
| ; IEEE0-NEXT: ret float [[MED3]] |
| ; |
| %med3 = call nsz ninf float @llvm.amdgcn.fmed3.f32(float %x, float %y, float 0x7FF8000000000000) |
| ret float %med3 |
| } |
| |
| attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } |
| attributes #1 = { nounwind "amdgpu-ieee"="true" } |
| attributes #2 = { nounwind strictfp "amdgpu-ieee"="true" } |