1; RUN: llc -march=amdgcn -mcpu=fiji -denormal-fp-math=preserve-sign -denormal-fp-math-f32=ieee -fp-contract=on -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-STRICT,VI-FLUSH,VI %s 2; RUN: llc -march=amdgcn -mcpu=fiji -denormal-fp-math=preserve-sign -denormal-fp-math-f32=ieee -fp-contract=fast -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-CONTRACT,VI-FLUSH,VI %s 3 4; RUN: llc -march=amdgcn -mcpu=fiji -denormal-fp-math=ieee -denormal-fp-math-f32=ieee -fp-contract=on -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-STRICT,GCN-DENORM,GCN-DENORM-STRICT,VI-DENORM-STRICT,VI-DENORM,VI %s 5; RUN: llc -march=amdgcn -mcpu=fiji -denormal-fp-math=ieee -denormal-fp-math-f32=ieee -fp-contract=fast -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-CONTRACT,GCN-DENORM,GCN-DENORM-CONTRACT,VI-DENORM-CONTRACT,VI-DENORM,VI %s 6 7; RUN: llc -march=amdgcn -mcpu=gfx1010 -denormal-fp-math=preserve-sign -denormal-fp-math-f32=ieee -fp-contract=on -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-STRICT,GFX10-FLUSH,GFX10 %s 8; RUN: llc -march=amdgcn -mcpu=gfx1010 -denormal-fp-math=preserve-sign -denormal-fp-math-f32=ieee -fp-contract=fast -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-CONTRACT,GFX10-FLUSH,GFX10 %s 9; RUN: llc -march=amdgcn -mcpu=gfx1010 -denormal-fp-math=ieee -denormal-fp-math-f32=ieee -fp-contract=on -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-STRICT,GCN-DENORM,GCN-DENORM-STRICT,GFX10-DENORM-STRICT,GFX10-DENORM,GFX10 %s 10; RUN: llc -march=amdgcn -mcpu=gfx1010 -denormal-fp-math=ieee -denormal-fp-math-f32=ieee -fp-contract=fast -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GCN-CONTRACT,GCN-DENORM,GCN-DENORM-CONTRACT,GFX10-DENORM-CONTRACT,GFX10-DENORM,GFX10 %s 11 12declare i32 @llvm.amdgcn.workitem.id.x() #1 13declare half @llvm.fmuladd.f16(half, half, half) #1 14declare half @llvm.fabs.f16(half) #1 15 16; GCN-LABEL: {{^}}fmuladd_f16: 17; VI-FLUSH: v_mac_f16_e32 {{v[0-9]+, v[0-9]+, v[0-9]+}} 18 19; VI-DENORM: v_fma_f16 {{v[0-9]+, v[0-9]+, v[0-9]+}} 20 21; GFX10-FLUSH: v_mul_f16_e32 22; GFX10-FLUSH: v_add_f16_e32 23; GFX10-DENORM: v_fmac_f16_e32 {{v[0-9]+, v[0-9]+, v[0-9]+}} 24 25define amdgpu_kernel void @fmuladd_f16(half addrspace(1)* %out, half addrspace(1)* %in1, 26 half addrspace(1)* %in2, half addrspace(1)* %in3) #0 { 27 %r0 = load half, half addrspace(1)* %in1 28 %r1 = load half, half addrspace(1)* %in2 29 %r2 = load half, half addrspace(1)* %in3 30 %r3 = tail call half @llvm.fmuladd.f16(half %r0, half %r1, half %r2) 31 store half %r3, half addrspace(1)* %out 32 ret void 33} 34 35; GCN-LABEL: {{^}}fmuladd_2.0_a_b_f16 36; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 37; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 38; VI-FLUSH: v_mac_f16_e32 [[R2]], 2.0, [[R1]] 39; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 40 41; VI-DENORM: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, [[R2]] 42; GFX10-DENORM: v_fmac_f16_e32 [[R2:v[0-9]+]], 2.0, [[R1]] 43 44; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 45; GFX10-FLUSH: v_add_f16_e32 [[RESULT:v[0-9]+]], [[MUL2]], [[R2]] 46 47; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 48; GFX10-DENORM: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 49; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 50 51define amdgpu_kernel void @fmuladd_2.0_a_b_f16(half addrspace(1)* %out, half addrspace(1)* %in) #0 { 52 %tid = call i32 @llvm.amdgcn.workitem.id.x() 53 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 54 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 55 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 56 57 %r1 = load volatile half, half addrspace(1)* %gep.0 58 %r2 = load volatile half, half addrspace(1)* %gep.1 59 60 %r3 = tail call half @llvm.fmuladd.f16(half 2.0, half %r1, half %r2) 61 store half %r3, half addrspace(1)* %gep.out 62 ret void 63} 64 65; GCN-LABEL: {{^}}fmuladd_a_2.0_b_f16 66; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 67; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 68; VI-FLUSH: v_mac_f16_e32 [[R2]], 2.0, [[R1]] 69; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 70 71; VI-DENORM: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, [[R2]] 72; GFX10-DENORM: v_fmac_f16_e32 [[R2]], 2.0, [[R1]] 73 74; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 75; GFX10-FLUSH: v_add_f16_e32 [[RESULT:v[0-9]+]], [[MUL2]], [[R2]] 76 77; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 78; GFX10-DENORM: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 79; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 80 81define amdgpu_kernel void @fmuladd_a_2.0_b_f16(half addrspace(1)* %out, half addrspace(1)* %in) #0 { 82 %tid = call i32 @llvm.amdgcn.workitem.id.x() 83 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 84 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 85 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 86 87 %r1 = load volatile half, half addrspace(1)* %gep.0 88 %r2 = load volatile half, half addrspace(1)* %gep.1 89 90 %r3 = tail call half @llvm.fmuladd.f16(half %r1, half 2.0, half %r2) 91 store half %r3, half addrspace(1)* %gep.out 92 ret void 93} 94 95; GCN-LABEL: {{^}}fadd_a_a_b_f16: 96; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 97; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 98; VI-FLUSH: v_mac_f16_e32 [[R2]], 2.0, [[R1]] 99; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 100 101; VI-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, [[R2]] 102; GFX10-DENORM-CONTRACT: v_fmac_f16_e32 [[R2]], 2.0, [[R1]] 103 104; GCN-DENORM-STRICT: v_add_f16_e32 [[TMP:v[0-9]+]], [[R1]], [[R1]] 105; GCN-DENORM-STRICT: v_add_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[R2]] 106 107; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 108 109; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 110; GFX10-FLUSH: v_add_f16_e32 [[RESULT:v[0-9]+]], [[MUL2]], [[R2]] 111; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 112; GFX10-DENORM-STRICT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 113; GFX10-DENORM-CONTRACT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 114 115define amdgpu_kernel void @fadd_a_a_b_f16(half addrspace(1)* %out, 116 half addrspace(1)* %in1, 117 half addrspace(1)* %in2) #0 { 118 %tid = call i32 @llvm.amdgcn.workitem.id.x() 119 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 120 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 121 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 122 123 %r0 = load volatile half, half addrspace(1)* %gep.0 124 %r1 = load volatile half, half addrspace(1)* %gep.1 125 126 %add.0 = fadd half %r0, %r0 127 %add.1 = fadd half %add.0, %r1 128 store half %add.1, half addrspace(1)* %gep.out 129 ret void 130} 131 132; GCN-LABEL: {{^}}fadd_b_a_a_f16: 133; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 134; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 135; VI-FLUSH: v_mac_f16_e32 [[R2]], 2.0, [[R1]] 136; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 137 138; VI-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, [[R2]] 139; GFX10-DENORM-CONTRACT: v_fmac_f16_e32 [[R2]], 2.0, [[R1]] 140 141; GCN-DENORM-STRICT: v_add_f16_e32 [[TMP:v[0-9]+]], [[R1]], [[R1]] 142; GCN-DENORM-STRICT: v_add_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[TMP]] 143 144; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 145 146; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 147; GFX10-FLUSH: v_add_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[MUL2]] 148; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 149; GFX10-DENORM-STRICT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 150; GFX10-DENORM-CONTRACT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 151 152define amdgpu_kernel void @fadd_b_a_a_f16(half addrspace(1)* %out, 153 half addrspace(1)* %in1, 154 half addrspace(1)* %in2) #0 { 155 %tid = call i32 @llvm.amdgcn.workitem.id.x() 156 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 157 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 158 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 159 160 %r0 = load volatile half, half addrspace(1)* %gep.0 161 %r1 = load volatile half, half addrspace(1)* %gep.1 162 163 %add.0 = fadd half %r0, %r0 164 %add.1 = fadd half %r1, %add.0 165 store half %add.1, half addrspace(1)* %gep.out 166 ret void 167} 168 169; GCN-LABEL: {{^}}fmuladd_neg_2.0_a_b_f16 170; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 171; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 172; VI-FLUSH: v_mac_f16_e32 [[R2]], -2.0, [[R1]] 173; VI-DENORM: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], -2.0, [[R2]] 174; GFX10-DENORM: v_fmac_f16_e32 [[R2]], -2.0, [[R1]] 175; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 176; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 177; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 178; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[MUL2]] 179; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 180; GFX10-DENORM: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 181define amdgpu_kernel void @fmuladd_neg_2.0_a_b_f16(half addrspace(1)* %out, half addrspace(1)* %in) #0 { 182 %tid = call i32 @llvm.amdgcn.workitem.id.x() 183 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 184 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 185 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 186 187 %r1 = load volatile half, half addrspace(1)* %gep.0 188 %r2 = load volatile half, half addrspace(1)* %gep.1 189 190 %r3 = tail call half @llvm.fmuladd.f16(half -2.0, half %r1, half %r2) 191 store half %r3, half addrspace(1)* %gep.out 192 ret void 193} 194 195; GCN-LABEL: {{^}}fmuladd_neg_2.0_neg_a_b_f16 196; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 197; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 198; VI-FLUSH: v_mac_f16_e32 [[R2]], 2.0, [[R1]] 199; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 200 201; VI-DENORM: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, [[R2]] 202; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 203 204; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 205; GFX10-FLUSH: v_add_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[MUL2]] 206; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 207 208; GFX10-DENORM: v_fmac_f16_e32 [[R2]], 2.0, [[R1]] 209; GFX10-DENORM: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 210define amdgpu_kernel void @fmuladd_neg_2.0_neg_a_b_f16(half addrspace(1)* %out, half addrspace(1)* %in) #0 { 211 %tid = call i32 @llvm.amdgcn.workitem.id.x() 212 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 213 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 214 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 215 216 %r1 = load volatile half, half addrspace(1)* %gep.0 217 %r2 = load volatile half, half addrspace(1)* %gep.1 218 219 %r1.fneg = fsub half -0.000000e+00, %r1 220 221 %r3 = tail call half @llvm.fmuladd.f16(half -2.0, half %r1.fneg, half %r2) 222 store half %r3, half addrspace(1)* %gep.out 223 ret void 224} 225 226; GCN-LABEL: {{^}}fmuladd_2.0_neg_a_b_f16 227; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 228; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 229; VI-FLUSH: v_mac_f16_e32 [[R2]], -2.0, [[R1]] 230; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 231 232; VI-DENORM: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], -2.0, [[R2]] 233; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 234 235; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 236; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[MUL2]] 237; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 238 239; GFX10-DENORM: v_fmac_f16_e32 [[R2]], -2.0, [[R1]] 240; GFX10-DENORM: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 241define amdgpu_kernel void @fmuladd_2.0_neg_a_b_f16(half addrspace(1)* %out, half addrspace(1)* %in) #0 { 242 %tid = call i32 @llvm.amdgcn.workitem.id.x() 243 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 244 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 245 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 246 247 %r1 = load volatile half, half addrspace(1)* %gep.0 248 %r2 = load volatile half, half addrspace(1)* %gep.1 249 250 %r1.fneg = fsub half -0.000000e+00, %r1 251 252 %r3 = tail call half @llvm.fmuladd.f16(half 2.0, half %r1.fneg, half %r2) 253 store half %r3, half addrspace(1)* %gep.out 254 ret void 255} 256 257; GCN-LABEL: {{^}}fmuladd_2.0_a_neg_b_f16 258; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 259; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 260; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, -[[R2]] 261; GCN-DENORM: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, -[[R2]] 262; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 263; GFX10-FLUSH: v_add_f16_e32 [[MUL2:v[0-9]+]], [[R1]], [[R1]] 264; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[MUL2]], [[R2]] 265; GFX10: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 266define amdgpu_kernel void @fmuladd_2.0_a_neg_b_f16(half addrspace(1)* %out, half addrspace(1)* %in) #0 { 267 %tid = call i32 @llvm.amdgcn.workitem.id.x() 268 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 269 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 270 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 271 272 %r1 = load volatile half, half addrspace(1)* %gep.0 273 %r2 = load volatile half, half addrspace(1)* %gep.1 274 275 %r2.fneg = fsub half -0.000000e+00, %r2 276 277 %r3 = tail call half @llvm.fmuladd.f16(half 2.0, half %r1, half %r2.fneg) 278 store half %r3, half addrspace(1)* %gep.out 279 ret void 280} 281 282; GCN-LABEL: {{^}}mad_sub_f16: 283; GCN: {{buffer|flat|global}}_load_ushort [[REGA:v[0-9]+]] 284; GCN: {{buffer|flat|global}}_load_ushort [[REGB:v[0-9]+]] 285; GCN: {{buffer|flat|global}}_load_ushort [[REGC:v[0-9]+]] 286 287; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], [[REGA]], [[REGB]], -[[REGC]] 288 289; GCN-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[REGA]], [[REGB]], -[[REGC]] 290 291; GCN-DENORM-STRICT: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 292; GCN-DENORM-STRICT: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[REGC]] 293 294; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 295 296; GFX10-FLUSH: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 297; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[REGC]] 298; GFX10: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 299define amdgpu_kernel void @mad_sub_f16(half addrspace(1)* noalias nocapture %out, half addrspace(1)* noalias nocapture readonly %ptr) #1 { 300 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() #0 301 %tid.ext = sext i32 %tid to i64 302 %gep0 = getelementptr half, half addrspace(1)* %ptr, i64 %tid.ext 303 %add1 = add i64 %tid.ext, 1 304 %gep1 = getelementptr half, half addrspace(1)* %ptr, i64 %add1 305 %add2 = add i64 %tid.ext, 2 306 %gep2 = getelementptr half, half addrspace(1)* %ptr, i64 %add2 307 %outgep = getelementptr half, half addrspace(1)* %out, i64 %tid.ext 308 %a = load volatile half, half addrspace(1)* %gep0, align 2 309 %b = load volatile half, half addrspace(1)* %gep1, align 2 310 %c = load volatile half, half addrspace(1)* %gep2, align 2 311 %mul = fmul half %a, %b 312 %sub = fsub half %mul, %c 313 store half %sub, half addrspace(1)* %outgep, align 2 314 ret void 315} 316 317; GCN-LABEL: {{^}}mad_sub_inv_f16: 318; GCN: {{buffer|flat|global}}_load_ushort [[REGA:v[0-9]+]] 319; GCN: {{buffer|flat|global}}_load_ushort [[REGB:v[0-9]+]] 320; GCN: {{buffer|flat|global}}_load_ushort [[REGC:v[0-9]+]] 321; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], -[[REGA]], [[REGB]], [[REGC]] 322 323; VI-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], -[[REGA]], [[REGB]], [[REGC]] 324; GFX10-DENORM-CONTRACT: v_fmac_f16_e64 [[REGC]], -[[REGA]], [[REGB]] 325 326; GCN-DENORM-STRICT: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 327; GCN-DENORM-STRICT: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[REGC]], [[TMP]] 328 329; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 330 331; GFX10-FLUSH: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 332; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[REGC]], [[TMP]] 333; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 334; GFX10-DENORM-STRICT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 335; GFX10-DENORM-CONTRACT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[REGC]] 336define amdgpu_kernel void @mad_sub_inv_f16(half addrspace(1)* noalias nocapture %out, half addrspace(1)* noalias nocapture readonly %ptr) #1 { 337 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() #0 338 %tid.ext = sext i32 %tid to i64 339 %gep0 = getelementptr half, half addrspace(1)* %ptr, i64 %tid.ext 340 %add1 = add i64 %tid.ext, 1 341 %gep1 = getelementptr half, half addrspace(1)* %ptr, i64 %add1 342 %add2 = add i64 %tid.ext, 2 343 %gep2 = getelementptr half, half addrspace(1)* %ptr, i64 %add2 344 %outgep = getelementptr half, half addrspace(1)* %out, i64 %tid.ext 345 %a = load volatile half, half addrspace(1)* %gep0, align 2 346 %b = load volatile half, half addrspace(1)* %gep1, align 2 347 %c = load volatile half, half addrspace(1)* %gep2, align 2 348 %mul = fmul half %a, %b 349 %sub = fsub half %c, %mul 350 store half %sub, half addrspace(1)* %outgep, align 2 351 ret void 352} 353 354; GCN-LABEL: {{^}}mad_sub_fabs_f16: 355; GCN: {{buffer|flat|global}}_load_ushort [[REGA:v[0-9]+]] 356; GCN: {{buffer|flat|global}}_load_ushort [[REGB:v[0-9]+]] 357; GCN: {{buffer|flat|global}}_load_ushort [[REGC:v[0-9]+]] 358; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], [[REGA]], [[REGB]], -|[[REGC]]| 359 360; GCN-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[REGA]], [[REGB]], -|[[REGC]]| 361 362; GCN-DENORM-STRICT: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 363; GCN-DENORM-STRICT: v_sub_f16_e64 [[RESULT:v[0-9]+]], [[TMP]], |[[REGC]]| 364 365; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 366 367; GFX10-FLUSH: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 368; GFX10-FLUSH: v_sub_f16_e64 [[RESULT:v[0-9]+]], [[TMP]], |[[REGC]]| 369; GFX10: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 370define amdgpu_kernel void @mad_sub_fabs_f16(half addrspace(1)* noalias nocapture %out, half addrspace(1)* noalias nocapture readonly %ptr) #1 { 371 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() #0 372 %tid.ext = sext i32 %tid to i64 373 %gep0 = getelementptr half, half addrspace(1)* %ptr, i64 %tid.ext 374 %add1 = add i64 %tid.ext, 1 375 %gep1 = getelementptr half, half addrspace(1)* %ptr, i64 %add1 376 %add2 = add i64 %tid.ext, 2 377 %gep2 = getelementptr half, half addrspace(1)* %ptr, i64 %add2 378 %outgep = getelementptr half, half addrspace(1)* %out, i64 %tid.ext 379 %a = load volatile half, half addrspace(1)* %gep0, align 2 380 %b = load volatile half, half addrspace(1)* %gep1, align 2 381 %c = load volatile half, half addrspace(1)* %gep2, align 2 382 %c.abs = call half @llvm.fabs.f16(half %c) #0 383 %mul = fmul half %a, %b 384 %sub = fsub half %mul, %c.abs 385 store half %sub, half addrspace(1)* %outgep, align 2 386 ret void 387} 388 389; GCN-LABEL: {{^}}mad_sub_fabs_inv_f16: 390; GCN: {{buffer|flat|global}}_load_ushort [[REGA:v[0-9]+]] 391; GCN: {{buffer|flat|global}}_load_ushort [[REGB:v[0-9]+]] 392; GCN: {{buffer|flat|global}}_load_ushort [[REGC:v[0-9]+]] 393 394; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], -[[REGA]], [[REGB]], |[[REGC]]| 395 396; GCN-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], -[[REGA]], [[REGB]], |[[REGC]]| 397 398; GCN-DENORM-STRICT: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 399; GCN-DENORM-STRICT: v_sub_f16_e64 [[RESULT:v[0-9]+]], |[[REGC]]|, [[TMP]] 400 401; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 402 403; GFX10-FLUSH: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 404; GFX10-FLUSH: v_sub_f16_e64 [[RESULT:v[0-9]+]], |[[REGC]]|, [[TMP]] 405; GFX10: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 406define amdgpu_kernel void @mad_sub_fabs_inv_f16(half addrspace(1)* noalias nocapture %out, half addrspace(1)* noalias nocapture readonly %ptr) #1 { 407 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() #0 408 %tid.ext = sext i32 %tid to i64 409 %gep0 = getelementptr half, half addrspace(1)* %ptr, i64 %tid.ext 410 %add1 = add i64 %tid.ext, 1 411 %gep1 = getelementptr half, half addrspace(1)* %ptr, i64 %add1 412 %add2 = add i64 %tid.ext, 2 413 %gep2 = getelementptr half, half addrspace(1)* %ptr, i64 %add2 414 %outgep = getelementptr half, half addrspace(1)* %out, i64 %tid.ext 415 %a = load volatile half, half addrspace(1)* %gep0, align 2 416 %b = load volatile half, half addrspace(1)* %gep1, align 2 417 %c = load volatile half, half addrspace(1)* %gep2, align 2 418 %c.abs = call half @llvm.fabs.f16(half %c) #0 419 %mul = fmul half %a, %b 420 %sub = fsub half %c.abs, %mul 421 store half %sub, half addrspace(1)* %outgep, align 2 422 ret void 423} 424 425; GCN-LABEL: {{^}}neg_neg_mad_f16: 426; GCN: {{buffer|flat|global}}_load_ushort [[REGA:v[0-9]+]] 427; GCN: {{buffer|flat|global}}_load_ushort [[REGB:v[0-9]+]] 428; GCN: {{buffer|flat|global}}_load_ushort [[REGC:v[0-9]+]] 429 430; VI-FLUSH: v_mac_f16_e32 [[REGC]], [[REGA]], [[REGB]] 431; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[REGC]] 432 433; VI-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[REGA]], [[REGB]], [[REGC]] 434; GFX10-DENORM-CONTRACT: v_fmac_f16_e32 [[REGC]], [[REGA]], [[REGB]] 435 436; GCN-DENORM-STRICT: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 437; GCN-DENORM-STRICT: v_add_f16_e32 [[RESULT:v[0-9]+]], [[REGC]], [[TMP]] 438; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 439 440; GFX10-FLUSH: v_mul_f16_e32 [[TMP:v[0-9]+]], [[REGA]], [[REGB]] 441; GFX10-FLUSH: v_add_f16_e32 [[RESULT:v[0-9]+]], [[REGC]], [[TMP]] 442; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 443; GFX10-DENORM-STRICT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 444; GFX10-DENORM-CONTRACT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[REGC]] 445define amdgpu_kernel void @neg_neg_mad_f16(half addrspace(1)* noalias nocapture %out, half addrspace(1)* noalias nocapture readonly %ptr) #1 { 446 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() #0 447 %tid.ext = sext i32 %tid to i64 448 %gep0 = getelementptr half, half addrspace(1)* %ptr, i64 %tid.ext 449 %add1 = add i64 %tid.ext, 1 450 %gep1 = getelementptr half, half addrspace(1)* %ptr, i64 %add1 451 %add2 = add i64 %tid.ext, 2 452 %gep2 = getelementptr half, half addrspace(1)* %ptr, i64 %add2 453 %outgep = getelementptr half, half addrspace(1)* %out, i64 %tid.ext 454 %a = load volatile half, half addrspace(1)* %gep0, align 2 455 %b = load volatile half, half addrspace(1)* %gep1, align 2 456 %c = load volatile half, half addrspace(1)* %gep2, align 2 457 %nega = fsub half -0.000000e+00, %a 458 %negb = fsub half -0.000000e+00, %b 459 %mul = fmul half %nega, %negb 460 %sub = fadd half %mul, %c 461 store half %sub, half addrspace(1)* %outgep, align 2 462 ret void 463} 464 465; GCN-LABEL: {{^}}mad_fabs_sub_f16: 466; GCN: {{buffer|flat|global}}_load_ushort [[REGA:v[0-9]+]] 467; GCN: {{buffer|flat|global}}_load_ushort [[REGB:v[0-9]+]] 468; GCN: {{buffer|flat|global}}_load_ushort [[REGC:v[0-9]+]] 469 470; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], [[REGA]], |[[REGB]]|, -[[REGC]] 471 472; GCN-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[REGA]], |[[REGB]]|, -[[REGC]] 473 474; GCN-DENORM-STRICT: v_mul_f16_e64 [[TMP:v[0-9]+]], [[REGA]], |[[REGB]]| 475; GCN-DENORM-STRICT: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[REGC]] 476 477; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 478 479; GFX10-FLUSH: v_mul_f16_e64 [[TMP:v[0-9]+]], [[REGA]], |[[REGB]]| 480; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[REGC]] 481; GFX10: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 482define amdgpu_kernel void @mad_fabs_sub_f16(half addrspace(1)* noalias nocapture %out, half addrspace(1)* noalias nocapture readonly %ptr) #1 { 483 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() #0 484 %tid.ext = sext i32 %tid to i64 485 %gep0 = getelementptr half, half addrspace(1)* %ptr, i64 %tid.ext 486 %add1 = add i64 %tid.ext, 1 487 %gep1 = getelementptr half, half addrspace(1)* %ptr, i64 %add1 488 %add2 = add i64 %tid.ext, 2 489 %gep2 = getelementptr half, half addrspace(1)* %ptr, i64 %add2 490 %outgep = getelementptr half, half addrspace(1)* %out, i64 %tid.ext 491 %a = load volatile half, half addrspace(1)* %gep0, align 2 492 %b = load volatile half, half addrspace(1)* %gep1, align 2 493 %c = load volatile half, half addrspace(1)* %gep2, align 2 494 %b.abs = call half @llvm.fabs.f16(half %b) #0 495 %mul = fmul half %a, %b.abs 496 %sub = fsub half %mul, %c 497 store half %sub, half addrspace(1)* %outgep, align 2 498 ret void 499} 500 501; GCN-LABEL: {{^}}fsub_c_fadd_a_a_f16: 502; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 503; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 504; VI-FLUSH: v_mac_f16_e32 [[R2]], -2.0, [[R1]] 505; VI-FLUSH: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 506 507; VI-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], -2.0, [[R2]] 508; GFX10-DENORM-CONTRACT: v_fmac_f16_e32 [[R2]], -2.0, [[R1]] 509 510; GCN-DENORM-STRICT: v_add_f16_e32 [[TMP:v[0-9]+]], [[R1]], [[R1]] 511; GCN-DENORM-STRICT: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[TMP]] 512 513; VI-DENORM: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 514 515; GFX10-FLUSH: v_add_f16_e32 [[TMP:v[0-9]+]], [[R1]], [[R1]] 516; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[R2]], [[TMP]] 517; GFX10-FLUSH: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 518; GFX10-DENORM-STRICT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 519; GFX10-DENORM-CONTRACT: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[R2]] 520define amdgpu_kernel void @fsub_c_fadd_a_a_f16(half addrspace(1)* %out, half addrspace(1)* %in) { 521 %tid = call i32 @llvm.amdgcn.workitem.id.x() 522 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 523 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 524 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 525 526 %r1 = load volatile half, half addrspace(1)* %gep.0 527 %r2 = load volatile half, half addrspace(1)* %gep.1 528 529 %add = fadd half %r1, %r1 530 %r3 = fsub half %r2, %add 531 532 store half %r3, half addrspace(1)* %gep.out 533 ret void 534} 535 536; GCN-LABEL: {{^}}fsub_fadd_a_a_c_f16: 537; GCN: {{buffer|flat|global}}_load_ushort [[R1:v[0-9]+]], 538; GCN: {{buffer|flat|global}}_load_ushort [[R2:v[0-9]+]], 539 540; VI-FLUSH: v_mad_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, -[[R2]] 541 542; GCN-DENORM-CONTRACT: v_fma_f16 [[RESULT:v[0-9]+]], [[R1]], 2.0, -[[R2]] 543 544; GCN-DENORM-STRICT: v_add_f16_e32 [[TMP:v[0-9]+]], [[R1]], [[R1]] 545; GCN-DENORM-STRICT: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[R2]] 546 547; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 548 549; GFX10-FLUSH: v_add_f16_e32 [[TMP:v[0-9]+]], [[R1]], [[R1]] 550; GFX10-FLUSH: v_sub_f16_e32 [[RESULT:v[0-9]+]], [[TMP]], [[R2]] 551; GFX10: global_store_short v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]] 552define amdgpu_kernel void @fsub_fadd_a_a_c_f16(half addrspace(1)* %out, half addrspace(1)* %in) { 553 %tid = call i32 @llvm.amdgcn.workitem.id.x() 554 %gep.0 = getelementptr half, half addrspace(1)* %out, i32 %tid 555 %gep.1 = getelementptr half, half addrspace(1)* %gep.0, i32 1 556 %gep.out = getelementptr half, half addrspace(1)* %out, i32 %tid 557 558 %r1 = load volatile half, half addrspace(1)* %gep.0 559 %r2 = load volatile half, half addrspace(1)* %gep.1 560 561 %add = fadd half %r1, %r1 562 %r3 = fsub half %add, %r2 563 564 store half %r3, half addrspace(1)* %gep.out 565 ret void 566} 567 568attributes #0 = { nounwind } 569attributes #1 = { nounwind readnone } 570