1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s 2; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX89,VI %s 3; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX89,GFX9 %s 4 5; GCN-LABEL: {{^}}v_clamp_f32: 6; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 7; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 8define amdgpu_kernel void @v_clamp_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 9 %tid = call i32 @llvm.amdgcn.workitem.id.x() 10 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 11 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 12 %a = load float, float addrspace(1)* %gep0 13 %max = call float @llvm.maxnum.f32(float %a, float 0.0) 14 %med = call float @llvm.minnum.f32(float %max, float 1.0) 15 16 store float %med, float addrspace(1)* %out.gep 17 ret void 18} 19 20; GCN-LABEL: {{^}}v_clamp_neg_f32: 21; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 22; GCN: v_max_f32_e64 v{{[0-9]+}}, -[[A]], -[[A]] clamp{{$}} 23define amdgpu_kernel void @v_clamp_neg_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 24 %tid = call i32 @llvm.amdgcn.workitem.id.x() 25 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 26 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 27 %a = load float, float addrspace(1)* %gep0 28 %fneg.a = fsub float -0.0, %a 29 %max = call float @llvm.maxnum.f32(float %fneg.a, float 0.0) 30 %med = call float @llvm.minnum.f32(float %max, float 1.0) 31 32 store float %med, float addrspace(1)* %out.gep 33 ret void 34} 35 36; GCN-LABEL: {{^}}v_clamp_negabs_f32: 37; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 38; GCN: v_max_f32_e64 v{{[0-9]+}}, -|[[A]]|, -|[[A]]| clamp{{$}} 39define amdgpu_kernel void @v_clamp_negabs_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 40 %tid = call i32 @llvm.amdgcn.workitem.id.x() 41 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 42 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 43 %a = load float, float addrspace(1)* %gep0 44 %fabs.a = call float @llvm.fabs.f32(float %a) 45 %fneg.fabs.a = fsub float -0.0, %fabs.a 46 47 %max = call float @llvm.maxnum.f32(float %fneg.fabs.a, float 0.0) 48 %med = call float @llvm.minnum.f32(float %max, float 1.0) 49 50 store float %med, float addrspace(1)* %out.gep 51 ret void 52} 53 54; GCN-LABEL: {{^}}v_clamp_negzero_f32: 55; GCN-DAG: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 56; GCN-DAG: v_bfrev_b32_e32 [[SIGNBIT:v[0-9]+]], 1 57; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], [[SIGNBIT]], 1.0 58define amdgpu_kernel void @v_clamp_negzero_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 59 %tid = call i32 @llvm.amdgcn.workitem.id.x() 60 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 61 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 62 %a = load float, float addrspace(1)* %gep0 63 %max = call float @llvm.maxnum.f32(float %a, float -0.0) 64 %med = call float @llvm.minnum.f32(float %max, float 1.0) 65 66 store float %med, float addrspace(1)* %out.gep 67 ret void 68} 69 70; GCN-LABEL: {{^}}v_clamp_multi_use_max_f32: 71; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 72; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0, [[A]] 73; GCN: v_min_f32_e32 [[MIN:v[0-9]+]], 1.0, [[MAX]] 74define amdgpu_kernel void @v_clamp_multi_use_max_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 75 %tid = call i32 @llvm.amdgcn.workitem.id.x() 76 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 77 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 78 %a = load float, float addrspace(1)* %gep0 79 %max = call float @llvm.maxnum.f32(float %a, float 0.0) 80 %med = call float @llvm.minnum.f32(float %max, float 1.0) 81 82 store float %med, float addrspace(1)* %out.gep 83 store volatile float %max, float addrspace(1)* undef 84 ret void 85} 86 87; GCN-LABEL: {{^}}v_clamp_f16: 88; GCN: {{buffer|flat|global}}_load_ushort [[A:v[0-9]+]] 89; GFX89: v_max_f16_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 90 91; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], [[A]] clamp{{$}} 92; SI: v_cvt_f16_f32_e32 v{{[0-9]+}}, [[CVT]] 93define amdgpu_kernel void @v_clamp_f16(half addrspace(1)* %out, half addrspace(1)* %aptr) #0 { 94 %tid = call i32 @llvm.amdgcn.workitem.id.x() 95 %gep0 = getelementptr half, half addrspace(1)* %aptr, i32 %tid 96 %out.gep = getelementptr half, half addrspace(1)* %out, i32 %tid 97 %a = load half, half addrspace(1)* %gep0 98 %max = call half @llvm.maxnum.f16(half %a, half 0.0) 99 %med = call half @llvm.minnum.f16(half %max, half 1.0) 100 101 store half %med, half addrspace(1)* %out.gep 102 ret void 103} 104 105; GCN-LABEL: {{^}}v_clamp_neg_f16: 106; GCN: {{buffer|flat|global}}_load_ushort [[A:v[0-9]+]] 107; GFX89: v_max_f16_e64 v{{[0-9]+}}, -[[A]], -[[A]] clamp{{$}} 108 109; FIXME: Better to fold neg into max 110; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], -[[A]] clamp{{$}} 111; SI: v_cvt_f16_f32_e32 v{{[0-9]+}}, [[CVT]] 112define amdgpu_kernel void @v_clamp_neg_f16(half addrspace(1)* %out, half addrspace(1)* %aptr) #0 { 113 %tid = call i32 @llvm.amdgcn.workitem.id.x() 114 %gep0 = getelementptr half, half addrspace(1)* %aptr, i32 %tid 115 %out.gep = getelementptr half, half addrspace(1)* %out, i32 %tid 116 %a = load half, half addrspace(1)* %gep0 117 %fneg.a = fsub half -0.0, %a 118 %max = call half @llvm.maxnum.f16(half %fneg.a, half 0.0) 119 %med = call half @llvm.minnum.f16(half %max, half 1.0) 120 121 store half %med, half addrspace(1)* %out.gep 122 ret void 123} 124 125; GCN-LABEL: {{^}}v_clamp_negabs_f16: 126; GCN: {{buffer|flat|global}}_load_ushort [[A:v[0-9]+]] 127; GFX89: v_max_f16_e64 v{{[0-9]+}}, -|[[A]]|, -|[[A]]| clamp{{$}} 128 129; FIXME: Better to fold neg/abs into max 130 131; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], -|[[A]]| clamp{{$}} 132; SI: v_cvt_f16_f32_e32 v{{[0-9]+}}, [[CVT]] 133define amdgpu_kernel void @v_clamp_negabs_f16(half addrspace(1)* %out, half addrspace(1)* %aptr) #0 { 134 %tid = call i32 @llvm.amdgcn.workitem.id.x() 135 %gep0 = getelementptr half, half addrspace(1)* %aptr, i32 %tid 136 %out.gep = getelementptr half, half addrspace(1)* %out, i32 %tid 137 %a = load half, half addrspace(1)* %gep0 138 %fabs.a = call half @llvm.fabs.f16(half %a) 139 %fneg.fabs.a = fsub half -0.0, %fabs.a 140 141 %max = call half @llvm.maxnum.f16(half %fneg.fabs.a, half 0.0) 142 %med = call half @llvm.minnum.f16(half %max, half 1.0) 143 144 store half %med, half addrspace(1)* %out.gep 145 ret void 146} 147 148; FIXME: Do f64 instructions support clamp? 149; GCN-LABEL: {{^}}v_clamp_f64: 150; GCN: {{buffer|flat|global}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 151; GCN: v_max_f64 v{{\[[0-9]+:[0-9]+\]}}, [[A]], [[A]] clamp{{$}} 152define amdgpu_kernel void @v_clamp_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #0 { 153 %tid = call i32 @llvm.amdgcn.workitem.id.x() 154 %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid 155 %out.gep = getelementptr double, double addrspace(1)* %out, i32 %tid 156 %a = load double, double addrspace(1)* %gep0 157 %max = call double @llvm.maxnum.f64(double %a, double 0.0) 158 %med = call double @llvm.minnum.f64(double %max, double 1.0) 159 160 store double %med, double addrspace(1)* %out.gep 161 ret void 162} 163 164; GCN-LABEL: {{^}}v_clamp_neg_f64: 165; GCN: {{buffer|flat|global}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 166; GCN: v_max_f64 v{{\[[0-9]+:[0-9]+\]}}, -[[A]], -[[A]] clamp{{$}} 167define amdgpu_kernel void @v_clamp_neg_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #0 { 168 %tid = call i32 @llvm.amdgcn.workitem.id.x() 169 %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid 170 %out.gep = getelementptr double, double addrspace(1)* %out, i32 %tid 171 %a = load double, double addrspace(1)* %gep0 172 %fneg.a = fsub double -0.0, %a 173 %max = call double @llvm.maxnum.f64(double %fneg.a, double 0.0) 174 %med = call double @llvm.minnum.f64(double %max, double 1.0) 175 176 store double %med, double addrspace(1)* %out.gep 177 ret void 178} 179 180; GCN-LABEL: {{^}}v_clamp_negabs_f64: 181; GCN: {{buffer|flat|global}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 182; GCN: v_max_f64 v{{\[[0-9]+:[0-9]+\]}}, -|[[A]]|, -|[[A]]| clamp{{$}} 183define amdgpu_kernel void @v_clamp_negabs_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #0 { 184 %tid = call i32 @llvm.amdgcn.workitem.id.x() 185 %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid 186 %out.gep = getelementptr double, double addrspace(1)* %out, i32 %tid 187 %a = load double, double addrspace(1)* %gep0 188 %fabs.a = call double @llvm.fabs.f64(double %a) 189 %fneg.fabs.a = fsub double -0.0, %fabs.a 190 191 %max = call double @llvm.maxnum.f64(double %fneg.fabs.a, double 0.0) 192 %med = call double @llvm.minnum.f64(double %max, double 1.0) 193 194 store double %med, double addrspace(1)* %out.gep 195 ret void 196} 197 198; GCN-LABEL: {{^}}v_clamp_med3_aby_negzero_f32: 199; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 200; GCN: v_med3_f32 201define amdgpu_kernel void @v_clamp_med3_aby_negzero_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 202 %tid = call i32 @llvm.amdgcn.workitem.id.x() 203 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 204 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 205 %a = load float, float addrspace(1)* %gep0 206 %med = call float @llvm.amdgcn.fmed3.f32(float -0.0, float 1.0, float %a) 207 store float %med, float addrspace(1)* %out.gep 208 ret void 209} 210 211; GCN-LABEL: {{^}}v_clamp_med3_aby_f32: 212; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 213; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 214define amdgpu_kernel void @v_clamp_med3_aby_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 215 %tid = call i32 @llvm.amdgcn.workitem.id.x() 216 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 217 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 218 %a = load float, float addrspace(1)* %gep0 219 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %a) 220 store float %med, float addrspace(1)* %out.gep 221 ret void 222} 223 224; GCN-LABEL: {{^}}v_clamp_med3_bay_f32: 225; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 226; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 227define amdgpu_kernel void @v_clamp_med3_bay_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 228 %tid = call i32 @llvm.amdgcn.workitem.id.x() 229 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 230 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 231 %a = load float, float addrspace(1)* %gep0 232 %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float 0.0, float %a) 233 store float %med, float addrspace(1)* %out.gep 234 ret void 235} 236 237; GCN-LABEL: {{^}}v_clamp_med3_yab_f32: 238; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 239; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 240define amdgpu_kernel void @v_clamp_med3_yab_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 241 %tid = call i32 @llvm.amdgcn.workitem.id.x() 242 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 243 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 244 %a = load float, float addrspace(1)* %gep0 245 %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 0.0, float 1.0) 246 store float %med, float addrspace(1)* %out.gep 247 ret void 248} 249 250; GCN-LABEL: {{^}}v_clamp_med3_yba_f32: 251; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 252; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 253define amdgpu_kernel void @v_clamp_med3_yba_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 254 %tid = call i32 @llvm.amdgcn.workitem.id.x() 255 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 256 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 257 %a = load float, float addrspace(1)* %gep0 258 %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 1.0, float 0.0) 259 store float %med, float addrspace(1)* %out.gep 260 ret void 261} 262 263; GCN-LABEL: {{^}}v_clamp_med3_ayb_f32: 264; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 265; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 266define amdgpu_kernel void @v_clamp_med3_ayb_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 267 %tid = call i32 @llvm.amdgcn.workitem.id.x() 268 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 269 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 270 %a = load float, float addrspace(1)* %gep0 271 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %a, float 1.0) 272 store float %med, float addrspace(1)* %out.gep 273 ret void 274} 275 276; GCN-LABEL: {{^}}v_clamp_med3_bya_f32: 277; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 278; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 279define amdgpu_kernel void @v_clamp_med3_bya_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 { 280 %tid = call i32 @llvm.amdgcn.workitem.id.x() 281 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 282 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 283 %a = load float, float addrspace(1)* %gep0 284 %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %a, float 0.0) 285 store float %med, float addrspace(1)* %out.gep 286 ret void 287} 288 289; GCN-LABEL: {{^}}v_clamp_constants_to_one_f32: 290; GCN: v_mov_b32_e32 v{{[0-9]+}}, 1.0 291define amdgpu_kernel void @v_clamp_constants_to_one_f32(float addrspace(1)* %out) #0 { 292 %tid = call i32 @llvm.amdgcn.workitem.id.x() 293 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 294 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 4.0) 295 store float %med, float addrspace(1)* %out.gep 296 ret void 297} 298 299; GCN-LABEL: {{^}}v_clamp_constants_to_zero_f32: 300; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0{{$}} 301define amdgpu_kernel void @v_clamp_constants_to_zero_f32(float addrspace(1)* %out) #0 { 302 %tid = call i32 @llvm.amdgcn.workitem.id.x() 303 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 304 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float -4.0) 305 store float %med, float addrspace(1)* %out.gep 306 ret void 307} 308 309; GCN-LABEL: {{^}}v_clamp_constant_preserve_f32: 310; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0.5 311define amdgpu_kernel void @v_clamp_constant_preserve_f32(float addrspace(1)* %out) #0 { 312 %tid = call i32 @llvm.amdgcn.workitem.id.x() 313 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 314 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0.5) 315 store float %med, float addrspace(1)* %out.gep 316 ret void 317} 318 319; GCN-LABEL: {{^}}v_clamp_constant_preserve_denorm_f32: 320; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0x7fffff{{$}} 321define amdgpu_kernel void @v_clamp_constant_preserve_denorm_f32(float addrspace(1)* %out) #0 { 322 %tid = call i32 @llvm.amdgcn.workitem.id.x() 323 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 324 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float bitcast (i32 8388607 to float)) 325 store float %med, float addrspace(1)* %out.gep 326 ret void 327} 328 329; GCN-LABEL: {{^}}v_clamp_constant_qnan_f32: 330; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0{{$}} 331define amdgpu_kernel void @v_clamp_constant_qnan_f32(float addrspace(1)* %out) #0 { 332 %tid = call i32 @llvm.amdgcn.workitem.id.x() 333 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 334 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0x7FF8000000000000) 335 store float %med, float addrspace(1)* %out.gep 336 ret void 337} 338 339; GCN-LABEL: {{^}}v_clamp_constant_snan_f32: 340; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0{{$}} 341define amdgpu_kernel void @v_clamp_constant_snan_f32(float addrspace(1)* %out) #0 { 342 %tid = call i32 @llvm.amdgcn.workitem.id.x() 343 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 344 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float bitcast (i32 2139095041 to float)) 345 store float %med, float addrspace(1)* %out.gep 346 ret void 347} 348 349; --------------------------------------------------------------------- 350; Test non-default behaviors enabling snans and disabling dx10_clamp 351; --------------------------------------------------------------------- 352 353; GCN-LABEL: {{^}}v_clamp_f32_no_dx10_clamp: 354; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 355; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 0, 1.0 356define amdgpu_kernel void @v_clamp_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 357 %tid = call i32 @llvm.amdgcn.workitem.id.x() 358 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 359 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 360 %a = load float, float addrspace(1)* %gep0 361 %max = call float @llvm.maxnum.f32(float %a, float 0.0) 362 %med = call float @llvm.minnum.f32(float %max, float 1.0) 363 364 store float %med, float addrspace(1)* %out.gep 365 ret void 366} 367 368; GCN-LABEL: {{^}}v_clamp_f32_snan_dx10clamp: 369; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 370; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 371define amdgpu_kernel void @v_clamp_f32_snan_dx10clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #3 { 372 %tid = call i32 @llvm.amdgcn.workitem.id.x() 373 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 374 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 375 %a = load float, float addrspace(1)* %gep0 376 %max = call float @llvm.maxnum.f32(float %a, float 0.0) 377 %med = call float @llvm.minnum.f32(float %max, float 1.0) 378 379 store float %med, float addrspace(1)* %out.gep 380 ret void 381} 382 383; GCN-LABEL: {{^}}v_clamp_f32_snan_no_dx10clamp: 384; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 385; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0, [[A]] 386; GCN: v_min_f32_e32 [[MIN:v[0-9]+]], 1.0, [[MAX]] 387define amdgpu_kernel void @v_clamp_f32_snan_no_dx10clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #4 { 388 %tid = call i32 @llvm.amdgcn.workitem.id.x() 389 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 390 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 391 %a = load float, float addrspace(1)* %gep0 392 %max = call float @llvm.maxnum.f32(float %a, float 0.0) 393 %med = call float @llvm.minnum.f32(float %max, float 1.0) 394 395 store float %med, float addrspace(1)* %out.gep 396 ret void 397} 398 399; GCN-LABEL: {{^}}v_clamp_f32_snan_no_dx10clamp_nnan_src: 400; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 401; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 0, 1.0 402define amdgpu_kernel void @v_clamp_f32_snan_no_dx10clamp_nnan_src(float addrspace(1)* %out, float addrspace(1)* %aptr) #4 { 403 %tid = call i32 @llvm.amdgcn.workitem.id.x() 404 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 405 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 406 %a = load float, float addrspace(1)* %gep0 407 %add = fadd nnan float %a, 1.0 408 %max = call float @llvm.maxnum.f32(float %add, float 0.0) 409 %med = call float @llvm.minnum.f32(float %max, float 1.0) 410 411 store float %med, float addrspace(1)* %out.gep 412 ret void 413} 414 415; GCN-LABEL: {{^}}v_clamp_med3_aby_f32_no_dx10_clamp: 416; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 417; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 418define amdgpu_kernel void @v_clamp_med3_aby_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 419 %tid = call i32 @llvm.amdgcn.workitem.id.x() 420 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 421 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 422 %a = load float, float addrspace(1)* %gep0 423 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %a) 424 store float %med, float addrspace(1)* %out.gep 425 ret void 426} 427 428; GCN-LABEL: {{^}}v_clamp_med3_bay_f32_no_dx10_clamp: 429; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 430; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}} 431define amdgpu_kernel void @v_clamp_med3_bay_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 432 %tid = call i32 @llvm.amdgcn.workitem.id.x() 433 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 434 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 435 %a = load float, float addrspace(1)* %gep0 436 %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float 0.0, float %a) 437 store float %med, float addrspace(1)* %out.gep 438 ret void 439} 440 441; GCN-LABEL: {{^}}v_clamp_med3_yab_f32_no_dx10_clamp: 442; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 443; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 0, 1.0 444define amdgpu_kernel void @v_clamp_med3_yab_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 445 %tid = call i32 @llvm.amdgcn.workitem.id.x() 446 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 447 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 448 %a = load float, float addrspace(1)* %gep0 449 %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 0.0, float 1.0) 450 store float %med, float addrspace(1)* %out.gep 451 ret void 452} 453 454; GCN-LABEL: {{^}}v_clamp_med3_yba_f32_no_dx10_clamp: 455; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 456; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 1.0, 0 457define amdgpu_kernel void @v_clamp_med3_yba_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 458 %tid = call i32 @llvm.amdgcn.workitem.id.x() 459 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 460 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 461 %a = load float, float addrspace(1)* %gep0 462 %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 1.0, float 0.0) 463 store float %med, float addrspace(1)* %out.gep 464 ret void 465} 466 467; GCN-LABEL: {{^}}v_clamp_med3_ayb_f32_no_dx10_clamp: 468; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 469; GCN: v_med3_f32 v{{[0-9]+}}, 0, [[A]], 1.0 470define amdgpu_kernel void @v_clamp_med3_ayb_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 471 %tid = call i32 @llvm.amdgcn.workitem.id.x() 472 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 473 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 474 %a = load float, float addrspace(1)* %gep0 475 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %a, float 1.0) 476 store float %med, float addrspace(1)* %out.gep 477 ret void 478} 479 480; GCN-LABEL: {{^}}v_clamp_med3_bya_f32_no_dx10_clamp: 481; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 482; GCN: v_med3_f32 v{{[0-9]+}}, 1.0, [[A]], 0 483define amdgpu_kernel void @v_clamp_med3_bya_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 484 %tid = call i32 @llvm.amdgcn.workitem.id.x() 485 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 486 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 487 %a = load float, float addrspace(1)* %gep0 488 %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %a, float 0.0) 489 store float %med, float addrspace(1)* %out.gep 490 ret void 491} 492 493; GCN-LABEL: {{^}}v_clamp_constant_qnan_f32_no_dx10_clamp: 494; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0x7fc00000 495define amdgpu_kernel void @v_clamp_constant_qnan_f32_no_dx10_clamp(float addrspace(1)* %out) #2 { 496 %tid = call i32 @llvm.amdgcn.workitem.id.x() 497 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 498 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0x7FF8000000000000) 499 store float %med, float addrspace(1)* %out.gep 500 ret void 501} 502 503; GCN-LABEL: {{^}}v_clamp_constant_snan_f32_no_dx10_clamp: 504; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0x7f800001 505define amdgpu_kernel void @v_clamp_constant_snan_f32_no_dx10_clamp(float addrspace(1)* %out) #2 { 506 %tid = call i32 @llvm.amdgcn.workitem.id.x() 507 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid 508 %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float bitcast (i32 2139095041 to float)) 509 store float %med, float addrspace(1)* %out.gep 510 ret void 511} 512 513; GCN-LABEL: {{^}}v_clamp_v2f16: 514; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 515; GFX9-NOT: [[A]] 516; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] clamp{{$}} 517define amdgpu_kernel void @v_clamp_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 518 %tid = call i32 @llvm.amdgcn.workitem.id.x() 519 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 520 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 521 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 522 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> zeroinitializer) 523 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 524 525 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 526 ret void 527} 528 529; GCN-LABEL: {{^}}v_clamp_v2f16_undef_elt: 530; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 531; GFX9-NOT: [[A]] 532; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] clamp{{$}} 533define amdgpu_kernel void @v_clamp_v2f16_undef_elt(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 534 %tid = call i32 @llvm.amdgcn.workitem.id.x() 535 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 536 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 537 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 538 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half undef, half 0.0>) 539 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half undef>) 540 541 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 542 ret void 543} 544 545; GCN-LABEL: {{^}}v_clamp_v2f16_not_zero: 546; GFX9: v_pk_max_f16 547; GFX9: v_pk_min_f16 548define amdgpu_kernel void @v_clamp_v2f16_not_zero(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 549 %tid = call i32 @llvm.amdgcn.workitem.id.x() 550 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 551 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 552 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 553 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half 2.0, half 0.0>) 554 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 555 556 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 557 ret void 558} 559 560; GCN-LABEL: {{^}}v_clamp_v2f16_not_one: 561; GFX9: v_pk_max_f16 562; GFX9: v_pk_min_f16 563define amdgpu_kernel void @v_clamp_v2f16_not_one(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 564 %tid = call i32 @llvm.amdgcn.workitem.id.x() 565 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 566 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 567 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 568 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half 0.0, half 0.0>) 569 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 0.0, half 1.0>) 570 571 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 572 ret void 573} 574 575; GCN-LABEL: {{^}}v_clamp_neg_v2f16: 576; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 577; GFX9-NOT: [[A]] 578; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] neg_lo:[1,1] neg_hi:[1,1] clamp{{$}} 579define amdgpu_kernel void @v_clamp_neg_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 580 %tid = call i32 @llvm.amdgcn.workitem.id.x() 581 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 582 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 583 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 584 %fneg.a = fsub <2 x half> <half -0.0, half -0.0>, %a 585 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %fneg.a, <2 x half> zeroinitializer) 586 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 587 588 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 589 ret void 590} 591 592; GCN-LABEL: {{^}}v_clamp_negabs_v2f16: 593; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 594; GFX9: v_and_b32_e32 [[ABS:v[0-9]+]], 0x7fff7fff, [[A]] 595; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[ABS]], [[ABS]] neg_lo:[1,1] neg_hi:[1,1] clamp{{$}} 596define amdgpu_kernel void @v_clamp_negabs_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 597 %tid = call i32 @llvm.amdgcn.workitem.id.x() 598 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 599 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 600 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 601 %fabs.a = call <2 x half> @llvm.fabs.v2f16(<2 x half> %a) 602 %fneg.fabs.a = fsub <2 x half> <half -0.0, half -0.0>, %fabs.a 603 604 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %fneg.fabs.a, <2 x half> zeroinitializer) 605 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 606 607 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 608 ret void 609} 610 611; GCN-LABEL: {{^}}v_clamp_neglo_v2f16: 612; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 613; GFX9-NOT: [[A]] 614; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] neg_lo:[1,1] clamp{{$}} 615define amdgpu_kernel void @v_clamp_neglo_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 616 %tid = call i32 @llvm.amdgcn.workitem.id.x() 617 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 618 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 619 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 620 %lo = extractelement <2 x half> %a, i32 0 621 %neg.lo = fsub half -0.0, %lo 622 %neg.lo.vec = insertelement <2 x half> %a, half %neg.lo, i32 0 623 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %neg.lo.vec, <2 x half> zeroinitializer) 624 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 625 626 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 627 ret void 628} 629 630; GCN-LABEL: {{^}}v_clamp_neghi_v2f16: 631; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 632; GFX9-NOT: [[A]] 633; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] neg_hi:[1,1] clamp{{$}} 634define amdgpu_kernel void @v_clamp_neghi_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 635 %tid = call i32 @llvm.amdgcn.workitem.id.x() 636 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 637 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 638 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 639 %hi = extractelement <2 x half> %a, i32 1 640 %neg.hi = fsub half -0.0, %hi 641 %neg.hi.vec = insertelement <2 x half> %a, half %neg.hi, i32 1 642 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %neg.hi.vec, <2 x half> zeroinitializer) 643 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 644 645 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 646 ret void 647} 648 649; GCN-LABEL: {{^}}v_clamp_v2f16_shuffle: 650; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]] 651; GFX9-NOT: [[A]] 652; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] op_sel:[1,1] op_sel_hi:[0,0] clamp{{$}} 653define amdgpu_kernel void @v_clamp_v2f16_shuffle(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 { 654 %tid = call i32 @llvm.amdgcn.workitem.id.x() 655 %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid 656 %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid 657 %a = load <2 x half>, <2 x half> addrspace(1)* %gep0 658 %shuf = shufflevector <2 x half> %a, <2 x half> undef, <2 x i32> <i32 1, i32 0> 659 %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %shuf, <2 x half> zeroinitializer) 660 %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>) 661 662 store <2 x half> %med, <2 x half> addrspace(1)* %out.gep 663 ret void 664} 665 666declare i32 @llvm.amdgcn.workitem.id.x() #1 667declare float @llvm.fabs.f32(float) #1 668declare float @llvm.minnum.f32(float, float) #1 669declare float @llvm.maxnum.f32(float, float) #1 670declare float @llvm.amdgcn.fmed3.f32(float, float, float) #1 671declare double @llvm.fabs.f64(double) #1 672declare double @llvm.minnum.f64(double, double) #1 673declare double @llvm.maxnum.f64(double, double) #1 674declare half @llvm.fabs.f16(half) #1 675declare half @llvm.minnum.f16(half, half) #1 676declare half @llvm.maxnum.f16(half, half) #1 677declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #1 678declare <2 x half> @llvm.minnum.v2f16(<2 x half>, <2 x half>) #1 679declare <2 x half> @llvm.maxnum.v2f16(<2 x half>, <2 x half>) #1 680 681attributes #0 = { nounwind } 682attributes #1 = { nounwind readnone } 683attributes #2 = { nounwind "target-features"="-dx10-clamp,-fp-exceptions" "no-nans-fp-math"="false" } 684attributes #3 = { nounwind "target-features"="+dx10-clamp,+fp-exceptions" "no-nans-fp-math"="false" } 685attributes #4 = { nounwind "target-features"="-dx10-clamp,+fp-exceptions" "no-nans-fp-math"="false" } 686