1; RUN: llc -march=amdgcn -mcpu=hawaii -start-after=sink -mattr=+flat-for-global -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=GCN-SAFE -check-prefix=SI -check-prefix=FUNC %s 2; RUN: llc -enable-no-signed-zeros-fp-math -march=amdgcn -mcpu=hawaii -mattr=+flat-for-global -start-after=sink -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=GCN-NSZ -check-prefix=SI -check-prefix=FUNC %s 3 4; RUN: llc -march=amdgcn -mcpu=fiji -start-after=sink --verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=GCN-SAFE -check-prefix=VI -check-prefix=FUNC %s 5; RUN: llc -enable-no-signed-zeros-fp-math -march=amdgcn -mcpu=fiji -start-after=sink -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=GCN-NSZ -check-prefix=VI -check-prefix=FUNC %s 6 7; -------------------------------------------------------------------------------- 8; fadd tests 9; -------------------------------------------------------------------------------- 10 11; GCN-LABEL: {{^}}v_fneg_add_f32: 12; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 13; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 14 15; GCN-SAFE: v_add_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 16; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[ADD]] 17 18; GCN-NSZ: v_sub_f32_e64 [[RESULT:v[0-9]+]], -[[A]], [[B]] 19; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 20define amdgpu_kernel void @v_fneg_add_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 21 %tid = call i32 @llvm.amdgcn.workitem.id.x() 22 %tid.ext = sext i32 %tid to i64 23 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 24 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 25 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 26 %a = load volatile float, float addrspace(1)* %a.gep 27 %b = load volatile float, float addrspace(1)* %b.gep 28 %add = fadd float %a, %b 29 %fneg = fsub float -0.000000e+00, %add 30 store float %fneg, float addrspace(1)* %out.gep 31 ret void 32} 33 34; GCN-LABEL: {{^}}v_fneg_add_store_use_add_f32: 35; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 36; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 37; GCN-DAG: v_add_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 38; GCN-DAG: v_xor_b32_e32 [[NEG_ADD:v[0-9]+]], 0x80000000, [[ADD]] 39; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_ADD]] 40; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 41define amdgpu_kernel void @v_fneg_add_store_use_add_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 42 %tid = call i32 @llvm.amdgcn.workitem.id.x() 43 %tid.ext = sext i32 %tid to i64 44 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 45 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 46 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 47 %a = load volatile float, float addrspace(1)* %a.gep 48 %b = load volatile float, float addrspace(1)* %b.gep 49 %add = fadd float %a, %b 50 %fneg = fsub float -0.000000e+00, %add 51 store volatile float %fneg, float addrspace(1)* %out 52 store volatile float %add, float addrspace(1)* %out 53 ret void 54} 55 56; GCN-LABEL: {{^}}v_fneg_add_multi_use_add_f32: 57; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 58; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 59 60; GCN-SAFE: v_add_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 61; GCN-SAFE: v_xor_b32_e32 [[NEG_ADD:v[0-9]+]], 0x80000000, [[ADD]] 62; GCN-SAFE: v_mul_f32_e32 [[MUL:v[0-9]+]], 4.0, [[ADD]] 63 64; GCN-NSZ: v_sub_f32_e64 [[NEG_ADD:v[0-9]+]], -[[A]], [[B]] 65; GCN-NSZ-NEXT: v_mul_f32_e32 [[MUL:v[0-9]+]], -4.0, [[NEG_ADD]] 66 67; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_ADD]] 68; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 69define amdgpu_kernel void @v_fneg_add_multi_use_add_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 70 %tid = call i32 @llvm.amdgcn.workitem.id.x() 71 %tid.ext = sext i32 %tid to i64 72 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 73 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 74 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 75 %a = load volatile float, float addrspace(1)* %a.gep 76 %b = load volatile float, float addrspace(1)* %b.gep 77 %add = fadd float %a, %b 78 %fneg = fsub float -0.000000e+00, %add 79 %use1 = fmul float %add, 4.0 80 store volatile float %fneg, float addrspace(1)* %out 81 store volatile float %use1, float addrspace(1)* %out 82 ret void 83} 84 85; GCN-LABEL: {{^}}v_fneg_add_fneg_x_f32: 86; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 87; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 88 89; GCN-SAFE: v_sub_f32_e32 90; GCN-SAFE: v_xor_b32_e32 [[ADD:v[0-9]+]], 0x80000000, 91 92; GCN-NSZ: v_sub_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 93 94; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 95define amdgpu_kernel void @v_fneg_add_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 96 %tid = call i32 @llvm.amdgcn.workitem.id.x() 97 %tid.ext = sext i32 %tid to i64 98 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 99 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 100 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 101 %a = load volatile float, float addrspace(1)* %a.gep 102 %b = load volatile float, float addrspace(1)* %b.gep 103 %fneg.a = fsub float -0.000000e+00, %a 104 %add = fadd float %fneg.a, %b 105 %fneg = fsub float -0.000000e+00, %add 106 store volatile float %fneg, float addrspace(1)* %out 107 ret void 108} 109 110; GCN-LABEL: {{^}}v_fneg_add_x_fneg_f32: 111; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 112; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 113 114; GCN-SAFE: v_sub_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 115; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[ADD]] 116 117; GCN-NSZ: v_sub_f32_e32 [[ADD:v[0-9]+]], [[B]], [[A]] 118; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 119define amdgpu_kernel void @v_fneg_add_x_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 120 %tid = call i32 @llvm.amdgcn.workitem.id.x() 121 %tid.ext = sext i32 %tid to i64 122 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 123 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 124 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 125 %a = load volatile float, float addrspace(1)* %a.gep 126 %b = load volatile float, float addrspace(1)* %b.gep 127 %fneg.b = fsub float -0.000000e+00, %b 128 %add = fadd float %a, %fneg.b 129 %fneg = fsub float -0.000000e+00, %add 130 store volatile float %fneg, float addrspace(1)* %out 131 ret void 132} 133 134; GCN-LABEL: {{^}}v_fneg_add_fneg_fneg_f32: 135; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 136; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 137 138; GCN-SAFE: v_sub_f32_e64 [[ADD:v[0-9]+]], -[[A]], [[B]] 139; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[ADD]] 140 141; GCN-NSZ: v_add_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 142; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 143define amdgpu_kernel void @v_fneg_add_fneg_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 144 %tid = call i32 @llvm.amdgcn.workitem.id.x() 145 %tid.ext = sext i32 %tid to i64 146 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 147 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 148 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 149 %a = load volatile float, float addrspace(1)* %a.gep 150 %b = load volatile float, float addrspace(1)* %b.gep 151 %fneg.a = fsub float -0.000000e+00, %a 152 %fneg.b = fsub float -0.000000e+00, %b 153 %add = fadd float %fneg.a, %fneg.b 154 %fneg = fsub float -0.000000e+00, %add 155 store volatile float %fneg, float addrspace(1)* %out 156 ret void 157} 158 159; GCN-LABEL: {{^}}v_fneg_add_store_use_fneg_x_f32: 160; GCN-SAFE: s_brev_b32 [[SIGNBIT:s[0-9]+]], 1{{$}} 161; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 162; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 163 164; GCN-SAFE: v_xor_b32_e32 [[NEG_A:v[0-9]+]], [[SIGNBIT]], [[A]] 165; GCN-SAFE: v_sub_f32_e32 [[ADD:v[0-9]+]], [[B]], [[A]] 166; GCN-SAFE: v_xor_b32_e32 [[NEG_ADD:v[0-9]+]], [[SIGNBIT]], [[ADD]] 167 168; GCN-NSZ-DAG: v_xor_b32_e32 [[NEG_A:v[0-9]+]], 0x80000000, [[A]] 169; GCN-NSZ-DAG: v_sub_f32_e32 [[NEG_ADD:v[0-9]+]], [[A]], [[B]] 170; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_ADD]] 171; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_A]] 172define amdgpu_kernel void @v_fneg_add_store_use_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 173 %tid = call i32 @llvm.amdgcn.workitem.id.x() 174 %tid.ext = sext i32 %tid to i64 175 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 176 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 177 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 178 %a = load volatile float, float addrspace(1)* %a.gep 179 %b = load volatile float, float addrspace(1)* %b.gep 180 %fneg.a = fsub float -0.000000e+00, %a 181 %add = fadd float %fneg.a, %b 182 %fneg = fsub float -0.000000e+00, %add 183 store volatile float %fneg, float addrspace(1)* %out 184 store volatile float %fneg.a, float addrspace(1)* %out 185 ret void 186} 187 188; GCN-LABEL: {{^}}v_fneg_add_multi_use_fneg_x_f32: 189; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 190; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 191 192; GCN-SAFE-DAG: v_mul_f32_e64 [[MUL:v[0-9]+]], -[[A]], s{{[0-9]+}} 193; GCN-SAFE-DAG: v_sub_f32_e32 [[ADD:v[0-9]+]], [[B]], [[A]] 194; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[ADD]] 195 196; GCN-NSZ-DAG: v_sub_f32_e32 [[NEG_ADD:v[0-9]+]], [[A]], [[B]] 197; GCN-NSZ-DAG: v_mul_f32_e64 [[MUL:v[0-9]+]], -[[A]], s{{[0-9]+}} 198; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_ADD]] 199; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 200define amdgpu_kernel void @v_fneg_add_multi_use_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float %c) #0 { 201 %tid = call i32 @llvm.amdgcn.workitem.id.x() 202 %tid.ext = sext i32 %tid to i64 203 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 204 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 205 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 206 %a = load volatile float, float addrspace(1)* %a.gep 207 %b = load volatile float, float addrspace(1)* %b.gep 208 %fneg.a = fsub float -0.000000e+00, %a 209 %add = fadd float %fneg.a, %b 210 %fneg = fsub float -0.000000e+00, %add 211 %use1 = fmul float %fneg.a, %c 212 store volatile float %fneg, float addrspace(1)* %out 213 store volatile float %use1, float addrspace(1)* %out 214 ret void 215} 216 217; This one asserted with -enable-no-signed-zeros-fp-math 218; GCN-LABEL: {{^}}fneg_fadd_0: 219; GCN-SAFE-DAG: v_mad_f32 [[A:v[0-9]+]], 220; GCN-SAFE-DAG: v_cmp_ngt_f32_e32 {{.*}}, [[A]] 221; GCN-SAFE-DAG: v_cndmask_b32_e64 v{{[0-9]+}}, -[[A]] 222define amdgpu_ps float @fneg_fadd_0(float inreg %tmp2, float inreg %tmp6, <4 x i32> %arg) local_unnamed_addr #0 { 223.entry: 224 %tmp7 = fdiv float 1.000000e+00, %tmp6 225 %tmp8 = fmul float 0.000000e+00, %tmp7 226 %tmp9 = fmul reassoc nnan arcp contract float 0.000000e+00, %tmp8 227 %.i188 = fadd float %tmp9, 0.000000e+00 228 %tmp10 = fcmp uge float %.i188, %tmp2 229 %tmp11 = fsub float -0.000000e+00, %.i188 230 %.i092 = select i1 %tmp10, float %tmp2, float %tmp11 231 %tmp12 = fcmp ule float %.i092, 0.000000e+00 232 %.i198 = select i1 %tmp12, float 0.000000e+00, float 0x7FF8000000000000 233 ret float %.i198 234} 235 236; This is a workaround because -enable-no-signed-zeros-fp-math does not set up 237; function attribute unsafe-fp-math automatically. Combine with the previous test 238; when that is done. 239; GCN-LABEL: {{^}}fneg_fadd_0_nsz: 240; GCN-NSZ-DAG: v_rcp_f32_e32 [[A:v[0-9]+]], 241; GCN-NSZ-DAG: v_mov_b32_e32 [[B:v[0-9]+]], 242; GCN-NSZ-DAG: v_mov_b32_e32 [[C:v[0-9]+]], 243; GCN-NSZ-DAG: v_mul_f32_e32 [[D:v[0-9]+]], 244; GCN-NSZ-DAG: v_cmp_nlt_f32_e64 {{.*}}, -[[D]] 245define amdgpu_ps float @fneg_fadd_0_nsz(float inreg %tmp2, float inreg %tmp6, <4 x i32> %arg) local_unnamed_addr #2 { 246.entry: 247 %tmp7 = fdiv float 1.000000e+00, %tmp6 248 %tmp8 = fmul float 0.000000e+00, %tmp7 249 %tmp9 = fmul reassoc nnan arcp contract float 0.000000e+00, %tmp8 250 %.i188 = fadd float %tmp9, 0.000000e+00 251 %tmp10 = fcmp uge float %.i188, %tmp2 252 %tmp11 = fsub float -0.000000e+00, %.i188 253 %.i092 = select i1 %tmp10, float %tmp2, float %tmp11 254 %tmp12 = fcmp ule float %.i092, 0.000000e+00 255 %.i198 = select i1 %tmp12, float 0.000000e+00, float 0x7FF8000000000000 256 ret float %.i198 257} 258 259; -------------------------------------------------------------------------------- 260; fmul tests 261; -------------------------------------------------------------------------------- 262 263; GCN-LABEL: {{^}}v_fneg_mul_f32: 264; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 265; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 266; GCN: v_mul_f32_e64 [[RESULT:v[0-9]+]], [[A]], -[[B]] 267; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 268define amdgpu_kernel void @v_fneg_mul_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 269 %tid = call i32 @llvm.amdgcn.workitem.id.x() 270 %tid.ext = sext i32 %tid to i64 271 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 272 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 273 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 274 %a = load volatile float, float addrspace(1)* %a.gep 275 %b = load volatile float, float addrspace(1)* %b.gep 276 %mul = fmul float %a, %b 277 %fneg = fsub float -0.000000e+00, %mul 278 store float %fneg, float addrspace(1)* %out.gep 279 ret void 280} 281 282; GCN-LABEL: {{^}}v_fneg_mul_store_use_mul_f32: 283; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 284; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 285; GCN-DAG: v_mul_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 286; GCN-DAG: v_xor_b32_e32 [[NEG_MUL:v[0-9]+]], 0x80000000, [[ADD]] 287; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MUL]] 288; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 289define amdgpu_kernel void @v_fneg_mul_store_use_mul_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 290 %tid = call i32 @llvm.amdgcn.workitem.id.x() 291 %tid.ext = sext i32 %tid to i64 292 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 293 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 294 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 295 %a = load volatile float, float addrspace(1)* %a.gep 296 %b = load volatile float, float addrspace(1)* %b.gep 297 %mul = fmul float %a, %b 298 %fneg = fsub float -0.000000e+00, %mul 299 store volatile float %fneg, float addrspace(1)* %out 300 store volatile float %mul, float addrspace(1)* %out 301 ret void 302} 303 304; GCN-LABEL: {{^}}v_fneg_mul_multi_use_mul_f32: 305; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 306; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 307; GCN: v_mul_f32_e64 [[MUL0:v[0-9]+]], [[A]], -[[B]] 308; GCN-NEXT: v_mul_f32_e32 [[MUL1:v[0-9]+]], -4.0, [[MUL0]] 309 310; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL0]] 311; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 312define amdgpu_kernel void @v_fneg_mul_multi_use_mul_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 313 %tid = call i32 @llvm.amdgcn.workitem.id.x() 314 %tid.ext = sext i32 %tid to i64 315 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 316 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 317 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 318 %a = load volatile float, float addrspace(1)* %a.gep 319 %b = load volatile float, float addrspace(1)* %b.gep 320 %mul = fmul float %a, %b 321 %fneg = fsub float -0.000000e+00, %mul 322 %use1 = fmul float %mul, 4.0 323 store volatile float %fneg, float addrspace(1)* %out 324 store volatile float %use1, float addrspace(1)* %out 325 ret void 326} 327 328; GCN-LABEL: {{^}}v_fneg_mul_fneg_x_f32: 329; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 330; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 331; GCN: v_mul_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 332; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 333define amdgpu_kernel void @v_fneg_mul_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 334 %tid = call i32 @llvm.amdgcn.workitem.id.x() 335 %tid.ext = sext i32 %tid to i64 336 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 337 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 338 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 339 %a = load volatile float, float addrspace(1)* %a.gep 340 %b = load volatile float, float addrspace(1)* %b.gep 341 %fneg.a = fsub float -0.000000e+00, %a 342 %mul = fmul float %fneg.a, %b 343 %fneg = fsub float -0.000000e+00, %mul 344 store volatile float %fneg, float addrspace(1)* %out 345 ret void 346} 347 348; GCN-LABEL: {{^}}v_fneg_mul_x_fneg_f32: 349; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 350; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 351; GCN: v_mul_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 352; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 353define amdgpu_kernel void @v_fneg_mul_x_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 354 %tid = call i32 @llvm.amdgcn.workitem.id.x() 355 %tid.ext = sext i32 %tid to i64 356 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 357 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 358 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 359 %a = load volatile float, float addrspace(1)* %a.gep 360 %b = load volatile float, float addrspace(1)* %b.gep 361 %fneg.b = fsub float -0.000000e+00, %b 362 %mul = fmul float %a, %fneg.b 363 %fneg = fsub float -0.000000e+00, %mul 364 store volatile float %fneg, float addrspace(1)* %out 365 ret void 366} 367 368; GCN-LABEL: {{^}}v_fneg_mul_fneg_fneg_f32: 369; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 370; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 371; GCN: v_mul_f32_e64 [[ADD:v[0-9]+]], [[A]], -[[B]] 372; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 373define amdgpu_kernel void @v_fneg_mul_fneg_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 374 %tid = call i32 @llvm.amdgcn.workitem.id.x() 375 %tid.ext = sext i32 %tid to i64 376 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 377 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 378 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 379 %a = load volatile float, float addrspace(1)* %a.gep 380 %b = load volatile float, float addrspace(1)* %b.gep 381 %fneg.a = fsub float -0.000000e+00, %a 382 %fneg.b = fsub float -0.000000e+00, %b 383 %mul = fmul float %fneg.a, %fneg.b 384 %fneg = fsub float -0.000000e+00, %mul 385 store volatile float %fneg, float addrspace(1)* %out 386 ret void 387} 388 389; GCN-LABEL: {{^}}v_fneg_mul_store_use_fneg_x_f32: 390; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 391; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 392; GCN-DAG: v_xor_b32_e32 [[NEG_A:v[0-9]+]], 0x80000000, [[A]] 393; GCN-DAG: v_mul_f32_e32 [[NEG_MUL:v[0-9]+]], [[A]], [[B]] 394 395; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MUL]] 396; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_A]] 397define amdgpu_kernel void @v_fneg_mul_store_use_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 398 %tid = call i32 @llvm.amdgcn.workitem.id.x() 399 %tid.ext = sext i32 %tid to i64 400 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 401 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 402 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 403 %a = load volatile float, float addrspace(1)* %a.gep 404 %b = load volatile float, float addrspace(1)* %b.gep 405 %fneg.a = fsub float -0.000000e+00, %a 406 %mul = fmul float %fneg.a, %b 407 %fneg = fsub float -0.000000e+00, %mul 408 store volatile float %fneg, float addrspace(1)* %out 409 store volatile float %fneg.a, float addrspace(1)* %out 410 ret void 411} 412 413; GCN-LABEL: {{^}}v_fneg_mul_multi_use_fneg_x_f32: 414; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 415; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 416; GCN-DAG: v_mul_f32_e32 [[NEG_MUL:v[0-9]+]], [[A]], [[B]] 417; GCN-DAG: v_mul_f32_e64 [[MUL:v[0-9]+]], -[[A]], s{{[0-9]+}} 418; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MUL]] 419; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 420define amdgpu_kernel void @v_fneg_mul_multi_use_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float %c) #0 { 421 %tid = call i32 @llvm.amdgcn.workitem.id.x() 422 %tid.ext = sext i32 %tid to i64 423 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 424 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 425 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 426 %a = load volatile float, float addrspace(1)* %a.gep 427 %b = load volatile float, float addrspace(1)* %b.gep 428 %fneg.a = fsub float -0.000000e+00, %a 429 %mul = fmul float %fneg.a, %b 430 %fneg = fsub float -0.000000e+00, %mul 431 %use1 = fmul float %fneg.a, %c 432 store volatile float %fneg, float addrspace(1)* %out 433 store volatile float %use1, float addrspace(1)* %out 434 ret void 435} 436 437; -------------------------------------------------------------------------------- 438; fminnum tests 439; -------------------------------------------------------------------------------- 440 441; GCN-LABEL: {{^}}v_fneg_minnum_f32_ieee: 442; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 443; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 444; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_A:v[0-9]+]], -1.0, [[A]] 445; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_B:v[0-9]+]], -1.0, [[B]] 446; GCN: v_max_f32_e32 [[RESULT:v[0-9]+]], [[NEG_QUIET_A]], [[NEG_QUIET_B]] 447; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 448define amdgpu_kernel void @v_fneg_minnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 449 %tid = call i32 @llvm.amdgcn.workitem.id.x() 450 %tid.ext = sext i32 %tid to i64 451 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 452 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 453 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 454 %a = load volatile float, float addrspace(1)* %a.gep 455 %b = load volatile float, float addrspace(1)* %b.gep 456 %min = call float @llvm.minnum.f32(float %a, float %b) 457 %fneg = fsub float -0.000000e+00, %min 458 store float %fneg, float addrspace(1)* %out.gep 459 ret void 460} 461 462; GCN-LABEL: {{^}}v_fneg_minnum_f32_no_ieee: 463; GCN-NOT: v0 464; GCN-NOT: v1 465; GCN: v_max_f32_e64 v0, -v0, -v1 466; GCN-NEXT: ; return 467define amdgpu_ps float @v_fneg_minnum_f32_no_ieee(float %a, float %b) #0 { 468 %min = call float @llvm.minnum.f32(float %a, float %b) 469 %fneg = fsub float -0.000000e+00, %min 470 ret float %fneg 471} 472 473; GCN-LABEL: {{^}}v_fneg_self_minnum_f32_ieee: 474; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 475; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_A:v[0-9]+]], -1.0, [[A]] 476; GCN: v_max_f32_e32 [[RESULT:v[0-9]+]], [[NEG_QUIET_A]], [[NEG_QUIET_A]] 477; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 478define amdgpu_kernel void @v_fneg_self_minnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 479 %tid = call i32 @llvm.amdgcn.workitem.id.x() 480 %tid.ext = sext i32 %tid to i64 481 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 482 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 483 %a = load volatile float, float addrspace(1)* %a.gep 484 %min = call float @llvm.minnum.f32(float %a, float %a) 485 %min.fneg = fsub float -0.0, %min 486 store float %min.fneg, float addrspace(1)* %out.gep 487 ret void 488} 489 490; GCN-LABEL: {{^}}v_fneg_self_minnum_f32_no_ieee: 491; GCN-NOT: v0 492; GCN: v_max_f32_e64 v0, -v0, -v0 493; GCN-NEXT: ; return 494define amdgpu_ps float @v_fneg_self_minnum_f32_no_ieee(float %a) #0 { 495 %min = call float @llvm.minnum.f32(float %a, float %a) 496 %min.fneg = fsub float -0.0, %min 497 ret float %min.fneg 498} 499 500; GCN-LABEL: {{^}}v_fneg_posk_minnum_f32_ieee: 501; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 502; GCN: v_mul_f32_e32 [[QUIET_NEG_A:v[0-9]+]], -1.0, [[A]] 503; GCN: v_max_f32_e32 [[RESULT:v[0-9]+]], -4.0, [[QUIET_NEG_A]] 504; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 505define amdgpu_kernel void @v_fneg_posk_minnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 506 %tid = call i32 @llvm.amdgcn.workitem.id.x() 507 %tid.ext = sext i32 %tid to i64 508 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 509 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 510 %a = load volatile float, float addrspace(1)* %a.gep 511 %min = call float @llvm.minnum.f32(float 4.0, float %a) 512 %fneg = fsub float -0.000000e+00, %min 513 store float %fneg, float addrspace(1)* %out.gep 514 ret void 515} 516 517; GCN-LABEL: {{^}}v_fneg_posk_minnum_f32_no_ieee: 518; GCN-NOT: v0 519; GCN: v_max_f32_e64 v0, -v0, -4.0 520; GCN-NEXT: ; return 521define amdgpu_ps float @v_fneg_posk_minnum_f32_no_ieee(float %a) #0 { 522 %min = call float @llvm.minnum.f32(float 4.0, float %a) 523 %fneg = fsub float -0.000000e+00, %min 524 ret float %fneg 525} 526 527; GCN-LABEL: {{^}}v_fneg_negk_minnum_f32_ieee: 528; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 529; GCN: v_mul_f32_e32 [[QUIET_NEG_A:v[0-9]+]], -1.0, [[A]] 530; GCN: v_max_f32_e32 [[RESULT:v[0-9]+]], 4.0, [[QUIET_NEG_A]] 531; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 532define amdgpu_kernel void @v_fneg_negk_minnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 533 %tid = call i32 @llvm.amdgcn.workitem.id.x() 534 %tid.ext = sext i32 %tid to i64 535 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 536 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 537 %a = load volatile float, float addrspace(1)* %a.gep 538 %min = call float @llvm.minnum.f32(float -4.0, float %a) 539 %fneg = fsub float -0.000000e+00, %min 540 store float %fneg, float addrspace(1)* %out.gep 541 ret void 542} 543 544; GCN-LABEL: {{^}}v_fneg_negk_minnum_f32_no_ieee: 545; GCN-NOT: v0 546; GCN: v_max_f32_e64 v0, -v0, 4.0 547; GCN-NEXT: ; return 548define amdgpu_ps float @v_fneg_negk_minnum_f32_no_ieee(float %a) #0 { 549 %min = call float @llvm.minnum.f32(float -4.0, float %a) 550 %fneg = fsub float -0.000000e+00, %min 551 ret float %fneg 552} 553 554; GCN-LABEL: {{^}}v_fneg_0_minnum_f32: 555; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 556; GCN: v_min_f32_e32 [[RESULT:v[0-9]+]], 0, [[A]] 557; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 558define amdgpu_kernel void @v_fneg_0_minnum_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 559 %tid = call i32 @llvm.amdgcn.workitem.id.x() 560 %tid.ext = sext i32 %tid to i64 561 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 562 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 563 %a = load volatile float, float addrspace(1)* %a.gep 564 %min = call float @llvm.minnum.f32(float 0.0, float %a) 565 %fneg = fsub float -0.000000e+00, %min 566 store float %fneg, float addrspace(1)* %out.gep 567 ret void 568} 569 570; GCN-LABEL: {{^}}v_fneg_neg0_minnum_f32_ieee: 571; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 572; GCN: v_mul_f32_e32 [[QUIET_NEG_A:v[0-9]+]], -1.0, [[A]] 573; GCN: v_max_f32_e32 [[RESULT:v[0-9]+]], 0, [[QUIET_NEG_A]] 574; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 575define amdgpu_kernel void @v_fneg_neg0_minnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 576 %tid = call i32 @llvm.amdgcn.workitem.id.x() 577 %tid.ext = sext i32 %tid to i64 578 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 579 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 580 %a = load volatile float, float addrspace(1)* %a.gep 581 %min = call float @llvm.minnum.f32(float -0.0, float %a) 582 %fneg = fsub float -0.000000e+00, %min 583 store float %fneg, float addrspace(1)* %out.gep 584 ret void 585} 586 587; GCN-LABEL: {{^}}v_fneg_inv2pi_minnum_f32: 588; GCN-DAG: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 589 590; SI-DAG: v_mul_f32_e32 [[QUIET_NEG:v[0-9]+]], -1.0, [[A]] 591; SI: v_max_f32_e32 [[RESULT:v[0-9]+]], 0xbe22f983, [[QUIET_NEG]] 592 593; VI: v_mul_f32_e32 [[QUIET:v[0-9]+]], 1.0, [[A]] 594; VI: v_min_f32_e32 [[MAX:v[0-9]+]], 0.15915494, [[QUIET]] 595; VI: v_xor_b32_e32 [[RESULT:v[0-9]+]], 0x80000000, [[MAX]] 596 597; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 598define amdgpu_kernel void @v_fneg_inv2pi_minnum_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 599 %tid = call i32 @llvm.amdgcn.workitem.id.x() 600 %tid.ext = sext i32 %tid to i64 601 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 602 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 603 %a = load volatile float, float addrspace(1)* %a.gep 604 %min = call float @llvm.minnum.f32(float 0x3FC45F3060000000, float %a) 605 %fneg = fsub float -0.000000e+00, %min 606 store float %fneg, float addrspace(1)* %out.gep 607 ret void 608} 609 610; GCN-LABEL: {{^}}v_fneg_neg_inv2pi_minnum_f32: 611; GCN-DAG: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 612 613; SI: v_mul_f32_e32 [[NEG_QUIET:v[0-9]+]], -1.0, [[A]] 614; SI: v_max_f32_e32 [[RESULT:v[0-9]+]], 0x3e22f983, [[NEG_QUIET]] 615 616; VI: v_mul_f32_e32 [[NEG_QUIET:v[0-9]+]], -1.0, [[A]] 617; VI: v_max_f32_e32 [[RESULT:v[0-9]+]], 0.15915494, [[NEG_QUIET]] 618 619; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 620define amdgpu_kernel void @v_fneg_neg_inv2pi_minnum_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 621 %tid = call i32 @llvm.amdgcn.workitem.id.x() 622 %tid.ext = sext i32 %tid to i64 623 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 624 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 625 %a = load volatile float, float addrspace(1)* %a.gep 626 %min = call float @llvm.minnum.f32(float 0xBFC45F3060000000, float %a) 627 %fneg = fsub float -0.000000e+00, %min 628 store float %fneg, float addrspace(1)* %out.gep 629 ret void 630} 631 632; GCN-LABEL: {{^}}v_fneg_inv2pi_minnum_f16: 633; GCN-DAG: {{buffer|flat}}_load_ushort [[A:v[0-9]+]] 634 635; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], -[[A]] 636; SI: v_max_f32_e32 [[MAX:v[0-9]+]], 0xbe230000, [[CVT]] 637; SI: v_cvt_f16_f32_e32 [[RESULT:v[0-9]+]], [[MAX]] 638 639; VI: v_max_f16_e32 [[QUIET:v[0-9]+]], [[A]], [[A]] 640; VI: v_min_f16_e32 [[MAX:v[0-9]+]], 0.15915494, [[QUIET]] 641; VI: v_xor_b32_e32 [[RESULT:v[0-9]+]], 0x8000, [[MAX]] 642 643; GCN: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 644define amdgpu_kernel void @v_fneg_inv2pi_minnum_f16(half addrspace(1)* %out, half addrspace(1)* %a.ptr) #0 { 645 %tid = call i32 @llvm.amdgcn.workitem.id.x() 646 %tid.ext = sext i32 %tid to i64 647 %a.gep = getelementptr inbounds half, half addrspace(1)* %a.ptr, i64 %tid.ext 648 %out.gep = getelementptr inbounds half, half addrspace(1)* %out, i64 %tid.ext 649 %a = load volatile half, half addrspace(1)* %a.gep 650 %min = call half @llvm.minnum.f16(half 0xH3118, half %a) 651 %fneg = fsub half -0.000000e+00, %min 652 store half %fneg, half addrspace(1)* %out.gep 653 ret void 654} 655 656; GCN-LABEL: {{^}}v_fneg_neg_inv2pi_minnum_f16: 657; GCN-DAG: {{buffer|flat}}_load_ushort [[A:v[0-9]+]] 658 659; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], -[[A]] 660; SI: v_max_f32_e32 [[MAX:v[0-9]+]], 0x3e230000, [[CVT]] 661; SI: v_cvt_f16_f32_e32 [[RESULT:v[0-9]+]], [[MAX]] 662 663; VI: v_max_f16_e64 [[NEG_QUIET:v[0-9]+]], -[[A]], -[[A]] 664; VI: v_max_f16_e32 [[RESULT:v[0-9]+]], 0.15915494, [[NEG_QUIET]] 665 666; GCN: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 667define amdgpu_kernel void @v_fneg_neg_inv2pi_minnum_f16(half addrspace(1)* %out, half addrspace(1)* %a.ptr) #0 { 668 %tid = call i32 @llvm.amdgcn.workitem.id.x() 669 %tid.ext = sext i32 %tid to i64 670 %a.gep = getelementptr inbounds half, half addrspace(1)* %a.ptr, i64 %tid.ext 671 %out.gep = getelementptr inbounds half, half addrspace(1)* %out, i64 %tid.ext 672 %a = load volatile half, half addrspace(1)* %a.gep 673 %min = call half @llvm.minnum.f16(half 0xHB118, half %a) 674 %fneg = fsub half -0.000000e+00, %min 675 store half %fneg, half addrspace(1)* %out.gep 676 ret void 677} 678 679; GCN-LABEL: {{^}}v_fneg_inv2pi_minnum_f64: 680; GCN-DAG: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 681 682; SI-DAG: s_mov_b32 s[[K_HI:[0-9]+]], 0xbfc45f30 683; SI-DAG: s_mov_b32 s[[K_LO:[0-9]+]], 0x6dc9c882 684; SI-DAG: v_max_f64 [[NEG_QUIET:v\[[0-9]+:[0-9]+\]]], -[[A]], -[[A]] 685; SI: v_max_f64 v{{\[}}[[RESULT_LO:[0-9]+]]:[[RESULT_HI:[0-9]+]]{{\]}}, [[NEG_QUIET]], s{{\[}}[[K_LO]]:[[K_HI]]{{\]}} 686 687; VI: v_min_f64 v{{\[}}[[RESULT_LO:[0-9]+]]:[[RESULT_HI:[0-9]+]]{{\]}}, [[A]], 0.15915494 688; VI: v_xor_b32_e32 v[[RESULT_HI]], 0x80000000, v[[RESULT_HI]] 689 690; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[RESULT_LO]]:[[RESULT_HI]]{{\]}} 691define amdgpu_kernel void @v_fneg_inv2pi_minnum_f64(double addrspace(1)* %out, double addrspace(1)* %a.ptr) #0 { 692 %tid = call i32 @llvm.amdgcn.workitem.id.x() 693 %tid.ext = sext i32 %tid to i64 694 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 695 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 696 %a = load volatile double, double addrspace(1)* %a.gep 697 %min = call double @llvm.minnum.f64(double 0x3fc45f306dc9c882, double %a) 698 %fneg = fsub double -0.000000e+00, %min 699 store double %fneg, double addrspace(1)* %out.gep 700 ret void 701} 702 703; GCN-LABEL: {{^}}v_fneg_neg_inv2pi_minnum_f64: 704; GCN-DAG: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 705 706; SI-DAG: s_mov_b32 s[[K_HI:[0-9]+]], 0x3fc45f30 707; SI-DAG: s_mov_b32 s[[K_LO:[0-9]+]], 0x6dc9c882 708; SI-DAG: v_max_f64 [[NEG_QUIET:v\[[0-9]+:[0-9]+\]]], -[[A]], -[[A]] 709; SI: v_max_f64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[NEG_QUIET]], s{{\[}}[[K_LO]]:[[K_HI]]{{\]}} 710 711; VI: v_max_f64 [[NEG_QUIET:v\[[0-9]+:[0-9]+\]]], -[[A]], -[[A]] 712; VI: v_max_f64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[NEG_QUIET]], 0.15915494 713 714; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 715define amdgpu_kernel void @v_fneg_neg_inv2pi_minnum_f64(double addrspace(1)* %out, double addrspace(1)* %a.ptr) #0 { 716 %tid = call i32 @llvm.amdgcn.workitem.id.x() 717 %tid.ext = sext i32 %tid to i64 718 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 719 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 720 %a = load volatile double, double addrspace(1)* %a.gep 721 %min = call double @llvm.minnum.f64(double 0xbfc45f306dc9c882, double %a) 722 %fneg = fsub double -0.000000e+00, %min 723 store double %fneg, double addrspace(1)* %out.gep 724 ret void 725} 726 727; GCN-LABEL: {{^}}v_fneg_neg0_minnum_f32_no_ieee: 728; GCN-NOT: v0 729; GCN: v_max_f32_e64 v0, -v0, 0{{$}} 730; GCN-NEXT: ; return 731define amdgpu_ps float @v_fneg_neg0_minnum_f32_no_ieee(float %a) #0 { 732 %min = call float @llvm.minnum.f32(float -0.0, float %a) 733 %fneg = fsub float -0.000000e+00, %min 734 ret float %fneg 735} 736 737; GCN-LABEL: {{^}}v_fneg_0_minnum_foldable_use_f32_ieee: 738; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 739; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 740; GCN: v_mul_f32_e32 [[QUIET_A:v[0-9]+]], 1.0, [[A]] 741; GCN: v_min_f32_e32 [[MIN:v[0-9]+]], 0, [[QUIET_A]] 742; GCN: v_mul_f32_e64 [[RESULT:v[0-9]+]], -[[MIN]], [[B]] 743; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 744define amdgpu_kernel void @v_fneg_0_minnum_foldable_use_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 745 %tid = call i32 @llvm.amdgcn.workitem.id.x() 746 %tid.ext = sext i32 %tid to i64 747 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 748 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 749 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 750 %a = load volatile float, float addrspace(1)* %a.gep 751 %b = load volatile float, float addrspace(1)* %b.gep 752 %min = call float @llvm.minnum.f32(float 0.0, float %a) 753 %fneg = fsub float -0.000000e+00, %min 754 %mul = fmul float %fneg, %b 755 store float %mul, float addrspace(1)* %out.gep 756 ret void 757} 758 759; GCN-LABEL: {{^}}v_fneg_inv2pi_minnum_foldable_use_f32: 760; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 761; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 762 763; SI: v_mul_f32_e32 [[QUIET_NEG:v[0-9]+]], -1.0, [[A]] 764 765; SI: v_max_f32_e32 [[MIN:v[0-9]+]], 0xbe22f983, [[QUIET_NEG]] 766; SI: v_mul_f32_e32 [[RESULT:v[0-9]+]], [[MIN]], [[B]] 767 768; VI: v_mul_f32_e32 [[QUIET:v[0-9]+]], 1.0, [[A]] 769; VI: v_min_f32_e32 [[MIN:v[0-9]+]], 0.15915494, [[QUIET]] 770; VI: v_mul_f32_e64 [[RESULT:v[0-9]+]], -[[MIN]], [[B]] 771 772; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 773define amdgpu_kernel void @v_fneg_inv2pi_minnum_foldable_use_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 774 %tid = call i32 @llvm.amdgcn.workitem.id.x() 775 %tid.ext = sext i32 %tid to i64 776 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 777 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 778 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 779 %a = load volatile float, float addrspace(1)* %a.gep 780 %b = load volatile float, float addrspace(1)* %b.gep 781 %min = call float @llvm.minnum.f32(float 0x3FC45F3060000000, float %a) 782 %fneg = fsub float -0.000000e+00, %min 783 %mul = fmul float %fneg, %b 784 store float %mul, float addrspace(1)* %out.gep 785 ret void 786} 787 788; GCN-LABEL: {{^}}v_fneg_0_minnum_foldable_use_f32_no_ieee: 789; GCN-NOT: v0 790; GCN-NOT: v1 791; GCN: v_min_f32_e32 [[MIN:v[0-9]+]], 0, v0 792; GCN: v_mul_f32_e64 [[RESULT:v[0-9]+]], -[[MIN]], v1 793; GCN-NEXT: ; return 794define amdgpu_ps float @v_fneg_0_minnum_foldable_use_f32_no_ieee(float %a, float %b) #0 { 795 %min = call float @llvm.minnum.f32(float 0.0, float %a) 796 %fneg = fsub float -0.000000e+00, %min 797 %mul = fmul float %fneg, %b 798 ret float %mul 799} 800 801; GCN-LABEL: {{^}}v_fneg_minnum_multi_use_minnum_f32_ieee: 802; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 803; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 804; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_A:v[0-9]+]], -1.0, [[A]] 805; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_B:v[0-9]+]], -1.0, [[B]] 806; GCN: v_max_f32_e32 [[MAX0:v[0-9]+]], [[NEG_QUIET_A]], [[NEG_QUIET_B]] 807; GCN-NEXT: v_mul_f32_e32 [[MUL1:v[0-9]+]], -4.0, [[MAX0]] 808; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MAX0]] 809; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 810define amdgpu_kernel void @v_fneg_minnum_multi_use_minnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 811 %tid = call i32 @llvm.amdgcn.workitem.id.x() 812 %tid.ext = sext i32 %tid to i64 813 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 814 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 815 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 816 %a = load volatile float, float addrspace(1)* %a.gep 817 %b = load volatile float, float addrspace(1)* %b.gep 818 %min = call float @llvm.minnum.f32(float %a, float %b) 819 %fneg = fsub float -0.000000e+00, %min 820 %use1 = fmul float %min, 4.0 821 store volatile float %fneg, float addrspace(1)* %out 822 store volatile float %use1, float addrspace(1)* %out 823 ret void 824} 825 826; GCN-LABEL: {{^}}v_fneg_minnum_multi_use_minnum_f32_no_ieee: 827; GCN-NOT: v0 828; GCN-NOT: v1 829; GCN: v_max_f32_e64 v0, -v0, -v1 830; GCN-NEXT: v_mul_f32_e32 v1, -4.0, v0 831; GCN-NEXT: ; return 832define amdgpu_ps <2 x float> @v_fneg_minnum_multi_use_minnum_f32_no_ieee(float %a, float %b) #0 { 833 %min = call float @llvm.minnum.f32(float %a, float %b) 834 %fneg = fsub float -0.000000e+00, %min 835 %use1 = fmul float %min, 4.0 836 %ins0 = insertelement <2 x float> undef, float %fneg, i32 0 837 %ins1 = insertelement <2 x float> %ins0, float %use1, i32 1 838 ret <2 x float> %ins1 839} 840 841; -------------------------------------------------------------------------------- 842; fmaxnum tests 843; -------------------------------------------------------------------------------- 844 845 846; GCN-LABEL: {{^}}v_fneg_maxnum_f32_ieee: 847; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 848; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 849; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_A:v[0-9]+]], -1.0, [[A]] 850; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_B:v[0-9]+]], -1.0, [[B]] 851; GCN: v_min_f32_e32 [[RESULT:v[0-9]+]], [[NEG_QUIET_A]], [[NEG_QUIET_B]] 852; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 853define amdgpu_kernel void @v_fneg_maxnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 854 %tid = call i32 @llvm.amdgcn.workitem.id.x() 855 %tid.ext = sext i32 %tid to i64 856 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 857 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 858 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 859 %a = load volatile float, float addrspace(1)* %a.gep 860 %b = load volatile float, float addrspace(1)* %b.gep 861 %max = call float @llvm.maxnum.f32(float %a, float %b) 862 %fneg = fsub float -0.000000e+00, %max 863 store float %fneg, float addrspace(1)* %out.gep 864 ret void 865} 866 867; GCN-LABEL: {{^}}v_fneg_maxnum_f32_no_ieee: 868; GCN-NOT: v0 869; GCN-NOT: v1 870; GCN: v_min_f32_e64 v0, -v0, -v1 871; GCN-NEXT: ; return 872define amdgpu_ps float @v_fneg_maxnum_f32_no_ieee(float %a, float %b) #0 { 873 %max = call float @llvm.maxnum.f32(float %a, float %b) 874 %fneg = fsub float -0.000000e+00, %max 875 ret float %fneg 876} 877 878; GCN-LABEL: {{^}}v_fneg_self_maxnum_f32_ieee: 879; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 880; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_A:v[0-9]+]], -1.0, [[A]] 881; GCN: v_min_f32_e32 [[RESULT:v[0-9]+]], [[NEG_QUIET_A]], [[NEG_QUIET_A]] 882; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 883define amdgpu_kernel void @v_fneg_self_maxnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 884 %tid = call i32 @llvm.amdgcn.workitem.id.x() 885 %tid.ext = sext i32 %tid to i64 886 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 887 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 888 %a = load volatile float, float addrspace(1)* %a.gep 889 %max = call float @llvm.maxnum.f32(float %a, float %a) 890 %max.fneg = fsub float -0.0, %max 891 store float %max.fneg, float addrspace(1)* %out.gep 892 ret void 893} 894 895; GCN-LABEL: {{^}}v_fneg_self_maxnum_f32_no_ieee: 896; GCN-NOT: v0 897; GCN: v_min_f32_e64 v0, -v0, -v0 898; GCN-NEXT: ; return 899define amdgpu_ps float @v_fneg_self_maxnum_f32_no_ieee(float %a) #0 { 900 %max = call float @llvm.maxnum.f32(float %a, float %a) 901 %max.fneg = fsub float -0.0, %max 902 ret float %max.fneg 903} 904 905; GCN-LABEL: {{^}}v_fneg_posk_maxnum_f32_ieee: 906; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 907; GCN: v_mul_f32_e32 [[QUIET_NEG_A:v[0-9]+]], -1.0, [[A]] 908; GCN: v_min_f32_e32 [[RESULT:v[0-9]+]], -4.0, [[QUIET_NEG_A]] 909; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 910define amdgpu_kernel void @v_fneg_posk_maxnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 911 %tid = call i32 @llvm.amdgcn.workitem.id.x() 912 %tid.ext = sext i32 %tid to i64 913 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 914 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 915 %a = load volatile float, float addrspace(1)* %a.gep 916 %max = call float @llvm.maxnum.f32(float 4.0, float %a) 917 %fneg = fsub float -0.000000e+00, %max 918 store float %fneg, float addrspace(1)* %out.gep 919 ret void 920} 921 922; GCN-LABEL: {{^}}v_fneg_posk_maxnum_f32_no_ieee: 923; GCN-NOT: v0 924; GCN: v_min_f32_e64 v0, -v0, -4.0 925; GCN-NEXT: ; return 926define amdgpu_ps float @v_fneg_posk_maxnum_f32_no_ieee(float %a) #0 { 927 %max = call float @llvm.maxnum.f32(float 4.0, float %a) 928 %fneg = fsub float -0.000000e+00, %max 929 ret float %fneg 930} 931 932; GCN-LABEL: {{^}}v_fneg_negk_maxnum_f32_ieee: 933; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 934; GCN: v_mul_f32_e32 [[QUIET_NEG_A:v[0-9]+]], -1.0, [[A]] 935; GCN: v_min_f32_e32 [[RESULT:v[0-9]+]], 4.0, [[QUIET_NEG_A]] 936; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 937define amdgpu_kernel void @v_fneg_negk_maxnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 938 %tid = call i32 @llvm.amdgcn.workitem.id.x() 939 %tid.ext = sext i32 %tid to i64 940 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 941 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 942 %a = load volatile float, float addrspace(1)* %a.gep 943 %max = call float @llvm.maxnum.f32(float -4.0, float %a) 944 %fneg = fsub float -0.000000e+00, %max 945 store float %fneg, float addrspace(1)* %out.gep 946 ret void 947} 948 949; GCN-LABEL: {{^}}v_fneg_negk_maxnum_f32_no_ieee: 950; GCN-NOT: v0 951; GCN: v_min_f32_e64 v0, -v0, 4.0 952; GCN-NEXT: ; return 953define amdgpu_ps float @v_fneg_negk_maxnum_f32_no_ieee(float %a) #0 { 954 %max = call float @llvm.maxnum.f32(float -4.0, float %a) 955 %fneg = fsub float -0.000000e+00, %max 956 ret float %fneg 957} 958 959; GCN-LABEL: {{^}}v_fneg_0_maxnum_f32: 960; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 961; GCN: v_max_f32_e32 [[RESULT:v[0-9]+]], 0, [[A]] 962; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 963define amdgpu_kernel void @v_fneg_0_maxnum_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 964 %tid = call i32 @llvm.amdgcn.workitem.id.x() 965 %tid.ext = sext i32 %tid to i64 966 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 967 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 968 %a = load volatile float, float addrspace(1)* %a.gep 969 %max = call float @llvm.maxnum.f32(float 0.0, float %a) 970 %fneg = fsub float -0.000000e+00, %max 971 store float %fneg, float addrspace(1)* %out.gep 972 ret void 973} 974 975; GCN-LABEL: {{^}}v_fneg_neg0_maxnum_f32_ieee: 976; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 977; GCN: v_mul_f32_e32 [[QUIET_NEG_A:v[0-9]+]], -1.0, [[A]] 978; GCN: v_min_f32_e32 [[RESULT:v[0-9]+]], 0, [[QUIET_NEG_A]] 979; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 980define amdgpu_kernel void @v_fneg_neg0_maxnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 981 %tid = call i32 @llvm.amdgcn.workitem.id.x() 982 %tid.ext = sext i32 %tid to i64 983 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 984 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 985 %a = load volatile float, float addrspace(1)* %a.gep 986 %max = call float @llvm.maxnum.f32(float -0.0, float %a) 987 %fneg = fsub float -0.000000e+00, %max 988 store float %fneg, float addrspace(1)* %out.gep 989 ret void 990} 991 992; GCN-LABEL: {{^}}v_fneg_neg0_maxnum_f32_no_ieee: 993; GCN-NOT: v0 994; GCN: v_min_f32_e64 v0, -v0, 0{{$}} 995; GCN-NEXT: ; return 996define amdgpu_ps float @v_fneg_neg0_maxnum_f32_no_ieee(float %a) #0 { 997 %max = call float @llvm.maxnum.f32(float -0.0, float %a) 998 %fneg = fsub float -0.000000e+00, %max 999 ret float %fneg 1000} 1001 1002; GCN-LABEL: {{^}}v_fneg_0_maxnum_foldable_use_f32_ieee: 1003; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1004; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1005; GCN: v_mul_f32_e32 [[QUIET_A:v[0-9]+]], 1.0, [[A]] 1006; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0, [[QUIET_A]] 1007; GCN: v_mul_f32_e64 [[RESULT:v[0-9]+]], -[[MAX]], [[B]] 1008; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1009define amdgpu_kernel void @v_fneg_0_maxnum_foldable_use_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1010 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1011 %tid.ext = sext i32 %tid to i64 1012 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1013 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1014 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1015 %a = load volatile float, float addrspace(1)* %a.gep 1016 %b = load volatile float, float addrspace(1)* %b.gep 1017 %max = call float @llvm.maxnum.f32(float 0.0, float %a) 1018 %fneg = fsub float -0.000000e+00, %max 1019 %mul = fmul float %fneg, %b 1020 store float %mul, float addrspace(1)* %out.gep 1021 ret void 1022} 1023 1024; GCN-LABEL: {{^}}v_fneg_0_maxnum_foldable_use_f32_no_ieee: 1025; GCN-NOT: v0 1026; GCN-NOT: v1 1027; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0, v0 1028; GCN: v_mul_f32_e64 [[RESULT:v[0-9]+]], -[[MAX]], v1 1029; GCN-NEXT: ; return 1030define amdgpu_ps float @v_fneg_0_maxnum_foldable_use_f32_no_ieee(float %a, float %b) #0 { 1031 %max = call float @llvm.maxnum.f32(float 0.0, float %a) 1032 %fneg = fsub float -0.000000e+00, %max 1033 %mul = fmul float %fneg, %b 1034 ret float %mul 1035} 1036 1037; GCN-LABEL: {{^}}v_fneg_maxnum_multi_use_maxnum_f32_ieee: 1038; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1039; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1040; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_A:v[0-9]+]], -1.0, [[A]] 1041; GCN-DAG: v_mul_f32_e32 [[NEG_QUIET_B:v[0-9]+]], -1.0, [[B]] 1042; GCN: v_min_f32_e32 [[MAX0:v[0-9]+]], [[NEG_QUIET_A]], [[NEG_QUIET_B]] 1043; GCN-NEXT: v_mul_f32_e32 [[MUL1:v[0-9]+]], -4.0, [[MAX0]] 1044; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MAX0]] 1045; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 1046define amdgpu_kernel void @v_fneg_maxnum_multi_use_maxnum_f32_ieee(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1047 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1048 %tid.ext = sext i32 %tid to i64 1049 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1050 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1051 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1052 %a = load volatile float, float addrspace(1)* %a.gep 1053 %b = load volatile float, float addrspace(1)* %b.gep 1054 %max = call float @llvm.maxnum.f32(float %a, float %b) 1055 %fneg = fsub float -0.000000e+00, %max 1056 %use1 = fmul float %max, 4.0 1057 store volatile float %fneg, float addrspace(1)* %out 1058 store volatile float %use1, float addrspace(1)* %out 1059 ret void 1060} 1061 1062; GCN-LABEL: {{^}}v_fneg_maxnum_multi_use_maxnum_f32_no_ieee: 1063; GCN-NOT: v0 1064; GCN-NOT: v1 1065; GCN: v_min_f32_e64 v0, -v0, -v1 1066; GCN-NEXT: v_mul_f32_e32 v1, -4.0, v0 1067; GCN-NEXT: ; return 1068define amdgpu_ps <2 x float> @v_fneg_maxnum_multi_use_maxnum_f32_no_ieee(float %a, float %b) #0 { 1069 %max = call float @llvm.maxnum.f32(float %a, float %b) 1070 %fneg = fsub float -0.000000e+00, %max 1071 %use1 = fmul float %max, 4.0 1072 %ins0 = insertelement <2 x float> undef, float %fneg, i32 0 1073 %ins1 = insertelement <2 x float> %ins0, float %use1, i32 1 1074 ret <2 x float> %ins1 1075} 1076 1077; -------------------------------------------------------------------------------- 1078; fma tests 1079; -------------------------------------------------------------------------------- 1080 1081; GCN-LABEL: {{^}}v_fneg_fma_f32: 1082; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1083; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1084; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1085 1086; GCN-SAFE: v_fma_f32 [[RESULT:v[0-9]+]], [[A]], [[B]], [[C]] 1087; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[RESULT]] 1088 1089; GCN-NSZ: v_fma_f32 [[RESULT:v[0-9]+]], [[A]], -[[B]], -[[C]] 1090; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1091define amdgpu_kernel void @v_fneg_fma_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1092 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1093 %tid.ext = sext i32 %tid to i64 1094 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1095 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1096 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1097 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1098 %a = load volatile float, float addrspace(1)* %a.gep 1099 %b = load volatile float, float addrspace(1)* %b.gep 1100 %c = load volatile float, float addrspace(1)* %c.gep 1101 %fma = call float @llvm.fma.f32(float %a, float %b, float %c) 1102 %fneg = fsub float -0.000000e+00, %fma 1103 store float %fneg, float addrspace(1)* %out.gep 1104 ret void 1105} 1106 1107; GCN-LABEL: {{^}}v_fneg_fma_store_use_fma_f32: 1108; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1109; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1110; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1111; GCN-DAG: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], [[C]] 1112; GCN-DAG: v_xor_b32_e32 [[NEG_FMA:v[0-9]+]], 0x80000000, [[FMA]] 1113; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_FMA]] 1114; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1115define amdgpu_kernel void @v_fneg_fma_store_use_fma_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1116 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1117 %tid.ext = sext i32 %tid to i64 1118 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1119 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1120 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1121 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1122 %a = load volatile float, float addrspace(1)* %a.gep 1123 %b = load volatile float, float addrspace(1)* %b.gep 1124 %c = load volatile float, float addrspace(1)* %c.gep 1125 %fma = call float @llvm.fma.f32(float %a, float %b, float %c) 1126 %fneg = fsub float -0.000000e+00, %fma 1127 store volatile float %fneg, float addrspace(1)* %out 1128 store volatile float %fma, float addrspace(1)* %out 1129 ret void 1130} 1131 1132; GCN-LABEL: {{^}}v_fneg_fma_multi_use_fma_f32: 1133; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1134; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1135; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1136 1137; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], [[C]] 1138; GCN-SAFE: v_xor_b32_e32 [[NEG_FMA:v[0-9]+]], 0x80000000, [[FMA]] 1139; GCN-SAFE: v_mul_f32_e32 [[MUL:v[0-9]+]], 4.0, [[FMA]] 1140 1141; GCN-NSZ: v_fma_f32 [[NEG_FMA:v[0-9]+]], [[A]], -[[B]], -[[C]] 1142; GCN-NSZ-NEXT: v_mul_f32_e32 [[MUL:v[0-9]+]], -4.0, [[NEG_FMA]] 1143 1144; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_FMA]] 1145; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1146define amdgpu_kernel void @v_fneg_fma_multi_use_fma_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1147 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1148 %tid.ext = sext i32 %tid to i64 1149 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1150 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1151 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1152 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1153 %a = load volatile float, float addrspace(1)* %a.gep 1154 %b = load volatile float, float addrspace(1)* %b.gep 1155 %c = load volatile float, float addrspace(1)* %c.gep 1156 %fma = call float @llvm.fma.f32(float %a, float %b, float %c) 1157 %fneg = fsub float -0.000000e+00, %fma 1158 %use1 = fmul float %fma, 4.0 1159 store volatile float %fneg, float addrspace(1)* %out 1160 store volatile float %use1, float addrspace(1)* %out 1161 ret void 1162} 1163 1164; GCN-LABEL: {{^}}v_fneg_fma_fneg_x_y_f32: 1165; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1166; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1167; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1168 1169; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]], -[[A]], [[B]], [[C]] 1170; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[FMA]] 1171 1172; GCN-NSZ: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], -[[C]] 1173; GCN-NSZ-NOT: [[FMA]] 1174; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1175define amdgpu_kernel void @v_fneg_fma_fneg_x_y_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1176 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1177 %tid.ext = sext i32 %tid to i64 1178 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1179 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1180 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1181 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1182 %a = load volatile float, float addrspace(1)* %a.gep 1183 %b = load volatile float, float addrspace(1)* %b.gep 1184 %c = load volatile float, float addrspace(1)* %c.gep 1185 %fneg.a = fsub float -0.000000e+00, %a 1186 %fma = call float @llvm.fma.f32(float %fneg.a, float %b, float %c) 1187 %fneg = fsub float -0.000000e+00, %fma 1188 store volatile float %fneg, float addrspace(1)* %out 1189 ret void 1190} 1191 1192; GCN-LABEL: {{^}}v_fneg_fma_x_fneg_y_f32: 1193; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1194; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1195; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1196 1197; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]], [[A]], -[[B]], [[C]] 1198; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[FMA]] 1199 1200; GCN-NSZ: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], -[[C]] 1201; GCN-NSZ-NOT: [[FMA]] 1202; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1203define amdgpu_kernel void @v_fneg_fma_x_fneg_y_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1204 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1205 %tid.ext = sext i32 %tid to i64 1206 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1207 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1208 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1209 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1210 %a = load volatile float, float addrspace(1)* %a.gep 1211 %b = load volatile float, float addrspace(1)* %b.gep 1212 %c = load volatile float, float addrspace(1)* %c.gep 1213 %fneg.b = fsub float -0.000000e+00, %b 1214 %fma = call float @llvm.fma.f32(float %a, float %fneg.b, float %c) 1215 %fneg = fsub float -0.000000e+00, %fma 1216 store volatile float %fneg, float addrspace(1)* %out 1217 ret void 1218} 1219 1220; GCN-LABEL: {{^}}v_fneg_fma_fneg_fneg_y_f32: 1221; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1222; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1223; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1224 1225; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], [[C]] 1226; GCN-SAFE: v_xor_b32_e32 v{{[[0-9]+}}, 0x80000000, [[FMA]] 1227 1228; GCN-NSZ: v_fma_f32 [[FMA:v[0-9]+]], [[A]], -[[B]], -[[C]] 1229; GCN-NSZ-NOT: [[FMA]] 1230; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1231define amdgpu_kernel void @v_fneg_fma_fneg_fneg_y_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1232 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1233 %tid.ext = sext i32 %tid to i64 1234 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1235 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1236 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1237 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1238 %a = load volatile float, float addrspace(1)* %a.gep 1239 %b = load volatile float, float addrspace(1)* %b.gep 1240 %c = load volatile float, float addrspace(1)* %c.gep 1241 %fneg.a = fsub float -0.000000e+00, %a 1242 %fneg.b = fsub float -0.000000e+00, %b 1243 %fma = call float @llvm.fma.f32(float %fneg.a, float %fneg.b, float %c) 1244 %fneg = fsub float -0.000000e+00, %fma 1245 store volatile float %fneg, float addrspace(1)* %out 1246 ret void 1247} 1248 1249; GCN-LABEL: {{^}}v_fneg_fma_fneg_x_fneg_f32: 1250; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1251; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1252; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1253 1254; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]], -[[A]], [[B]], -[[C]] 1255; GCN-SAFE: v_xor_b32_e32 v{{[[0-9]+}}, 0x80000000, [[FMA]] 1256 1257; GCN-NSZ: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], [[C]] 1258; GCN-NSZ-NOT: [[FMA]] 1259; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1260define amdgpu_kernel void @v_fneg_fma_fneg_x_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1261 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1262 %tid.ext = sext i32 %tid to i64 1263 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1264 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1265 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1266 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1267 %a = load volatile float, float addrspace(1)* %a.gep 1268 %b = load volatile float, float addrspace(1)* %b.gep 1269 %c = load volatile float, float addrspace(1)* %c.gep 1270 %fneg.a = fsub float -0.000000e+00, %a 1271 %fneg.c = fsub float -0.000000e+00, %c 1272 %fma = call float @llvm.fma.f32(float %fneg.a, float %b, float %fneg.c) 1273 %fneg = fsub float -0.000000e+00, %fma 1274 store volatile float %fneg, float addrspace(1)* %out 1275 ret void 1276} 1277 1278; GCN-LABEL: {{^}}v_fneg_fma_x_y_fneg_f32: 1279; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1280; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1281; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1282 1283; GCN-NSZ-SAFE: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], -[[C]] 1284; GCN-NSZ-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[FMA]] 1285 1286; GCN-NSZ: v_fma_f32 [[FMA:v[0-9]+]], [[A]], -[[B]], [[C]] 1287; GCN-NSZ-NOT: [[FMA]] 1288; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1289define amdgpu_kernel void @v_fneg_fma_x_y_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1290 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1291 %tid.ext = sext i32 %tid to i64 1292 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1293 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1294 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1295 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1296 %a = load volatile float, float addrspace(1)* %a.gep 1297 %b = load volatile float, float addrspace(1)* %b.gep 1298 %c = load volatile float, float addrspace(1)* %c.gep 1299 %fneg.c = fsub float -0.000000e+00, %c 1300 %fma = call float @llvm.fma.f32(float %a, float %b, float %fneg.c) 1301 %fneg = fsub float -0.000000e+00, %fma 1302 store volatile float %fneg, float addrspace(1)* %out 1303 ret void 1304} 1305 1306; GCN-LABEL: {{^}}v_fneg_fma_store_use_fneg_x_y_f32: 1307; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1308; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1309; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1310 1311; GCN-SAFE: v_xor_b32 1312; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]], -[[A]], 1313; GCN-SAFE: v_xor_b32 1314 1315; GCN-NSZ-DAG: v_xor_b32_e32 [[NEG_A:v[0-9]+]], 0x80000000, [[A]] 1316; GCN-NSZ-DAG: v_fma_f32 [[FMA:v[0-9]+]], [[A]], [[B]], -[[C]] 1317 1318; GCN-NSZ-NOT: [[FMA]] 1319; GCN-NSZ-NOT: [[NEG_A]] 1320; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA]] 1321; GCN-NSZ-NOT: [[NEG_A]] 1322; GCN-NSZ: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_A]] 1323define amdgpu_kernel void @v_fneg_fma_store_use_fneg_x_y_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1324 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1325 %tid.ext = sext i32 %tid to i64 1326 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1327 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1328 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1329 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1330 %a = load volatile float, float addrspace(1)* %a.gep 1331 %b = load volatile float, float addrspace(1)* %b.gep 1332 %c = load volatile float, float addrspace(1)* %c.gep 1333 %fneg.a = fsub float -0.000000e+00, %a 1334 %fma = call float @llvm.fma.f32(float %fneg.a, float %b, float %c) 1335 %fneg = fsub float -0.000000e+00, %fma 1336 store volatile float %fneg, float addrspace(1)* %out 1337 store volatile float %fneg.a, float addrspace(1)* %out 1338 ret void 1339} 1340 1341; GCN-LABEL: {{^}}v_fneg_fma_multi_use_fneg_x_y_f32: 1342; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1343; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1344; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1345 1346; GCN: v_mul_f32_e64 [[MUL:v[0-9]+]], -[[A]], s{{[0-9]+}} 1347; GCN-SAFE: v_fma_f32 [[FMA:v[0-9]+]] 1348; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[FMA]] 1349 1350; GCN-NSZ-DAG: v_fma_f32 [[NEG_FMA:v[0-9]+]], [[A]], [[B]], -[[C]] 1351; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_FMA]] 1352; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1353define amdgpu_kernel void @v_fneg_fma_multi_use_fneg_x_y_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, float %d) #0 { 1354 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1355 %tid.ext = sext i32 %tid to i64 1356 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1357 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1358 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1359 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1360 %a = load volatile float, float addrspace(1)* %a.gep 1361 %b = load volatile float, float addrspace(1)* %b.gep 1362 %c = load volatile float, float addrspace(1)* %c.gep 1363 %fneg.a = fsub float -0.000000e+00, %a 1364 %fma = call float @llvm.fma.f32(float %fneg.a, float %b, float %c) 1365 %fneg = fsub float -0.000000e+00, %fma 1366 %use1 = fmul float %fneg.a, %d 1367 store volatile float %fneg, float addrspace(1)* %out 1368 store volatile float %use1, float addrspace(1)* %out 1369 ret void 1370} 1371 1372; -------------------------------------------------------------------------------- 1373; fmad tests 1374; -------------------------------------------------------------------------------- 1375 1376; GCN-LABEL: {{^}}v_fneg_fmad_f32: 1377; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1378; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1379; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1380 1381; GCN-SAFE: v_mac_f32_e32 [[C]], [[A]], [[B]] 1382; GCN-SAFE: v_xor_b32_e32 v{{[0-9]+}}, 0x80000000, [[C]] 1383 1384; GCN-NSZ: v_mad_f32 [[RESULT:v[0-9]+]], [[A]], -[[B]], -[[C]] 1385; GCN-NSZ-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1386define amdgpu_kernel void @v_fneg_fmad_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1387 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1388 %tid.ext = sext i32 %tid to i64 1389 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1390 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1391 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1392 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1393 %a = load volatile float, float addrspace(1)* %a.gep 1394 %b = load volatile float, float addrspace(1)* %b.gep 1395 %c = load volatile float, float addrspace(1)* %c.gep 1396 %fma = call float @llvm.fmuladd.f32(float %a, float %b, float %c) 1397 %fneg = fsub float -0.000000e+00, %fma 1398 store float %fneg, float addrspace(1)* %out.gep 1399 ret void 1400} 1401 1402; GCN-LABEL: {{^}}v_fneg_fmad_multi_use_fmad_f32: 1403; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1404; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1405; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 1406 1407; GCN-SAFE: v_mac_f32_e32 [[C]], [[A]], [[B]] 1408; GCN-SAFE: v_xor_b32_e32 [[NEG_MAD:v[0-9]+]], 0x80000000, [[C]] 1409; GCN-SAFE-NEXT: v_mul_f32_e32 [[MUL:v[0-9]+]], 4.0, [[C]] 1410 1411; GCN-NSZ: v_mad_f32 [[NEG_MAD:v[0-9]+]], [[A]], -[[B]], -[[C]] 1412; GCN-NSZ-NEXT: v_mul_f32_e32 [[MUL:v[0-9]+]], -4.0, [[NEG_MAD]] 1413 1414; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MAD]] 1415; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1416define amdgpu_kernel void @v_fneg_fmad_multi_use_fmad_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 1417 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1418 %tid.ext = sext i32 %tid to i64 1419 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1420 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1421 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 1422 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1423 %a = load volatile float, float addrspace(1)* %a.gep 1424 %b = load volatile float, float addrspace(1)* %b.gep 1425 %c = load volatile float, float addrspace(1)* %c.gep 1426 %fma = call float @llvm.fmuladd.f32(float %a, float %b, float %c) 1427 %fneg = fsub float -0.000000e+00, %fma 1428 %use1 = fmul float %fma, 4.0 1429 store volatile float %fneg, float addrspace(1)* %out 1430 store volatile float %use1, float addrspace(1)* %out 1431 ret void 1432} 1433 1434; -------------------------------------------------------------------------------- 1435; fp_extend tests 1436; -------------------------------------------------------------------------------- 1437 1438; GCN-LABEL: {{^}}v_fneg_fp_extend_f32_to_f64: 1439; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1440; GCN: v_cvt_f64_f32_e64 [[RESULT:v\[[0-9]+:[0-9]+\]]], -[[A]] 1441; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1442define amdgpu_kernel void @v_fneg_fp_extend_f32_to_f64(double addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1443 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1444 %tid.ext = sext i32 %tid to i64 1445 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1446 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 1447 %a = load volatile float, float addrspace(1)* %a.gep 1448 %fpext = fpext float %a to double 1449 %fneg = fsub double -0.000000e+00, %fpext 1450 store double %fneg, double addrspace(1)* %out.gep 1451 ret void 1452} 1453 1454; GCN-LABEL: {{^}}v_fneg_fp_extend_fneg_f32_to_f64: 1455; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1456; GCN: v_cvt_f64_f32_e32 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[A]] 1457; GCN: {{buffer|flat}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1458define amdgpu_kernel void @v_fneg_fp_extend_fneg_f32_to_f64(double addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1459 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1460 %tid.ext = sext i32 %tid to i64 1461 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1462 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 1463 %a = load volatile float, float addrspace(1)* %a.gep 1464 %fneg.a = fsub float -0.000000e+00, %a 1465 %fpext = fpext float %fneg.a to double 1466 %fneg = fsub double -0.000000e+00, %fpext 1467 store double %fneg, double addrspace(1)* %out.gep 1468 ret void 1469} 1470 1471; GCN-LABEL: {{^}}v_fneg_fp_extend_store_use_fneg_f32_to_f64: 1472; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1473; GCN-DAG: v_cvt_f64_f32_e32 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[A]] 1474; GCN-DAG: v_xor_b32_e32 [[FNEG_A:v[0-9]+]], 0x80000000, [[A]] 1475; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1476; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FNEG_A]] 1477define amdgpu_kernel void @v_fneg_fp_extend_store_use_fneg_f32_to_f64(double addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1478 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1479 %tid.ext = sext i32 %tid to i64 1480 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1481 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 1482 %a = load volatile float, float addrspace(1)* %a.gep 1483 %fneg.a = fsub float -0.000000e+00, %a 1484 %fpext = fpext float %fneg.a to double 1485 %fneg = fsub double -0.000000e+00, %fpext 1486 store volatile double %fneg, double addrspace(1)* %out.gep 1487 store volatile float %fneg.a, float addrspace(1)* undef 1488 ret void 1489} 1490 1491; GCN-LABEL: {{^}}v_fneg_multi_use_fp_extend_fneg_f32_to_f64: 1492; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1493; GCN-DAG: v_cvt_f64_f32_e32 v{{\[}}[[CVT_LO:[0-9]+]]:[[CVT_HI:[0-9]+]]{{\]}}, [[A]] 1494; GCN-DAG: v_xor_b32_e32 v[[FNEG_A:[0-9]+]], 0x80000000, v[[CVT_HI]] 1495; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+}}:[[FNEG_A]]{{\]}} 1496; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[CVT_LO]]:[[CVT_HI]]{{\]}} 1497define amdgpu_kernel void @v_fneg_multi_use_fp_extend_fneg_f32_to_f64(double addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1498 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1499 %tid.ext = sext i32 %tid to i64 1500 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1501 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 1502 %a = load volatile float, float addrspace(1)* %a.gep 1503 %fpext = fpext float %a to double 1504 %fneg = fsub double -0.000000e+00, %fpext 1505 store volatile double %fneg, double addrspace(1)* %out.gep 1506 store volatile double %fpext, double addrspace(1)* undef 1507 ret void 1508} 1509 1510; GCN-LABEL: {{^}}v_fneg_multi_foldable_use_fp_extend_fneg_f32_to_f64: 1511; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1512; GCN-DAG: v_cvt_f64_f32_e32 v{{\[}}[[CVT_LO:[0-9]+]]:[[CVT_HI:[0-9]+]]{{\]}}, [[A]] 1513; GCN-DAG: v_xor_b32_e32 v[[FNEG_A:[0-9]+]], 0x80000000, v[[CVT_HI]] 1514; GCN-DAG: v_mul_f64 [[MUL:v\[[0-9]+:[0-9]+\]]], v{{\[}}[[CVT_LO]]:[[CVT_HI]]{{\]}}, 4.0 1515; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+}}:[[FNEG_A]]{{\]}} 1516; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1517define amdgpu_kernel void @v_fneg_multi_foldable_use_fp_extend_fneg_f32_to_f64(double addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1518 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1519 %tid.ext = sext i32 %tid to i64 1520 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1521 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 1522 %a = load volatile float, float addrspace(1)* %a.gep 1523 %fpext = fpext float %a to double 1524 %fneg = fsub double -0.000000e+00, %fpext 1525 %mul = fmul double %fpext, 4.0 1526 store volatile double %fneg, double addrspace(1)* %out.gep 1527 store volatile double %mul, double addrspace(1)* %out.gep 1528 ret void 1529} 1530 1531; FIXME: Source modifiers not folded for f16->f32 1532; GCN-LABEL: {{^}}v_fneg_multi_use_fp_extend_fneg_f16_to_f32: 1533define amdgpu_kernel void @v_fneg_multi_use_fp_extend_fneg_f16_to_f32(float addrspace(1)* %out, half addrspace(1)* %a.ptr) #0 { 1534 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1535 %tid.ext = sext i32 %tid to i64 1536 %a.gep = getelementptr inbounds half, half addrspace(1)* %a.ptr, i64 %tid.ext 1537 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1538 %a = load volatile half, half addrspace(1)* %a.gep 1539 %fpext = fpext half %a to float 1540 %fneg = fsub float -0.000000e+00, %fpext 1541 store volatile float %fneg, float addrspace(1)* %out.gep 1542 store volatile float %fpext, float addrspace(1)* %out.gep 1543 ret void 1544} 1545 1546; GCN-LABEL: {{^}}v_fneg_multi_foldable_use_fp_extend_fneg_f16_to_f32: 1547define amdgpu_kernel void @v_fneg_multi_foldable_use_fp_extend_fneg_f16_to_f32(float addrspace(1)* %out, half addrspace(1)* %a.ptr) #0 { 1548 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1549 %tid.ext = sext i32 %tid to i64 1550 %a.gep = getelementptr inbounds half, half addrspace(1)* %a.ptr, i64 %tid.ext 1551 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1552 %a = load volatile half, half addrspace(1)* %a.gep 1553 %fpext = fpext half %a to float 1554 %fneg = fsub float -0.000000e+00, %fpext 1555 %mul = fmul float %fpext, 4.0 1556 store volatile float %fneg, float addrspace(1)* %out.gep 1557 store volatile float %mul, float addrspace(1)* %out.gep 1558 ret void 1559} 1560 1561; -------------------------------------------------------------------------------- 1562; fp_round tests 1563; -------------------------------------------------------------------------------- 1564 1565; GCN-LABEL: {{^}}v_fneg_fp_round_f64_to_f32: 1566; GCN: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 1567; GCN: v_cvt_f32_f64_e64 [[RESULT:v[0-9]+]], -[[A]] 1568; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1569define amdgpu_kernel void @v_fneg_fp_round_f64_to_f32(float addrspace(1)* %out, double addrspace(1)* %a.ptr) #0 { 1570 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1571 %tid.ext = sext i32 %tid to i64 1572 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 1573 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1574 %a = load volatile double, double addrspace(1)* %a.gep 1575 %fpround = fptrunc double %a to float 1576 %fneg = fsub float -0.000000e+00, %fpround 1577 store float %fneg, float addrspace(1)* %out.gep 1578 ret void 1579} 1580 1581; GCN-LABEL: {{^}}v_fneg_fp_round_fneg_f64_to_f32: 1582; GCN: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 1583; GCN: v_cvt_f32_f64_e32 [[RESULT:v[0-9]+]], [[A]] 1584; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1585define amdgpu_kernel void @v_fneg_fp_round_fneg_f64_to_f32(float addrspace(1)* %out, double addrspace(1)* %a.ptr) #0 { 1586 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1587 %tid.ext = sext i32 %tid to i64 1588 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 1589 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1590 %a = load volatile double, double addrspace(1)* %a.gep 1591 %fneg.a = fsub double -0.000000e+00, %a 1592 %fpround = fptrunc double %fneg.a to float 1593 %fneg = fsub float -0.000000e+00, %fpround 1594 store float %fneg, float addrspace(1)* %out.gep 1595 ret void 1596} 1597 1598; GCN-LABEL: {{^}}v_fneg_fp_round_store_use_fneg_f64_to_f32: 1599; GCN: {{buffer|flat}}_load_dwordx2 v{{\[}}[[A_LO:[0-9]+]]:[[A_HI:[0-9]+]]{{\]}} 1600; GCN-DAG: v_cvt_f32_f64_e32 [[RESULT:v[0-9]+]], v{{\[}}[[A_LO]]:[[A_HI]]{{\]}} 1601; GCN-DAG: v_xor_b32_e32 v[[NEG_A_HI:[0-9]+]], 0x80000000, v[[A_HI]] 1602; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1603; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[A_LO]]:[[NEG_A_HI]]{{\]}} 1604define amdgpu_kernel void @v_fneg_fp_round_store_use_fneg_f64_to_f32(float addrspace(1)* %out, double addrspace(1)* %a.ptr) #0 { 1605 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1606 %tid.ext = sext i32 %tid to i64 1607 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 1608 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1609 %a = load volatile double, double addrspace(1)* %a.gep 1610 %fneg.a = fsub double -0.000000e+00, %a 1611 %fpround = fptrunc double %fneg.a to float 1612 %fneg = fsub float -0.000000e+00, %fpround 1613 store volatile float %fneg, float addrspace(1)* %out.gep 1614 store volatile double %fneg.a, double addrspace(1)* undef 1615 ret void 1616} 1617 1618; GCN-LABEL: {{^}}v_fneg_fp_round_multi_use_fneg_f64_to_f32: 1619; GCN: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 1620; GCN-DAG: v_cvt_f32_f64_e32 [[RESULT:v[0-9]+]], [[A]] 1621; GCN-DAG: v_mul_f64 [[USE1:v\[[0-9]+:[0-9]+\]]], -[[A]], s{{\[}} 1622 1623; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1624; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[USE1]] 1625define amdgpu_kernel void @v_fneg_fp_round_multi_use_fneg_f64_to_f32(float addrspace(1)* %out, double addrspace(1)* %a.ptr, double %c) #0 { 1626 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1627 %tid.ext = sext i32 %tid to i64 1628 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 1629 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1630 %a = load volatile double, double addrspace(1)* %a.gep 1631 %fneg.a = fsub double -0.000000e+00, %a 1632 %fpround = fptrunc double %fneg.a to float 1633 %fneg = fsub float -0.000000e+00, %fpround 1634 %use1 = fmul double %fneg.a, %c 1635 store volatile float %fneg, float addrspace(1)* %out.gep 1636 store volatile double %use1, double addrspace(1)* undef 1637 ret void 1638} 1639 1640; GCN-LABEL: {{^}}v_fneg_fp_round_f32_to_f16: 1641; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1642; GCN: v_cvt_f16_f32_e64 [[RESULT:v[0-9]+]], -[[A]] 1643; GCN: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1644define amdgpu_kernel void @v_fneg_fp_round_f32_to_f16(half addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1645 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1646 %tid.ext = sext i32 %tid to i64 1647 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1648 %out.gep = getelementptr inbounds half, half addrspace(1)* %out, i64 %tid.ext 1649 %a = load volatile float, float addrspace(1)* %a.gep 1650 %fpround = fptrunc float %a to half 1651 %fneg = fsub half -0.000000e+00, %fpround 1652 store half %fneg, half addrspace(1)* %out.gep 1653 ret void 1654} 1655 1656; GCN-LABEL: {{^}}v_fneg_fp_round_fneg_f32_to_f16: 1657; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1658; GCN: v_cvt_f16_f32_e32 [[RESULT:v[0-9]+]], [[A]] 1659; GCN: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1660define amdgpu_kernel void @v_fneg_fp_round_fneg_f32_to_f16(half addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1661 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1662 %tid.ext = sext i32 %tid to i64 1663 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1664 %out.gep = getelementptr inbounds half, half addrspace(1)* %out, i64 %tid.ext 1665 %a = load volatile float, float addrspace(1)* %a.gep 1666 %fneg.a = fsub float -0.000000e+00, %a 1667 %fpround = fptrunc float %fneg.a to half 1668 %fneg = fsub half -0.000000e+00, %fpround 1669 store half %fneg, half addrspace(1)* %out.gep 1670 ret void 1671} 1672 1673; GCN-LABEL: {{^}}v_fneg_multi_use_fp_round_fneg_f64_to_f32: 1674; GCN: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 1675; GCN-DAG: v_cvt_f32_f64_e32 [[CVT:v[0-9]+]], [[A]] 1676; GCN-DAG: v_xor_b32_e32 [[NEG:v[0-9]+]], 0x80000000, [[CVT]] 1677; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG]] 1678; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[CVT]] 1679define amdgpu_kernel void @v_fneg_multi_use_fp_round_fneg_f64_to_f32(float addrspace(1)* %out, double addrspace(1)* %a.ptr) #0 { 1680 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1681 %tid.ext = sext i32 %tid to i64 1682 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 1683 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1684 %a = load volatile double, double addrspace(1)* %a.gep 1685 %fpround = fptrunc double %a to float 1686 %fneg = fsub float -0.000000e+00, %fpround 1687 store volatile float %fneg, float addrspace(1)* %out.gep 1688 store volatile float %fpround, float addrspace(1)* %out.gep 1689 ret void 1690} 1691 1692; GCN-LABEL: {{^}}v_fneg_fp_round_store_use_fneg_f32_to_f16: 1693; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1694; GCN-DAG: v_cvt_f16_f32_e32 [[RESULT:v[0-9]+]], [[A]] 1695; GCN-DAG: v_xor_b32_e32 [[NEG_A:v[0-9]+]], 0x80000000, [[A]] 1696; GCN: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1697; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_A]] 1698define amdgpu_kernel void @v_fneg_fp_round_store_use_fneg_f32_to_f16(half addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1699 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1700 %tid.ext = sext i32 %tid to i64 1701 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1702 %out.gep = getelementptr inbounds half, half addrspace(1)* %out, i64 %tid.ext 1703 %a = load volatile float, float addrspace(1)* %a.gep 1704 %fneg.a = fsub float -0.000000e+00, %a 1705 %fpround = fptrunc float %fneg.a to half 1706 %fneg = fsub half -0.000000e+00, %fpround 1707 store volatile half %fneg, half addrspace(1)* %out.gep 1708 store volatile float %fneg.a, float addrspace(1)* undef 1709 ret void 1710} 1711 1712; GCN-LABEL: {{^}}v_fneg_fp_round_multi_use_fneg_f32_to_f16: 1713; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1714; GCN-DAG: v_cvt_f16_f32_e32 [[RESULT:v[0-9]+]], [[A]] 1715; GCN-DAG: v_mul_f32_e64 [[USE1:v[0-9]+]], -[[A]], s 1716; GCN: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1717; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[USE1]] 1718define amdgpu_kernel void @v_fneg_fp_round_multi_use_fneg_f32_to_f16(half addrspace(1)* %out, float addrspace(1)* %a.ptr, float %c) #0 { 1719 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1720 %tid.ext = sext i32 %tid to i64 1721 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1722 %out.gep = getelementptr inbounds half, half addrspace(1)* %out, i64 %tid.ext 1723 %a = load volatile float, float addrspace(1)* %a.gep 1724 %fneg.a = fsub float -0.000000e+00, %a 1725 %fpround = fptrunc float %fneg.a to half 1726 %fneg = fsub half -0.000000e+00, %fpround 1727 %use1 = fmul float %fneg.a, %c 1728 store volatile half %fneg, half addrspace(1)* %out.gep 1729 store volatile float %use1, float addrspace(1)* undef 1730 ret void 1731} 1732 1733; -------------------------------------------------------------------------------- 1734; rcp tests 1735; -------------------------------------------------------------------------------- 1736 1737; GCN-LABEL: {{^}}v_fneg_rcp_f32: 1738; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1739; GCN: v_rcp_f32_e64 [[RESULT:v[0-9]+]], -[[A]] 1740; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1741define amdgpu_kernel void @v_fneg_rcp_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1742 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1743 %tid.ext = sext i32 %tid to i64 1744 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1745 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1746 %a = load volatile float, float addrspace(1)* %a.gep 1747 %rcp = call float @llvm.amdgcn.rcp.f32(float %a) 1748 %fneg = fsub float -0.000000e+00, %rcp 1749 store float %fneg, float addrspace(1)* %out.gep 1750 ret void 1751} 1752 1753; GCN-LABEL: {{^}}v_fneg_rcp_fneg_f32: 1754; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1755; GCN: v_rcp_f32_e32 [[RESULT:v[0-9]+]], [[A]] 1756; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1757define amdgpu_kernel void @v_fneg_rcp_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1758 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1759 %tid.ext = sext i32 %tid to i64 1760 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1761 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1762 %a = load volatile float, float addrspace(1)* %a.gep 1763 %fneg.a = fsub float -0.000000e+00, %a 1764 %rcp = call float @llvm.amdgcn.rcp.f32(float %fneg.a) 1765 %fneg = fsub float -0.000000e+00, %rcp 1766 store float %fneg, float addrspace(1)* %out.gep 1767 ret void 1768} 1769 1770; GCN-LABEL: {{^}}v_fneg_rcp_store_use_fneg_f32: 1771; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1772; GCN-DAG: v_rcp_f32_e32 [[RESULT:v[0-9]+]], [[A]] 1773; GCN-DAG: v_xor_b32_e32 [[NEG_A:v[0-9]+]], 0x80000000, [[A]] 1774; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1775; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_A]] 1776define amdgpu_kernel void @v_fneg_rcp_store_use_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1777 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1778 %tid.ext = sext i32 %tid to i64 1779 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1780 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1781 %a = load volatile float, float addrspace(1)* %a.gep 1782 %fneg.a = fsub float -0.000000e+00, %a 1783 %rcp = call float @llvm.amdgcn.rcp.f32(float %fneg.a) 1784 %fneg = fsub float -0.000000e+00, %rcp 1785 store volatile float %fneg, float addrspace(1)* %out.gep 1786 store volatile float %fneg.a, float addrspace(1)* undef 1787 ret void 1788} 1789 1790; GCN-LABEL: {{^}}v_fneg_rcp_multi_use_fneg_f32: 1791; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1792; GCN-DAG: v_rcp_f32_e32 [[RESULT:v[0-9]+]], [[A]] 1793; GCN-DAG: v_mul_f32_e64 [[MUL:v[0-9]+]], -[[A]], s{{[0-9]+}} 1794; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1795; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1796define amdgpu_kernel void @v_fneg_rcp_multi_use_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float %c) #0 { 1797 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1798 %tid.ext = sext i32 %tid to i64 1799 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1800 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1801 %a = load volatile float, float addrspace(1)* %a.gep 1802 %fneg.a = fsub float -0.000000e+00, %a 1803 %rcp = call float @llvm.amdgcn.rcp.f32(float %fneg.a) 1804 %fneg = fsub float -0.000000e+00, %rcp 1805 %use1 = fmul float %fneg.a, %c 1806 store volatile float %fneg, float addrspace(1)* %out.gep 1807 store volatile float %use1, float addrspace(1)* undef 1808 ret void 1809} 1810 1811; -------------------------------------------------------------------------------- 1812; fmul_legacy tests 1813; -------------------------------------------------------------------------------- 1814 1815; GCN-LABEL: {{^}}v_fneg_mul_legacy_f32: 1816; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1817; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1818; GCN: v_mul_legacy_f32_e64 [[RESULT:v[0-9]+]], [[A]], -[[B]] 1819; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1820define amdgpu_kernel void @v_fneg_mul_legacy_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1821 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1822 %tid.ext = sext i32 %tid to i64 1823 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1824 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1825 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1826 %a = load volatile float, float addrspace(1)* %a.gep 1827 %b = load volatile float, float addrspace(1)* %b.gep 1828 %mul = call float @llvm.amdgcn.fmul.legacy(float %a, float %b) 1829 %fneg = fsub float -0.000000e+00, %mul 1830 store float %fneg, float addrspace(1)* %out.gep 1831 ret void 1832} 1833 1834; GCN-LABEL: {{^}}v_fneg_mul_legacy_store_use_mul_legacy_f32: 1835; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1836; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1837; GCN-DAG: v_mul_legacy_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 1838; GCN-DAG: v_xor_b32_e32 [[NEG_MUL_LEGACY:v[0-9]+]], 0x80000000, [[ADD]] 1839; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MUL_LEGACY]] 1840; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 1841define amdgpu_kernel void @v_fneg_mul_legacy_store_use_mul_legacy_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1842 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1843 %tid.ext = sext i32 %tid to i64 1844 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1845 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1846 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1847 %a = load volatile float, float addrspace(1)* %a.gep 1848 %b = load volatile float, float addrspace(1)* %b.gep 1849 %mul = call float @llvm.amdgcn.fmul.legacy(float %a, float %b) 1850 %fneg = fsub float -0.000000e+00, %mul 1851 store volatile float %fneg, float addrspace(1)* %out 1852 store volatile float %mul, float addrspace(1)* %out 1853 ret void 1854} 1855 1856; GCN-LABEL: {{^}}v_fneg_mul_legacy_multi_use_mul_legacy_f32: 1857; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1858; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1859; GCN: v_mul_legacy_f32_e64 [[ADD:v[0-9]+]], [[A]], -[[B]] 1860; GCN-NEXT: v_mul_legacy_f32_e64 [[MUL:v[0-9]+]], -[[ADD]], 4.0 1861; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 1862; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1863define amdgpu_kernel void @v_fneg_mul_legacy_multi_use_mul_legacy_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1864 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1865 %tid.ext = sext i32 %tid to i64 1866 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1867 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1868 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1869 %a = load volatile float, float addrspace(1)* %a.gep 1870 %b = load volatile float, float addrspace(1)* %b.gep 1871 %mul = call float @llvm.amdgcn.fmul.legacy(float %a, float %b) 1872 %fneg = fsub float -0.000000e+00, %mul 1873 %use1 = call float @llvm.amdgcn.fmul.legacy(float %mul, float 4.0) 1874 store volatile float %fneg, float addrspace(1)* %out 1875 store volatile float %use1, float addrspace(1)* %out 1876 ret void 1877} 1878 1879; GCN-LABEL: {{^}}v_fneg_mul_legacy_fneg_x_f32: 1880; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1881; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1882; GCN: v_mul_legacy_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 1883; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 1884define amdgpu_kernel void @v_fneg_mul_legacy_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1885 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1886 %tid.ext = sext i32 %tid to i64 1887 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1888 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1889 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1890 %a = load volatile float, float addrspace(1)* %a.gep 1891 %b = load volatile float, float addrspace(1)* %b.gep 1892 %fneg.a = fsub float -0.000000e+00, %a 1893 %mul = call float @llvm.amdgcn.fmul.legacy(float %fneg.a, float %b) 1894 %fneg = fsub float -0.000000e+00, %mul 1895 store volatile float %fneg, float addrspace(1)* %out 1896 ret void 1897} 1898 1899; GCN-LABEL: {{^}}v_fneg_mul_legacy_x_fneg_f32: 1900; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1901; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1902; GCN: v_mul_legacy_f32_e32 [[ADD:v[0-9]+]], [[A]], [[B]] 1903; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 1904define amdgpu_kernel void @v_fneg_mul_legacy_x_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1905 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1906 %tid.ext = sext i32 %tid to i64 1907 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1908 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1909 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1910 %a = load volatile float, float addrspace(1)* %a.gep 1911 %b = load volatile float, float addrspace(1)* %b.gep 1912 %fneg.b = fsub float -0.000000e+00, %b 1913 %mul = call float @llvm.amdgcn.fmul.legacy(float %a, float %fneg.b) 1914 %fneg = fsub float -0.000000e+00, %mul 1915 store volatile float %fneg, float addrspace(1)* %out 1916 ret void 1917} 1918 1919; GCN-LABEL: {{^}}v_fneg_mul_legacy_fneg_fneg_f32: 1920; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1921; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1922; GCN: v_mul_legacy_f32_e64 [[ADD:v[0-9]+]], [[A]], -[[B]] 1923; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[ADD]] 1924define amdgpu_kernel void @v_fneg_mul_legacy_fneg_fneg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1925 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1926 %tid.ext = sext i32 %tid to i64 1927 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1928 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1929 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1930 %a = load volatile float, float addrspace(1)* %a.gep 1931 %b = load volatile float, float addrspace(1)* %b.gep 1932 %fneg.a = fsub float -0.000000e+00, %a 1933 %fneg.b = fsub float -0.000000e+00, %b 1934 %mul = call float @llvm.amdgcn.fmul.legacy(float %fneg.a, float %fneg.b) 1935 %fneg = fsub float -0.000000e+00, %mul 1936 store volatile float %fneg, float addrspace(1)* %out 1937 ret void 1938} 1939 1940; GCN-LABEL: {{^}}v_fneg_mul_legacy_store_use_fneg_x_f32: 1941; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1942; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1943; GCN-DAG: v_xor_b32_e32 [[NEG_A:v[0-9]+]], 0x80000000, [[A]] 1944; GCN-DAG: v_mul_legacy_f32_e32 [[NEG_MUL_LEGACY:v[0-9]+]], [[A]], [[B]] 1945; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MUL_LEGACY]] 1946; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_A]] 1947define amdgpu_kernel void @v_fneg_mul_legacy_store_use_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 1948 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1949 %tid.ext = sext i32 %tid to i64 1950 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1951 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1952 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1953 %a = load volatile float, float addrspace(1)* %a.gep 1954 %b = load volatile float, float addrspace(1)* %b.gep 1955 %fneg.a = fsub float -0.000000e+00, %a 1956 %mul = call float @llvm.amdgcn.fmul.legacy(float %fneg.a, float %b) 1957 %fneg = fsub float -0.000000e+00, %mul 1958 store volatile float %fneg, float addrspace(1)* %out 1959 store volatile float %fneg.a, float addrspace(1)* %out 1960 ret void 1961} 1962 1963; GCN-LABEL: {{^}}v_fneg_mul_legacy_multi_use_fneg_x_f32: 1964; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1965; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 1966; GCN-DAG: v_mul_legacy_f32_e32 [[NEG_MUL_LEGACY:v[0-9]+]], [[A]], [[B]] 1967; GCN-DAG: v_mul_legacy_f32_e64 [[MUL:v[0-9]+]], -[[A]], s{{[0-9]+}} 1968; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[NEG_MUL_LEGACY]] 1969; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 1970define amdgpu_kernel void @v_fneg_mul_legacy_multi_use_fneg_x_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float %c) #0 { 1971 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1972 %tid.ext = sext i32 %tid to i64 1973 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 1974 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 1975 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 1976 %a = load volatile float, float addrspace(1)* %a.gep 1977 %b = load volatile float, float addrspace(1)* %b.gep 1978 %fneg.a = fsub float -0.000000e+00, %a 1979 %mul = call float @llvm.amdgcn.fmul.legacy(float %fneg.a, float %b) 1980 %fneg = fsub float -0.000000e+00, %mul 1981 %use1 = call float @llvm.amdgcn.fmul.legacy(float %fneg.a, float %c) 1982 store volatile float %fneg, float addrspace(1)* %out 1983 store volatile float %use1, float addrspace(1)* %out 1984 ret void 1985} 1986 1987; -------------------------------------------------------------------------------- 1988; sin tests 1989; -------------------------------------------------------------------------------- 1990 1991; GCN-LABEL: {{^}}v_fneg_sin_f32: 1992; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 1993; GCN: v_mul_f32_e32 [[MUL:v[0-9]+]], 0xbe22f983, [[A]] 1994; GCN: v_fract_f32_e32 [[FRACT:v[0-9]+]], [[MUL]] 1995; GCN: v_sin_f32_e32 [[RESULT:v[0-9]+]], [[FRACT]] 1996; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 1997define amdgpu_kernel void @v_fneg_sin_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 1998 %tid = call i32 @llvm.amdgcn.workitem.id.x() 1999 %tid.ext = sext i32 %tid to i64 2000 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2001 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2002 %a = load volatile float, float addrspace(1)* %a.gep 2003 %sin = call float @llvm.sin.f32(float %a) 2004 %fneg = fsub float -0.000000e+00, %sin 2005 store float %fneg, float addrspace(1)* %out.gep 2006 ret void 2007} 2008 2009; GCN-LABEL: {{^}}v_fneg_amdgcn_sin_f32: 2010; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2011; GCN: v_sin_f32_e64 [[RESULT:v[0-9]+]], -[[A]] 2012; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 2013define amdgpu_kernel void @v_fneg_amdgcn_sin_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 2014 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2015 %tid.ext = sext i32 %tid to i64 2016 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2017 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2018 %a = load volatile float, float addrspace(1)* %a.gep 2019 %sin = call float @llvm.amdgcn.sin.f32(float %a) 2020 %fneg = fsub float -0.0, %sin 2021 store float %fneg, float addrspace(1)* %out.gep 2022 ret void 2023} 2024 2025; -------------------------------------------------------------------------------- 2026; ftrunc tests 2027; -------------------------------------------------------------------------------- 2028 2029; GCN-LABEL: {{^}}v_fneg_trunc_f32: 2030; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2031; GCN: v_trunc_f32_e64 [[RESULT:v[0-9]+]], -[[A]] 2032; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 2033define amdgpu_kernel void @v_fneg_trunc_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 2034 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2035 %tid.ext = sext i32 %tid to i64 2036 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2037 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2038 %a = load volatile float, float addrspace(1)* %a.gep 2039 %trunc = call float @llvm.trunc.f32(float %a) 2040 %fneg = fsub float -0.0, %trunc 2041 store float %fneg, float addrspace(1)* %out.gep 2042 ret void 2043} 2044 2045; -------------------------------------------------------------------------------- 2046; fround tests 2047; -------------------------------------------------------------------------------- 2048 2049; GCN-LABEL: {{^}}v_fneg_round_f32: 2050; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2051; GCN: v_trunc_f32_e32 2052; GCN: v_sub_f32_e32 2053; GCN: v_cndmask_b32 2054 2055; GCN-SAFE: v_add_f32_e32 [[ADD:v[0-9]+]], v{{[0-9]+}}, v{{[0-9]+}} 2056; GCN-SAFE: v_xor_b32_e32 [[RESULT:v[0-9]+]], 0x80000000, [[ADD]] 2057 2058; GCN-NSZ: v_sub_f32_e64 [[RESULT:v[0-9]+]], -v{{[0-9]+}}, v{{[0-9]+}} 2059; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 2060define amdgpu_kernel void @v_fneg_round_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 2061 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2062 %tid.ext = sext i32 %tid to i64 2063 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2064 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2065 %a = load volatile float, float addrspace(1)* %a.gep 2066 %round = call float @llvm.round.f32(float %a) 2067 %fneg = fsub float -0.0, %round 2068 store float %fneg, float addrspace(1)* %out.gep 2069 ret void 2070} 2071 2072; -------------------------------------------------------------------------------- 2073; rint tests 2074; -------------------------------------------------------------------------------- 2075 2076; GCN-LABEL: {{^}}v_fneg_rint_f32: 2077; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2078; GCN: v_rndne_f32_e64 [[RESULT:v[0-9]+]], -[[A]] 2079; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 2080define amdgpu_kernel void @v_fneg_rint_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 2081 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2082 %tid.ext = sext i32 %tid to i64 2083 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2084 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2085 %a = load volatile float, float addrspace(1)* %a.gep 2086 %rint = call float @llvm.rint.f32(float %a) 2087 %fneg = fsub float -0.0, %rint 2088 store float %fneg, float addrspace(1)* %out.gep 2089 ret void 2090} 2091 2092; -------------------------------------------------------------------------------- 2093; nearbyint tests 2094; -------------------------------------------------------------------------------- 2095 2096; GCN-LABEL: {{^}}v_fneg_nearbyint_f32: 2097; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2098; GCN: v_rndne_f32_e64 [[RESULT:v[0-9]+]], -[[A]] 2099; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 2100define amdgpu_kernel void @v_fneg_nearbyint_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 2101 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2102 %tid.ext = sext i32 %tid to i64 2103 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2104 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2105 %a = load volatile float, float addrspace(1)* %a.gep 2106 %nearbyint = call float @llvm.nearbyint.f32(float %a) 2107 %fneg = fsub float -0.0, %nearbyint 2108 store float %fneg, float addrspace(1)* %out.gep 2109 ret void 2110} 2111 2112; -------------------------------------------------------------------------------- 2113; fcanonicalize tests 2114; -------------------------------------------------------------------------------- 2115 2116; GCN-LABEL: {{^}}v_fneg_canonicalize_f32: 2117; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2118; GCN: v_mul_f32_e32 [[RESULT:v[0-9]+]], -1.0, [[A]] 2119; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 2120define amdgpu_kernel void @v_fneg_canonicalize_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr) #0 { 2121 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2122 %tid.ext = sext i32 %tid to i64 2123 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2124 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2125 %a = load volatile float, float addrspace(1)* %a.gep 2126 %trunc = call float @llvm.canonicalize.f32(float %a) 2127 %fneg = fsub float -0.0, %trunc 2128 store float %fneg, float addrspace(1)* %out.gep 2129 ret void 2130} 2131 2132; -------------------------------------------------------------------------------- 2133; vintrp tests 2134; -------------------------------------------------------------------------------- 2135 2136; GCN-LABEL: {{^}}v_fneg_interp_p1_f32: 2137; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2138; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2139; GCN: v_mul_f32_e64 [[MUL:v[0-9]+]], [[A]], -[[B]] 2140; GCN: v_interp_p1_f32{{(_e32)?}} v{{[0-9]+}}, [[MUL]] 2141; GCN: v_interp_p1_f32{{(_e32)?}} v{{[0-9]+}}, [[MUL]] 2142define amdgpu_kernel void @v_fneg_interp_p1_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 2143 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2144 %tid.ext = sext i32 %tid to i64 2145 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2146 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2147 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2148 %a = load volatile float, float addrspace(1)* %a.gep 2149 %b = load volatile float, float addrspace(1)* %b.gep 2150 %mul = fmul float %a, %b 2151 %fneg = fsub float -0.0, %mul 2152 %intrp0 = call float @llvm.amdgcn.interp.p1(float %fneg, i32 0, i32 0, i32 0) 2153 %intrp1 = call float @llvm.amdgcn.interp.p1(float %fneg, i32 1, i32 0, i32 0) 2154 store volatile float %intrp0, float addrspace(1)* %out.gep 2155 store volatile float %intrp1, float addrspace(1)* %out.gep 2156 ret void 2157} 2158 2159; GCN-LABEL: {{^}}v_fneg_interp_p2_f32: 2160; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2161; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2162; GCN: v_mul_f32_e64 [[MUL:v[0-9]+]], [[A]], -[[B]] 2163; GCN: v_interp_p2_f32{{(_e32)?}} v{{[0-9]+}}, [[MUL]] 2164; GCN: v_interp_p2_f32{{(_e32)?}} v{{[0-9]+}}, [[MUL]] 2165define amdgpu_kernel void @v_fneg_interp_p2_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr) #0 { 2166 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2167 %tid.ext = sext i32 %tid to i64 2168 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2169 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2170 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2171 %a = load volatile float, float addrspace(1)* %a.gep 2172 %b = load volatile float, float addrspace(1)* %b.gep 2173 %mul = fmul float %a, %b 2174 %fneg = fsub float -0.0, %mul 2175 %intrp0 = call float @llvm.amdgcn.interp.p2(float 4.0, float %fneg, i32 0, i32 0, i32 0) 2176 %intrp1 = call float @llvm.amdgcn.interp.p2(float 4.0, float %fneg, i32 1, i32 0, i32 0) 2177 store volatile float %intrp0, float addrspace(1)* %out.gep 2178 store volatile float %intrp1, float addrspace(1)* %out.gep 2179 ret void 2180} 2181 2182; -------------------------------------------------------------------------------- 2183; CopyToReg tests 2184; -------------------------------------------------------------------------------- 2185 2186; GCN-LABEL: {{^}}v_fneg_copytoreg_f32: 2187; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2188; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2189; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2190; GCN: v_mul_f32_e32 [[MUL0:v[0-9]+]], [[A]], [[B]] 2191; GCN: s_cbranch_scc0 2192 2193; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL0]] 2194; GCN: s_endpgm 2195 2196; GCN: v_xor_b32_e32 [[XOR:v[0-9]+]], 0x80000000, [[MUL0]] 2197; GCN: v_mul_f32_e32 [[MUL1:v[0-9]+]], [[XOR]], [[C]] 2198; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 2199 2200define amdgpu_kernel void @v_fneg_copytoreg_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, i32 %d) #0 { 2201 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2202 %tid.ext = sext i32 %tid to i64 2203 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2204 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2205 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2206 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2207 %a = load volatile float, float addrspace(1)* %a.gep 2208 %b = load volatile float, float addrspace(1)* %b.gep 2209 %c = load volatile float, float addrspace(1)* %c.gep 2210 %mul = fmul float %a, %b 2211 %fneg = fsub float -0.0, %mul 2212 %cmp0 = icmp eq i32 %d, 0 2213 br i1 %cmp0, label %if, label %endif 2214 2215if: 2216 %mul1 = fmul float %fneg, %c 2217 store volatile float %mul1, float addrspace(1)* %out.gep 2218 br label %endif 2219 2220endif: 2221 store volatile float %mul, float addrspace(1)* %out.gep 2222 ret void 2223} 2224 2225; -------------------------------------------------------------------------------- 2226; inlineasm tests 2227; -------------------------------------------------------------------------------- 2228 2229; Can't fold into use, so should fold into source 2230; GCN-LABEL: {{^}}v_fneg_inlineasm_f32: 2231; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2232; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2233; GCN: v_mul_f32_e64 [[MUL:v[0-9]+]], [[A]], -[[B]] 2234; GCN: ; use [[MUL]] 2235; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 2236define amdgpu_kernel void @v_fneg_inlineasm_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, i32 %d) #0 { 2237 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2238 %tid.ext = sext i32 %tid to i64 2239 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2240 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2241 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2242 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2243 %a = load volatile float, float addrspace(1)* %a.gep 2244 %b = load volatile float, float addrspace(1)* %b.gep 2245 %c = load volatile float, float addrspace(1)* %c.gep 2246 %mul = fmul float %a, %b 2247 %fneg = fsub float -0.0, %mul 2248 call void asm sideeffect "; use $0", "v"(float %fneg) #0 2249 store volatile float %fneg, float addrspace(1)* %out.gep 2250 ret void 2251} 2252 2253; -------------------------------------------------------------------------------- 2254; inlineasm tests 2255; -------------------------------------------------------------------------------- 2256 2257; Can't fold into use, so should fold into source 2258; GCN-LABEL: {{^}}v_fneg_inlineasm_multi_use_src_f32: 2259; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2260; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2261; GCN: v_mul_f32_e32 [[MUL:v[0-9]+]], [[A]], [[B]] 2262; GCN: v_xor_b32_e32 [[NEG:v[0-9]+]], 0x80000000, [[MUL]] 2263; GCN: ; use [[NEG]] 2264; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL]] 2265define amdgpu_kernel void @v_fneg_inlineasm_multi_use_src_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, i32 %d) #0 { 2266 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2267 %tid.ext = sext i32 %tid to i64 2268 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2269 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2270 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2271 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2272 %a = load volatile float, float addrspace(1)* %a.gep 2273 %b = load volatile float, float addrspace(1)* %b.gep 2274 %c = load volatile float, float addrspace(1)* %c.gep 2275 %mul = fmul float %a, %b 2276 %fneg = fsub float -0.0, %mul 2277 call void asm sideeffect "; use $0", "v"(float %fneg) #0 2278 store volatile float %mul, float addrspace(1)* %out.gep 2279 ret void 2280} 2281 2282; -------------------------------------------------------------------------------- 2283; code size regression tests 2284; -------------------------------------------------------------------------------- 2285 2286; There are multiple users of the fneg that must use a VOP3 2287; instruction, so there is no penalty 2288; GCN-LABEL: {{^}}multiuse_fneg_2_vop3_users_f32: 2289; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2290; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2291; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2292 2293; GCN: v_fma_f32 [[FMA0:v[0-9]+]], -[[A]], [[B]], [[C]] 2294; GCN-NEXT: v_fma_f32 [[FMA1:v[0-9]+]], -[[A]], [[C]], 2.0 2295 2296; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA0]] 2297; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA1]] 2298define amdgpu_kernel void @multiuse_fneg_2_vop3_users_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 2299 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2300 %tid.ext = sext i32 %tid to i64 2301 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2302 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2303 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2304 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2305 %a = load volatile float, float addrspace(1)* %a.gep 2306 %b = load volatile float, float addrspace(1)* %b.gep 2307 %c = load volatile float, float addrspace(1)* %c.gep 2308 2309 %fneg.a = fsub float -0.0, %a 2310 %fma0 = call float @llvm.fma.f32(float %fneg.a, float %b, float %c) 2311 %fma1 = call float @llvm.fma.f32(float %fneg.a, float %c, float 2.0) 2312 2313 store volatile float %fma0, float addrspace(1)* %out 2314 store volatile float %fma1, float addrspace(1)* %out 2315 ret void 2316} 2317 2318; There are multiple users, but both require using a larger encoding 2319; for the modifier. 2320 2321; GCN-LABEL: {{^}}multiuse_fneg_2_vop2_users_f32: 2322; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2323; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2324; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2325 2326; GCN: v_mul_f32_e64 [[MUL0:v[0-9]+]], -[[A]], [[B]] 2327; GCN: v_mul_f32_e64 [[MUL1:v[0-9]+]], -[[A]], [[C]] 2328; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL0]] 2329; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 2330define amdgpu_kernel void @multiuse_fneg_2_vop2_users_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 2331 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2332 %tid.ext = sext i32 %tid to i64 2333 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2334 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2335 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2336 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2337 %a = load volatile float, float addrspace(1)* %a.gep 2338 %b = load volatile float, float addrspace(1)* %b.gep 2339 %c = load volatile float, float addrspace(1)* %c.gep 2340 2341 %fneg.a = fsub float -0.0, %a 2342 %mul0 = fmul float %fneg.a, %b 2343 %mul1 = fmul float %fneg.a, %c 2344 2345 store volatile float %mul0, float addrspace(1)* %out 2346 store volatile float %mul1, float addrspace(1)* %out 2347 ret void 2348} 2349 2350; One user is VOP3 so has no cost to folding the modifier, the other does. 2351; GCN-LABEL: {{^}}multiuse_fneg_vop2_vop3_users_f32: 2352; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2353; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2354; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2355 2356; GCN: v_fma_f32 [[FMA0:v[0-9]+]], -[[A]], [[B]], 2.0 2357; GCN: v_mul_f32_e64 [[MUL1:v[0-9]+]], -[[A]], [[C]] 2358 2359; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA0]] 2360; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 2361define amdgpu_kernel void @multiuse_fneg_vop2_vop3_users_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr) #0 { 2362 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2363 %tid.ext = sext i32 %tid to i64 2364 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2365 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2366 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2367 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2368 %a = load volatile float, float addrspace(1)* %a.gep 2369 %b = load volatile float, float addrspace(1)* %b.gep 2370 %c = load volatile float, float addrspace(1)* %c.gep 2371 2372 %fneg.a = fsub float -0.0, %a 2373 %fma0 = call float @llvm.fma.f32(float %fneg.a, float %b, float 2.0) 2374 %mul1 = fmul float %fneg.a, %c 2375 2376 store volatile float %fma0, float addrspace(1)* %out 2377 store volatile float %mul1, float addrspace(1)* %out 2378 ret void 2379} 2380 2381; The use of the fneg requires a code size increase, but folding into 2382; the source does not 2383 2384; GCN-LABEL: {{^}}free_fold_src_code_size_cost_use_f32: 2385; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2386; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2387; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2388; GCN: {{buffer|flat}}_load_dword [[D:v[0-9]+]] 2389 2390; GCN-SAFE: v_fma_f32 [[FMA0:v[0-9]+]], [[A]], [[B]], 2.0 2391; GCN-SAFE-DAG: v_mul_f32_e64 [[MUL1:v[0-9]+]], -[[FMA0]], [[C]] 2392; GCN-SAFE-DAG: v_mul_f32_e64 [[MUL2:v[0-9]+]], -[[FMA0]], [[D]] 2393 2394; GCN-NSZ: v_fma_f32 [[FMA0:v[0-9]+]], [[A]], -[[B]], -2.0 2395; GCN-NSZ-DAG: v_mul_f32_e32 [[MUL1:v[0-9]+]], [[FMA0]], [[C]] 2396; GCN-NSZ-DAG: v_mul_f32_e32 [[MUL2:v[0-9]+]], [[FMA0]], [[D]] 2397 2398; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 2399; GCN-NEXT: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL2]] 2400define amdgpu_kernel void @free_fold_src_code_size_cost_use_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, float addrspace(1)* %d.ptr) #0 { 2401 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2402 %tid.ext = sext i32 %tid to i64 2403 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2404 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2405 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2406 %d.gep = getelementptr inbounds float, float addrspace(1)* %d.ptr, i64 %tid.ext 2407 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2408 %a = load volatile float, float addrspace(1)* %a.gep 2409 %b = load volatile float, float addrspace(1)* %b.gep 2410 %c = load volatile float, float addrspace(1)* %c.gep 2411 %d = load volatile float, float addrspace(1)* %d.gep 2412 2413 %fma0 = call float @llvm.fma.f32(float %a, float %b, float 2.0) 2414 %fneg.fma0 = fsub float -0.0, %fma0 2415 %mul1 = fmul float %fneg.fma0, %c 2416 %mul2 = fmul float %fneg.fma0, %d 2417 2418 store volatile float %mul1, float addrspace(1)* %out 2419 store volatile float %mul2, float addrspace(1)* %out 2420 ret void 2421} 2422 2423; GCN-LABEL: {{^}}free_fold_src_code_size_cost_use_f64: 2424; GCN: {{buffer|flat}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]] 2425; GCN: {{buffer|flat}}_load_dwordx2 [[B:v\[[0-9]+:[0-9]+\]]] 2426; GCN: {{buffer|flat}}_load_dwordx2 [[C:v\[[0-9]+:[0-9]+\]]] 2427; GCN: {{buffer|flat}}_load_dwordx2 [[D:v\[[0-9]+:[0-9]+\]]] 2428 2429; GCN: v_fma_f64 [[FMA0:v\[[0-9]+:[0-9]+\]]], [[A]], [[B]], 2.0 2430; GCN-DAG: v_mul_f64 [[MUL0:v\[[0-9]+:[0-9]+\]]], -[[FMA0]], [[C]] 2431; GCN-DAG: v_mul_f64 [[MUL1:v\[[0-9]+:[0-9]+\]]], -[[FMA0]], [[D]] 2432 2433; GCN: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[MUL0]] 2434; GCN-NEXT: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 2435define amdgpu_kernel void @free_fold_src_code_size_cost_use_f64(double addrspace(1)* %out, double addrspace(1)* %a.ptr, double addrspace(1)* %b.ptr, double addrspace(1)* %c.ptr, double addrspace(1)* %d.ptr) #0 { 2436 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2437 %tid.ext = sext i32 %tid to i64 2438 %a.gep = getelementptr inbounds double, double addrspace(1)* %a.ptr, i64 %tid.ext 2439 %b.gep = getelementptr inbounds double, double addrspace(1)* %b.ptr, i64 %tid.ext 2440 %c.gep = getelementptr inbounds double, double addrspace(1)* %c.ptr, i64 %tid.ext 2441 %d.gep = getelementptr inbounds double, double addrspace(1)* %d.ptr, i64 %tid.ext 2442 %out.gep = getelementptr inbounds double, double addrspace(1)* %out, i64 %tid.ext 2443 %a = load volatile double, double addrspace(1)* %a.gep 2444 %b = load volatile double, double addrspace(1)* %b.gep 2445 %c = load volatile double, double addrspace(1)* %c.gep 2446 %d = load volatile double, double addrspace(1)* %d.gep 2447 2448 %fma0 = call double @llvm.fma.f64(double %a, double %b, double 2.0) 2449 %fneg.fma0 = fsub double -0.0, %fma0 2450 %mul1 = fmul double %fneg.fma0, %c 2451 %mul2 = fmul double %fneg.fma0, %d 2452 2453 store volatile double %mul1, double addrspace(1)* %out 2454 store volatile double %mul2, double addrspace(1)* %out 2455 ret void 2456} 2457 2458; %trunc.a has one fneg use, but it requires a code size increase and 2459; %the fneg can instead be folded for free into the fma. 2460 2461; GCN-LABEL: {{^}}one_use_cost_to_fold_into_src_f32: 2462; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2463; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2464; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2465; GCN: v_trunc_f32_e32 [[TRUNC_A:v[0-9]+]], [[A]] 2466; GCN: v_fma_f32 [[FMA0:v[0-9]+]], -[[TRUNC_A]], [[B]], [[C]] 2467; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA0]] 2468define amdgpu_kernel void @one_use_cost_to_fold_into_src_f32(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, float addrspace(1)* %d.ptr) #0 { 2469 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2470 %tid.ext = sext i32 %tid to i64 2471 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2472 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2473 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2474 %d.gep = getelementptr inbounds float, float addrspace(1)* %d.ptr, i64 %tid.ext 2475 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2476 %a = load volatile float, float addrspace(1)* %a.gep 2477 %b = load volatile float, float addrspace(1)* %b.gep 2478 %c = load volatile float, float addrspace(1)* %c.gep 2479 %d = load volatile float, float addrspace(1)* %d.gep 2480 2481 %trunc.a = call float @llvm.trunc.f32(float %a) 2482 %trunc.fneg.a = fsub float -0.0, %trunc.a 2483 %fma0 = call float @llvm.fma.f32(float %trunc.fneg.a, float %b, float %c) 2484 store volatile float %fma0, float addrspace(1)* %out 2485 ret void 2486} 2487 2488; GCN-LABEL: {{^}}multi_use_cost_to_fold_into_src: 2489; GCN: {{buffer|flat}}_load_dword [[A:v[0-9]+]] 2490; GCN: {{buffer|flat}}_load_dword [[B:v[0-9]+]] 2491; GCN: {{buffer|flat}}_load_dword [[C:v[0-9]+]] 2492; GCN: {{buffer|flat}}_load_dword [[D:v[0-9]+]] 2493; GCN: v_trunc_f32_e32 [[TRUNC_A:v[0-9]+]], [[A]] 2494; GCN-DAG: v_fma_f32 [[FMA0:v[0-9]+]], -[[TRUNC_A]], [[B]], [[C]] 2495; GCN-DAG: v_mul_f32_e32 [[MUL1:v[0-9]+]], [[TRUNC_A]], [[D]] 2496; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[FMA0]] 2497; GCN: flat_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[MUL1]] 2498define amdgpu_kernel void @multi_use_cost_to_fold_into_src(float addrspace(1)* %out, float addrspace(1)* %a.ptr, float addrspace(1)* %b.ptr, float addrspace(1)* %c.ptr, float addrspace(1)* %d.ptr) #0 { 2499 %tid = call i32 @llvm.amdgcn.workitem.id.x() 2500 %tid.ext = sext i32 %tid to i64 2501 %a.gep = getelementptr inbounds float, float addrspace(1)* %a.ptr, i64 %tid.ext 2502 %b.gep = getelementptr inbounds float, float addrspace(1)* %b.ptr, i64 %tid.ext 2503 %c.gep = getelementptr inbounds float, float addrspace(1)* %c.ptr, i64 %tid.ext 2504 %d.gep = getelementptr inbounds float, float addrspace(1)* %d.ptr, i64 %tid.ext 2505 %out.gep = getelementptr inbounds float, float addrspace(1)* %out, i64 %tid.ext 2506 %a = load volatile float, float addrspace(1)* %a.gep 2507 %b = load volatile float, float addrspace(1)* %b.gep 2508 %c = load volatile float, float addrspace(1)* %c.gep 2509 %d = load volatile float, float addrspace(1)* %d.gep 2510 2511 %trunc.a = call float @llvm.trunc.f32(float %a) 2512 %trunc.fneg.a = fsub float -0.0, %trunc.a 2513 %fma0 = call float @llvm.fma.f32(float %trunc.fneg.a, float %b, float %c) 2514 %mul1 = fmul float %trunc.a, %d 2515 store volatile float %fma0, float addrspace(1)* %out 2516 store volatile float %mul1, float addrspace(1)* %out 2517 ret void 2518} 2519 2520declare i32 @llvm.amdgcn.workitem.id.x() #1 2521declare float @llvm.fma.f32(float, float, float) #1 2522declare float @llvm.fmuladd.f32(float, float, float) #1 2523declare float @llvm.sin.f32(float) #1 2524declare float @llvm.trunc.f32(float) #1 2525declare float @llvm.round.f32(float) #1 2526declare float @llvm.rint.f32(float) #1 2527declare float @llvm.nearbyint.f32(float) #1 2528declare float @llvm.canonicalize.f32(float) #1 2529declare float @llvm.minnum.f32(float, float) #1 2530declare float @llvm.maxnum.f32(float, float) #1 2531declare half @llvm.minnum.f16(half, half) #1 2532declare double @llvm.minnum.f64(double, double) #1 2533declare double @llvm.fma.f64(double, double, double) #1 2534 2535declare float @llvm.amdgcn.sin.f32(float) #1 2536declare float @llvm.amdgcn.rcp.f32(float) #1 2537declare float @llvm.amdgcn.rcp.legacy(float) #1 2538declare float @llvm.amdgcn.fmul.legacy(float, float) #1 2539declare float @llvm.amdgcn.interp.p1(float, i32, i32, i32) #0 2540declare float @llvm.amdgcn.interp.p2(float, float, i32, i32, i32) #0 2541 2542attributes #0 = { nounwind } 2543attributes #1 = { nounwind readnone } 2544attributes #2 = { nounwind "unsafe-fp-math"="true" } 2545