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