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
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)
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]]
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
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]+]]
36 ; SI: s_mov_b32 s[[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[[B_F32:[0-9]]], s[[A_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: s_movk_i32 s[[A_F16:[0-9]+]], 0x4200{{$}}
42 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[B_F16]], s[[A_F16]], v[[C_F16]]
43 ; GCN: buffer_store_short v[[R_F16]]
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
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: s_mov_b32 s[[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]]], s[[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: s_movk_i32 s[[B_F16:[0-9]+]], 0x4200{{$}}
65 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[A_F16]], s[[B_F16]], v[[C_F16]]
66 ; GCN: buffer_store_short v[[R_F16]]
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
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: s_mov_b32 s[[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]]], s[[C_F32:[0-9]]]
86 ; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[R_F32]]
87 ; VI: s_movk_i32 s[[C_F16:[0-9]+]], 0x4200{{$}}
88 ; VI: v_fma_f16 v[[R_F16:[0-9]+]], v[[A_F16]], v[[B_F16]], s[[C_F16]]
89 ; GCN: buffer_store_short v[[R_F16]]
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
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]+]]
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]]
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]]
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]]
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]]
130 ; GCN-DAG: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]]
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]]
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
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]+]]
153 ; VI: buffer_load_dword v[[C_V2_F16:[0-9]+]]
154 ; VI: buffer_load_dword v[[B_V2_F16:[0-9]+]]
157 ; SI: s_mov_b32 s[[A_F32:[0-9]+]], 0x40400000{{$}}
158 ; VI: s_movk_i32 s[[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]]
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]]
167 ; SI: v_fma_f32 v[[R_F32_1:[0-9]+]], v[[B_F32_1]], s[[A_F32]], v[[C_F32_1]]
168 ; SI-DAG: v_fma_f32 v[[R_F32_0:[0-9]+]], v[[B_F32_0]], s[[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]]
172 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[C_F16_1]], s[[A_F16]], v[[B_F16_1]]
173 ; VI-DAG: v_fma_f16 v[[R_F16_0:[0-9]+]], v[[C_V2_F16]], s[[A_F16]], v[[B_V2_F16]]
175 ; GCN-DAG: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]]
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]]
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
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]+]]
195 ; VI: buffer_load_dword v[[A_V2_F16:[0-9]+]]
196 ; VI: buffer_load_dword v[[C_V2_F16:[0-9]+]]
198 ; SI: s_mov_b32 s[[B_F32:[0-9]+]], 0x40400000{{$}}
199 ; VI: s_movk_i32 s[[B_F16:[0-9]+]], 0x4200{{$}}
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]]
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]], s[[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]], s[[B_F32]], v[[C_F32_1]]
211 ; SI-DAG: v_cvt_f16_f32_e32 v[[R_F16_1:[0-9]+]], v[[R_F32_1]]
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]], s[[B_F16]], v[[C_V2_F16]]
216 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[A_F16_1]], s[[B_F16]], v[[C_F16_1]]
218 ; GCN-DAG: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]]
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]]
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
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]+]]
238 ; VI: buffer_load_dword v[[A_V2_F16:[0-9]+]]
239 ; VI: buffer_load_dword v[[B_V2_F16:[0-9]+]]
241 ; SI: s_mov_b32 s[[C_F32:[0-9]+]], 0x40400000{{$}}
242 ; VI: s_movk_i32 s[[C_F16:[0-9]+]], 0x4200{{$}}
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]]
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]]
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]]
253 ; SI: v_fma_f32 v[[R_F32_1:[0-9]+]], v[[A_F32_1]], v[[B_F32_1]], s[[C_F32]]
254 ; SI-DAG: v_fma_f32 v[[R_F32_0:[0-9]+]], v[[A_F32_0]], v[[B_F32_0]], s[[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]]
259 ; SI: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_HI]]
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]], s[[C_F16]]
264 ; VI-DAG: v_fma_f16 v[[R_F16_1:[0-9]+]], v[[A_F16_1]], v[[B_F16_1]], s[[C_F16]]
266 ; VI: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_0]], v[[R_F16_1]]
269 ; GCN: buffer_store_dword v[[R_V2_F16]]
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