1 ; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=tahiti -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=SI %s 2 ; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=fiji -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=VI %s 3 4 declare half @llvm.fma.f16(half %a, half %b, half %c) 5 declare <2 x half> @llvm.fma.v2f16(<2 x half> %a, <2 x half> %b, <2 x half> %c) 6 7 ; GCN-LABEL: {{^}}fma_f16 8 ; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] 9 ; GCN: buffer_load_ushort v[[B_F16:[0-9]+]] 10 ; GCN: buffer_load_ushort v[[C_F16:[0-9]+]] 11 ; SI: v_cvt_f32_f16_e32 v[[A_F32:[0-9]+]], v[[A_F16]] 12 ; SI: v_cvt_f32_f16_e32 v[[B_F32:[0-9]+]], v[[B_F16]] 13 ; SI: v_cvt_f32_f16_e32 v[[C_F32:[0-9]+]], v[[C_F16]] 14 ; SI: v_fma_f32 v[[R_F32:[0-9]+]], v[[A_F32:[0-9]]], v[[B_F32:[0-9]]], v[[C_F32:[0-9]]] 15 ; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[R_F32]] 16 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[A_F16]], v[[B_F16]], v[[C_F16]] 17 ; GCN: buffer_store_short v[[R_F16]] 18 ; GCN: s_endpgm 19 define amdgpu_kernel void @fma_f16( 20 half addrspace(1)* %r, 21 half addrspace(1)* %a, 22 half addrspace(1)* %b, 23 half addrspace(1)* %c) { 24 %a.val = load half, half addrspace(1)* %a 25 %b.val = load half, half addrspace(1)* %b 26 %c.val = load half, half addrspace(1)* %c 27 %r.val = call half @llvm.fma.f16(half %a.val, half %b.val, half %c.val) 28 store half %r.val, half addrspace(1)* %r 29 ret void 30 } 31 32 ; GCN-LABEL: {{^}}fma_f16_imm_a 33 ; GCN: buffer_load_ushort v[[B_F16:[0-9]+]] 34 ; GCN: buffer_load_ushort v[[C_F16:[0-9]+]] 35 36 ; SI: v_mov_b32_e32 v[[A_F32:[0-9]+]], 0x40400000{{$}} 37 ; SI: v_cvt_f32_f16_e32 v[[B_F32:[0-9]+]], v[[B_F16]] 38 ; SI: v_cvt_f32_f16_e32 v[[C_F32:[0-9]+]], v[[C_F16]] 39 ; SI: v_fma_f32 v[[R_F32:[0-9]+]], v[[A_F32:[0-9]]], v[[B_F32:[0-9]]], v[[C_F32:[0-9]]] 40 ; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[R_F32]] 41 ; VI: v_mov_b32_e32 v[[A_F16:[0-9]+]], 0x4200{{$}} 42 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[B_F16]], v[[A_F16]], v[[C_F16]] 43 ; GCN: buffer_store_short v[[R_F16]] 44 ; GCN: s_endpgm 45 define amdgpu_kernel void @fma_f16_imm_a( 46 half addrspace(1)* %r, 47 half addrspace(1)* %b, 48 half addrspace(1)* %c) { 49 %b.val = load half, half addrspace(1)* %b 50 %c.val = load half, half addrspace(1)* %c 51 %r.val = call half @llvm.fma.f16(half 3.0, half %b.val, half %c.val) 52 store half %r.val, half addrspace(1)* %r 53 ret void 54 } 55 56 ; GCN-LABEL: {{^}}fma_f16_imm_b 57 ; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] 58 ; GCN: buffer_load_ushort v[[C_F16:[0-9]+]] 59 ; SI: v_mov_b32_e32 v[[B_F32:[0-9]+]], 0x40400000{{$}} 60 ; SI: v_cvt_f32_f16_e32 v[[A_F32:[0-9]+]], v[[A_F16]] 61 ; SI: v_cvt_f32_f16_e32 v[[C_F32:[0-9]+]], v[[C_F16]] 62 ; SI: v_fma_f32 v[[R_F32:[0-9]+]], v[[A_F32:[0-9]]], v[[B_F32:[0-9]]], v[[C_F32:[0-9]]] 63 ; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[R_F32]] 64 ; VI: v_mov_b32_e32 v[[B_F16:[0-9]+]], 0x4200{{$}} 65 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[A_F16]], v[[B_F16]], v[[C_F16]] 66 ; GCN: buffer_store_short v[[R_F16]] 67 ; GCN: s_endpgm 68 define amdgpu_kernel void @fma_f16_imm_b( 69 half addrspace(1)* %r, 70 half addrspace(1)* %a, 71 half addrspace(1)* %c) { 72 %a.val = load half, half addrspace(1)* %a 73 %c.val = load half, half addrspace(1)* %c 74 %r.val = call half @llvm.fma.f16(half %a.val, half 3.0, half %c.val) 75 store half %r.val, half addrspace(1)* %r 76 ret void 77 } 78 79 ; GCN-LABEL: {{^}}fma_f16_imm_c 80 ; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] 81 ; GCN: buffer_load_ushort v[[B_F16:[0-9]+]] 82 ; SI: v_mov_b32_e32 v[[C_F32:[0-9]+]], 0x40400000{{$}} 83 ; SI: v_cvt_f32_f16_e32 v[[A_F32:[0-9]+]], v[[A_F16]] 84 ; SI: v_cvt_f32_f16_e32 v[[B_F32:[0-9]+]], v[[B_F16]] 85 ; SI: v_fma_f32 v[[R_F32:[0-9]+]], v[[A_F32:[0-9]]], v[[B_F32:[0-9]]], v[[C_F32:[0-9]]] 86 ; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[R_F32]] 87 ; VI: v_mov_b32_e32 v[[C_F16:[0-9]+]], 0x4200{{$}} 88 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[A_F16]], v[[B_F16]], v[[C_F16]] 89 ; GCN: buffer_store_short v[[R_F16]] 90 ; GCN: s_endpgm 91 define amdgpu_kernel void @fma_f16_imm_c( 92 half addrspace(1)* %r, 93 half addrspace(1)* %a, 94 half addrspace(1)* %b) { 95 %a.val = load half, half addrspace(1)* %a 96 %b.val = load half, half addrspace(1)* %b 97 %r.val = call half @llvm.fma.f16(half %a.val, half %b.val, half 3.0) 98 store half %r.val, half addrspace(1)* %r 99 ret void 100 } 101 102 ; GCN-LABEL: {{^}}fma_v2f16 103 ; GCN: buffer_load_dword v[[A_V2_F16:[0-9]+]] 104 ; GCN: buffer_load_dword v[[B_V2_F16:[0-9]+]] 105 ; GCN: buffer_load_dword v[[C_V2_F16:[0-9]+]] 106 107 ; SI: v_cvt_f32_f16_e32 v[[A_F32_0:[0-9]+]], v[[A_V2_F16]] 108 ; SI: v_lshrrev_b32_e32 v[[B_F16_1:[0-9]+]], 16, v[[B_V2_F16]] 109 ; SI: v_lshrrev_b32_e32 v[[C_F16_1:[0-9]+]], 16, v[[C_V2_F16]] 110 ; SI: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 111 ; SI: v_cvt_f32_f16_e32 v[[A_F32_1:[0-9]+]], v[[A_F16_1]] 112 ; SI: v_cvt_f32_f16_e32 v[[B_F32_1:[0-9]+]], v[[B_F16_1]] 113 ; SI: v_cvt_f32_f16_e32 v[[C_F32_1:[0-9]+]], v[[C_F16_1]] 114 115 ; SI: v_cvt_f32_f16_e32 v[[B_F32_0:[0-9]+]], v[[B_V2_F16]] 116 ; SI: v_cvt_f32_f16_e32 v[[C_F32_0:[0-9]+]], v[[C_V2_F16]] 117 118 119 ; SI-DAG: v_fma_f32 v[[R_F32_0:[0-9]+]], v[[A_F32_0]], v[[B_F32_0]], v[[C_F32_0]] 120 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_0:[0-9]+]], v[[R_F32_0]] 121 ; SI-DAG: v_fma_f32 v[[R_F32_1:[0-9]+]], v[[A_F32_1]], v[[B_F32_1]], v[[C_F32_1]] 122 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_1:[0-9]+]], v[[R_F32_1]] 123 124 ; VI: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 125 ; VI: v_lshrrev_b32_e32 v[[B_F16_1:[0-9]+]], 16, v[[B_V2_F16]] 126 ; VI: v_lshrrev_b32_e32 v[[C_F16_1:[0-9]+]], 16, v[[C_V2_F16]] 127 ; VI-DAG: v_fma_f16 v[[R_F16_0:[0-9]+]], v[[A_V2_F16]], v[[B_V2_F16]], v[[C_V2_F16]] 128 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[A_F16_1]], v[[B_F16_1]], v[[C_F16_1]] 129 130 ; GCN-DAG: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]] 131 ; GCN-NOT: and 132 ; GCN: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_HI]] 133 ; GCN: buffer_store_dword v[[R_V2_F16]] 134 ; GCN: s_endpgm 135 define amdgpu_kernel void @fma_v2f16( 136 <2 x half> addrspace(1)* %r, 137 <2 x half> addrspace(1)* %a, 138 <2 x half> addrspace(1)* %b, 139 <2 x half> addrspace(1)* %c) { 140 %a.val = load <2 x half>, <2 x half> addrspace(1)* %a 141 %b.val = load <2 x half>, <2 x half> addrspace(1)* %b 142 %c.val = load <2 x half>, <2 x half> addrspace(1)* %c 143 %r.val = call <2 x half> @llvm.fma.v2f16(<2 x half> %a.val, <2 x half> %b.val, <2 x half> %c.val) 144 store <2 x half> %r.val, <2 x half> addrspace(1)* %r 145 ret void 146 } 147 148 ; GCN-LABEL: {{^}}fma_v2f16_imm_a: 149 ; SI: buffer_load_dword v[[C_V2_F16:[0-9]+]] 150 ; SI: buffer_load_dword v[[B_V2_F16:[0-9]+]] 151 152 153 ; VI: buffer_load_dword v[[C_V2_F16:[0-9]+]] 154 ; VI: buffer_load_dword v[[B_V2_F16:[0-9]+]] 155 156 157 ; SI: v_mov_b32_e32 v[[A_F32:[0-9]+]], 0x40400000{{$}} 158 ; VI: v_mov_b32_e32 v[[A_F16:[0-9]+]], 0x4200{{$}} 159 ; GCN-DAG: v_lshrrev_b32_e32 v[[B_F16_1:[0-9]+]], 16, v[[B_V2_F16]] 160 ; GCN-DAG: v_lshrrev_b32_e32 v[[C_F16_1:[0-9]+]], 16, v[[C_V2_F16]] 161 162 ; SI: v_cvt_f32_f16_e32 v[[C_F32_1:[0-9]+]], v[[C_F16_1]] 163 ; SI: v_cvt_f32_f16_e32 v[[B_F32_1:[0-9]+]], v[[B_F16_1]] 164 ; SI: v_cvt_f32_f16_e32 v[[C_F32_0:[0-9]+]], v[[C_V2_F16]] 165 ; SI: v_cvt_f32_f16_e32 v[[B_F32_0:[0-9]+]], v[[B_V2_F16]] 166 167 ; SI: v_fma_f32 v[[R_F32_1:[0-9]+]], v[[B_F32_1]], v[[A_F32]], v[[C_F32_1]] 168 ; SI-DAG: v_fma_f32 v[[R_F32_0:[0-9]+]], v[[B_F32_0]], v[[A_F32]], v[[C_F32_0]] 169 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_0:[0-9]+]], v[[R_F32_0]] 170 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_1:[0-9]+]], v[[R_F32_1]] 171 172 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[C_F16_1]], v[[A_F16]], v[[B_F16_1]] 173 ; VI-DAG: v_fma_f16 v[[R_F16_0:[0-9]+]], v[[C_V2_F16]], v[[A_F16]], v[[B_V2_F16]] 174 175 ; GCN-DAG: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]] 176 ; GCN-NOT: and 177 ; GCN: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_HI]] 178 ; GCN: buffer_store_dword v[[R_V2_F16]] 179 ; GCN: s_endpgm 180 define amdgpu_kernel void @fma_v2f16_imm_a( 181 <2 x half> addrspace(1)* %r, 182 <2 x half> addrspace(1)* %b, 183 <2 x half> addrspace(1)* %c) { 184 %b.val = load <2 x half>, <2 x half> addrspace(1)* %b 185 %c.val = load <2 x half>, <2 x half> addrspace(1)* %c 186 %r.val = call <2 x half> @llvm.fma.v2f16(<2 x half> <half 3.0, half 3.0>, <2 x half> %b.val, <2 x half> %c.val) 187 store <2 x half> %r.val, <2 x half> addrspace(1)* %r 188 ret void 189 } 190 191 ; GCN-LABEL: {{^}}fma_v2f16_imm_b: 192 ; SI: buffer_load_dword v[[C_V2_F16:[0-9]+]] 193 ; SI: buffer_load_dword v[[A_V2_F16:[0-9]+]] 194 195 ; VI: buffer_load_dword v[[A_V2_F16:[0-9]+]] 196 ; VI: buffer_load_dword v[[C_V2_F16:[0-9]+]] 197 198 ; SI: v_mov_b32_e32 v[[B_F32:[0-9]+]], 0x40400000{{$}} 199 ; VI: v_mov_b32_e32 v[[B_F16:[0-9]+]], 0x4200{{$}} 200 201 ; SI-DAG: v_cvt_f32_f16_e32 v[[A_F32_0:[0-9]+]], v[[A_V2_F16]] 202 ; SI-DAG: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 203 ; SI-DAG: v_cvt_f32_f16_e32 v[[C_F32_0:[0-9]+]], v[[C_V2_F16]] 204 ; SI-DAG: v_lshrrev_b32_e32 v[[C_F16_1:[0-9]+]], 16, v[[C_V2_F16]] 205 206 ; SI-DAG: v_cvt_f32_f16_e32 v[[A_F32_1:[0-9]+]], v[[A_F16_1]] 207 ; SI-DAG: v_cvt_f32_f16_e32 v[[C_F32_1:[0-9]+]], v[[C_F16_1]] 208 ; SI-DAG: v_fma_f32 v[[R_F32_0:[0-9]+]], v[[A_F32_0]], v[[B_F32]], v[[C_F32_0]] 209 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_0:[0-9]+]], v[[R_F32_0]] 210 ; SI-DAG: v_fma_f32 v[[R_F32_1:[0-9]+]], v[[A_F32_1]], v[[B_F32]], v[[C_F32_1]] 211 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_1:[0-9]+]], v[[R_F32_1]] 212 213 ; VI-DAG: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 214 ; VI-DAG: v_lshrrev_b32_e32 v[[C_F16_1:[0-9]+]], 16, v[[C_V2_F16]] 215 ; VI-DAG: v_fma_f16 v[[R_F16_0:[0-9]+]], v[[A_V2_F16]], v[[B_F16]], v[[C_V2_F16]] 216 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[A_F16_1]], v[[B_F16]], v[[C_F16_1]] 217 218 ; GCN-DAG: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]] 219 ; GCN-NOT: and 220 ; GCN: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_HI]] 221 ; GCN: buffer_store_dword v[[R_V2_F16]] 222 ; GCN: s_endpgm 223 define amdgpu_kernel void @fma_v2f16_imm_b( 224 <2 x half> addrspace(1)* %r, 225 <2 x half> addrspace(1)* %a, 226 <2 x half> addrspace(1)* %c) { 227 %a.val = load <2 x half>, <2 x half> addrspace(1)* %a 228 %c.val = load <2 x half>, <2 x half> addrspace(1)* %c 229 %r.val = call <2 x half> @llvm.fma.v2f16(<2 x half> %a.val, <2 x half> <half 3.0, half 3.0>, <2 x half> %c.val) 230 store <2 x half> %r.val, <2 x half> addrspace(1)* %r 231 ret void 232 } 233 234 ; GCN-LABEL: {{^}}fma_v2f16_imm_c: 235 ; SI: buffer_load_dword v[[B_V2_F16:[0-9]+]] 236 ; SI: buffer_load_dword v[[A_V2_F16:[0-9]+]] 237 238 ; VI: buffer_load_dword v[[A_V2_F16:[0-9]+]] 239 ; VI: buffer_load_dword v[[B_V2_F16:[0-9]+]] 240 241 ; SI: v_mov_b32_e32 v[[C_F32:[0-9]+]], 0x40400000{{$}} 242 ; VI: v_mov_b32_e32 v[[C_F16:[0-9]+]], 0x4200{{$}} 243 244 ; SI: v_lshrrev_b32_e32 v[[B_F16_1:[0-9]+]], 16, v[[B_V2_F16]] 245 ; SI: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 246 247 ; SI-DAG: v_cvt_f32_f16_e32 v[[A_F32_0:[0-9]+]], v[[A_V2_F16]] 248 ; SI-DAG: v_cvt_f32_f16_e32 v[[B_F32_0:[0-9]+]], v[[B_V2_F16]] 249 250 ; SI-DAG: v_cvt_f32_f16_e32 v[[B_F32_1:[0-9]+]], v[[B_F16_1]] 251 ; SI-DAG: v_cvt_f32_f16_e32 v[[A_F32_1:[0-9]+]], v[[A_F16_1]] 252 253 ; SI: v_fma_f32 v[[R_F32_1:[0-9]+]], v[[A_F32_1]], v[[B_F32_1]], v[[C_F32]] 254 ; SI-DAG: v_fma_f32 v[[R_F32_0:[0-9]+]], v[[A_F32_0]], v[[B_F32_0]], v[[C_F32]] 255 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_0:[0-9]+]], v[[R_F32_0]] 256 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_1:[0-9]+]], v[[R_F32_1]] 257 ; SI: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]] 258 ; GCN-NOT: and 259 ; SI: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_HI]] 260 261 ; VI-DAG: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 262 ; VI-DAG: v_lshrrev_b32_e32 v[[B_F16_1:[0-9]+]], 16, v[[B_V2_F16]] 263 ; VI-DAG: v_fma_f16 v[[R_F16_0:[0-9]+]], v[[A_V2_F16]], v[[B_V2_F16]], v[[C_F16]] 264 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[A_F16_1]], v[[B_F16_1]], v[[C_F16]] 265 ; GCN-NOT: and 266 ; VI: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_1]] 267 268 269 ; GCN: buffer_store_dword v[[R_V2_F16]] 270 ; GCN: s_endpgm 271 define amdgpu_kernel void @fma_v2f16_imm_c( 272 <2 x half> addrspace(1)* %r, 273 <2 x half> addrspace(1)* %a, 274 <2 x half> addrspace(1)* %b) { 275 %a.val = load <2 x half>, <2 x half> addrspace(1)* %a 276 %b.val = load <2 x half>, <2 x half> addrspace(1)* %b 277 %r.val = call <2 x half> @llvm.fma.v2f16(<2 x half> %a.val, <2 x half> %b.val, <2 x half> <half 3.0, half 3.0>) 278 store <2 x half> %r.val, <2 x half> addrspace(1)* %r 279 ret void 280 } 281