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