1; RUN: llc -march=amdgcn -mcpu=tahiti -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI,GFX678 %s
2; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX89,GFX678 %s
3; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX89,GFX9 %s
4
5; GCN-LABEL: {{^}}v_clamp_f32:
6; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
7; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
8define amdgpu_kernel void @v_clamp_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
9  %tid = call i32 @llvm.amdgcn.workitem.id.x()
10  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
11  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
12  %a = load float, float addrspace(1)* %gep0
13  %max = call float @llvm.maxnum.f32(float %a, float 0.0)
14  %med = call float @llvm.minnum.f32(float %max, float 1.0)
15
16  store float %med, float addrspace(1)* %out.gep
17  ret void
18}
19
20; GCN-LABEL: {{^}}v_clamp_neg_f32:
21; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
22; GCN: v_max_f32_e64 v{{[0-9]+}}, -[[A]], -[[A]] clamp{{$}}
23define amdgpu_kernel void @v_clamp_neg_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
24  %tid = call i32 @llvm.amdgcn.workitem.id.x()
25  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
26  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
27  %a = load float, float addrspace(1)* %gep0
28  %fneg.a = fneg float %a
29  %max = call float @llvm.maxnum.f32(float %fneg.a, float 0.0)
30  %med = call float @llvm.minnum.f32(float %max, float 1.0)
31
32  store float %med, float addrspace(1)* %out.gep
33  ret void
34}
35
36; GCN-LABEL: {{^}}v_clamp_negabs_f32:
37; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
38; GCN: v_max_f32_e64 v{{[0-9]+}}, -|[[A]]|, -|[[A]]| clamp{{$}}
39define amdgpu_kernel void @v_clamp_negabs_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
40  %tid = call i32 @llvm.amdgcn.workitem.id.x()
41  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
42  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
43  %a = load float, float addrspace(1)* %gep0
44  %fabs.a = call float @llvm.fabs.f32(float %a)
45  %fneg.fabs.a = fneg float %fabs.a
46
47  %max = call float @llvm.maxnum.f32(float %fneg.fabs.a, float 0.0)
48  %med = call float @llvm.minnum.f32(float %max, float 1.0)
49
50  store float %med, float addrspace(1)* %out.gep
51  ret void
52}
53
54; GCN-LABEL: {{^}}v_clamp_negzero_f32:
55; GCN-DAG: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
56; GCN-DAG: v_add_f32_e32 [[ADD:v[0-9]+]], 0.5, [[A]]
57; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0x80000000, [[ADD]]
58; GCN: v_min_f32_e32 v{{[0-9]+}}, 1.0, [[MAX]]
59define amdgpu_kernel void @v_clamp_negzero_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
60  %tid = call i32 @llvm.amdgcn.workitem.id.x()
61  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
62  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
63  %a = load float, float addrspace(1)* %gep0
64  %add = fadd nnan float %a, 0.5
65  %max = call float @llvm.maxnum.f32(float %add, float -0.0)
66  %med = call float @llvm.minnum.f32(float %max, float 1.0)
67
68  store float %med, float addrspace(1)* %out.gep
69  ret void
70}
71
72; FIXME: Weird inconsistency in how -0.0 is treated. Accepted if clamp
73; matched through med3, not if directly. Is this correct?
74
75; GCN-LABEL: {{^}}v_clamp_negzero_maybe_snan_f32:
76; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
77; GFX678: v_mul_f32_e32 [[QUIET:v[0-9]+]], 1.0, [[A]]
78; GFX9: v_max_f32_e32 [[QUIET:v[0-9]+]], [[A]], [[A]]
79; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0x80000000, [[QUIET]]
80; GCN: v_min_f32_e32 [[MIN:v[0-9]+]], 1.0, [[MAX]]
81define amdgpu_kernel void @v_clamp_negzero_maybe_snan_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
82  %tid = call i32 @llvm.amdgcn.workitem.id.x()
83  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
84  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
85  %a = load float, float addrspace(1)* %gep0
86  %max = call float @llvm.maxnum.f32(float %a, float -0.0)
87  %med = call float @llvm.minnum.f32(float %max, float 1.0)
88
89  store float %med, float addrspace(1)* %out.gep
90  ret void
91}
92
93; GCN-LABEL: {{^}}v_clamp_multi_use_max_f32:
94; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
95; GFX678: v_mul_f32_e32 [[QUIET_A:v[0-9]+]], 1.0, [[A]]
96; GFX9: v_max_f32_e32 [[QUIET_A:v[0-9]+]], [[A]], [[A]]
97; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0, [[QUIET_A]]
98; GCN: v_min_f32_e32 [[MED:v[0-9]+]], 1.0, [[QUIET_A]]
99; GCN-NOT: [[MAX]]
100; GCN-NOT: [[MED]]
101
102; SI: buffer_store_dword [[MED]]
103; SI: buffer_store_dword [[MAX]]
104
105; GFX89: {{flat|global}}_store_dword v{{.+}}, [[MED]]
106; GFX89: {{flat|global}}_store_dword v{{.+}}, [[MAX]]
107define amdgpu_kernel void @v_clamp_multi_use_max_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
108  %tid = call i32 @llvm.amdgcn.workitem.id.x()
109  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
110  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
111  %a = load float, float addrspace(1)* %gep0
112  %max = call float @llvm.maxnum.f32(float %a, float 0.0)
113  %med = call float @llvm.minnum.f32(float %max, float 1.0)
114
115  store float %med, float addrspace(1)* %out.gep
116  store volatile float %max, float addrspace(1)* undef
117  ret void
118}
119
120; GCN-LABEL: {{^}}v_clamp_f16:
121; GCN: {{buffer|flat|global}}_load_ushort [[A:v[0-9]+]]
122; GFX89: v_max_f16_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
123
124; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], [[A]] clamp{{$}}
125; SI: v_cvt_f16_f32_e32 v{{[0-9]+}}, [[CVT]]
126define amdgpu_kernel void @v_clamp_f16(half addrspace(1)* %out, half addrspace(1)* %aptr) #0 {
127  %tid = call i32 @llvm.amdgcn.workitem.id.x()
128  %gep0 = getelementptr half, half addrspace(1)* %aptr, i32 %tid
129  %out.gep = getelementptr half, half addrspace(1)* %out, i32 %tid
130  %a = load half, half addrspace(1)* %gep0
131  %max = call half @llvm.maxnum.f16(half %a, half 0.0)
132  %med = call half @llvm.minnum.f16(half %max, half 1.0)
133
134  store half %med, half addrspace(1)* %out.gep
135  ret void
136}
137
138; GCN-LABEL: {{^}}v_clamp_neg_f16:
139; GCN: {{buffer|flat|global}}_load_ushort [[A:v[0-9]+]]
140; GFX89: v_max_f16_e64 v{{[0-9]+}}, -[[A]], -[[A]] clamp{{$}}
141
142; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], -[[A]] clamp{{$}}
143; SI: v_cvt_f16_f32_e32 v{{[0-9]+}}, [[CVT]]
144define amdgpu_kernel void @v_clamp_neg_f16(half addrspace(1)* %out, half addrspace(1)* %aptr) #0 {
145  %tid = call i32 @llvm.amdgcn.workitem.id.x()
146  %gep0 = getelementptr half, half addrspace(1)* %aptr, i32 %tid
147  %out.gep = getelementptr half, half addrspace(1)* %out, i32 %tid
148  %a = load half, half addrspace(1)* %gep0
149  %fneg.a = fsub half -0.0, %a
150  %max = call half @llvm.maxnum.f16(half %fneg.a, half 0.0)
151  %med = call half @llvm.minnum.f16(half %max, half 1.0)
152
153  store half %med, half addrspace(1)* %out.gep
154  ret void
155}
156
157; GCN-LABEL: {{^}}v_clamp_negabs_f16:
158; GCN: {{buffer|flat|global}}_load_ushort [[A:v[0-9]+]]
159; GFX89: v_max_f16_e64 v{{[0-9]+}}, -|[[A]]|, -|[[A]]| clamp{{$}}
160
161; SI: v_cvt_f32_f16_e64 [[CVT:v[0-9]+]], -|[[A]]| clamp{{$}}
162; SI: v_cvt_f16_f32_e32 v{{[0-9]+}}, [[CVT]]
163define amdgpu_kernel void @v_clamp_negabs_f16(half addrspace(1)* %out, half addrspace(1)* %aptr) #0 {
164  %tid = call i32 @llvm.amdgcn.workitem.id.x()
165  %gep0 = getelementptr half, half addrspace(1)* %aptr, i32 %tid
166  %out.gep = getelementptr half, half addrspace(1)* %out, i32 %tid
167  %a = load half, half addrspace(1)* %gep0
168  %fabs.a = call half @llvm.fabs.f16(half %a)
169  %fneg.fabs.a = fsub half -0.0, %fabs.a
170
171  %max = call half @llvm.maxnum.f16(half %fneg.fabs.a, half 0.0)
172  %med = call half @llvm.minnum.f16(half %max, half 1.0)
173
174  store half %med, half addrspace(1)* %out.gep
175  ret void
176}
177
178; GCN-LABEL: {{^}}v_clamp_f64:
179; GCN: {{buffer|flat|global}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]]
180; GCN: v_max_f64 v{{\[[0-9]+:[0-9]+\]}}, [[A]], [[A]] clamp{{$}}
181define amdgpu_kernel void @v_clamp_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #0 {
182  %tid = call i32 @llvm.amdgcn.workitem.id.x()
183  %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid
184  %out.gep = getelementptr double, double addrspace(1)* %out, i32 %tid
185  %a = load double, double addrspace(1)* %gep0
186  %max = call double @llvm.maxnum.f64(double %a, double 0.0)
187  %med = call double @llvm.minnum.f64(double %max, double 1.0)
188
189  store double %med, double addrspace(1)* %out.gep
190  ret void
191}
192
193; GCN-LABEL: {{^}}v_clamp_neg_f64:
194; GCN: {{buffer|flat|global}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]]
195; GCN: v_max_f64 v{{\[[0-9]+:[0-9]+\]}}, -[[A]], -[[A]] clamp{{$}}
196define amdgpu_kernel void @v_clamp_neg_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #0 {
197  %tid = call i32 @llvm.amdgcn.workitem.id.x()
198  %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid
199  %out.gep = getelementptr double, double addrspace(1)* %out, i32 %tid
200  %a = load double, double addrspace(1)* %gep0
201  %fneg.a = fsub double -0.0, %a
202  %max = call double @llvm.maxnum.f64(double %fneg.a, double 0.0)
203  %med = call double @llvm.minnum.f64(double %max, double 1.0)
204
205  store double %med, double addrspace(1)* %out.gep
206  ret void
207}
208
209; GCN-LABEL: {{^}}v_clamp_negabs_f64:
210; GCN: {{buffer|flat|global}}_load_dwordx2 [[A:v\[[0-9]+:[0-9]+\]]]
211; GCN: v_max_f64 v{{\[[0-9]+:[0-9]+\]}}, -|[[A]]|, -|[[A]]| clamp{{$}}
212define amdgpu_kernel void @v_clamp_negabs_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #0 {
213  %tid = call i32 @llvm.amdgcn.workitem.id.x()
214  %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid
215  %out.gep = getelementptr double, double addrspace(1)* %out, i32 %tid
216  %a = load double, double addrspace(1)* %gep0
217  %fabs.a = call double @llvm.fabs.f64(double %a)
218  %fneg.fabs.a = fsub double -0.0, %fabs.a
219
220  %max = call double @llvm.maxnum.f64(double %fneg.fabs.a, double 0.0)
221  %med = call double @llvm.minnum.f64(double %max, double 1.0)
222
223  store double %med, double addrspace(1)* %out.gep
224  ret void
225}
226
227; GCN-LABEL: {{^}}v_clamp_med3_aby_negzero_f32:
228; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
229; GCN: v_med3_f32
230define amdgpu_kernel void @v_clamp_med3_aby_negzero_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
231  %tid = call i32 @llvm.amdgcn.workitem.id.x()
232  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
233  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
234  %a = load float, float addrspace(1)* %gep0
235  %med = call float @llvm.amdgcn.fmed3.f32(float -0.0, float 1.0, float %a)
236  store float %med, float addrspace(1)* %out.gep
237  ret void
238}
239
240; GCN-LABEL: {{^}}v_clamp_med3_aby_f32:
241; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
242; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
243define amdgpu_kernel void @v_clamp_med3_aby_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
244  %tid = call i32 @llvm.amdgcn.workitem.id.x()
245  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
246  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
247  %a = load float, float addrspace(1)* %gep0
248  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %a)
249  store float %med, float addrspace(1)* %out.gep
250  ret void
251}
252
253; GCN-LABEL: {{^}}v_clamp_med3_bay_f32:
254; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
255; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
256define amdgpu_kernel void @v_clamp_med3_bay_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
257  %tid = call i32 @llvm.amdgcn.workitem.id.x()
258  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
259  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
260  %a = load float, float addrspace(1)* %gep0
261  %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float 0.0, float %a)
262  store float %med, float addrspace(1)* %out.gep
263  ret void
264}
265
266; GCN-LABEL: {{^}}v_clamp_med3_yab_f32:
267; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
268; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
269define amdgpu_kernel void @v_clamp_med3_yab_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
270  %tid = call i32 @llvm.amdgcn.workitem.id.x()
271  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
272  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
273  %a = load float, float addrspace(1)* %gep0
274  %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 0.0, float 1.0)
275  store float %med, float addrspace(1)* %out.gep
276  ret void
277}
278
279; GCN-LABEL: {{^}}v_clamp_med3_yba_f32:
280; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
281; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
282define amdgpu_kernel void @v_clamp_med3_yba_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
283  %tid = call i32 @llvm.amdgcn.workitem.id.x()
284  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
285  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
286  %a = load float, float addrspace(1)* %gep0
287  %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 1.0, float 0.0)
288  store float %med, float addrspace(1)* %out.gep
289  ret void
290}
291
292; GCN-LABEL: {{^}}v_clamp_med3_ayb_f32:
293; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
294; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
295define amdgpu_kernel void @v_clamp_med3_ayb_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
296  %tid = call i32 @llvm.amdgcn.workitem.id.x()
297  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
298  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
299  %a = load float, float addrspace(1)* %gep0
300  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %a, float 1.0)
301  store float %med, float addrspace(1)* %out.gep
302  ret void
303}
304
305; GCN-LABEL: {{^}}v_clamp_med3_bya_f32:
306; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
307; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
308define amdgpu_kernel void @v_clamp_med3_bya_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
309  %tid = call i32 @llvm.amdgcn.workitem.id.x()
310  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
311  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
312  %a = load float, float addrspace(1)* %gep0
313  %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %a, float 0.0)
314  store float %med, float addrspace(1)* %out.gep
315  ret void
316}
317
318; GCN-LABEL: {{^}}v_clamp_constants_to_one_f32:
319; GCN: v_mov_b32_e32 v{{[0-9]+}}, 1.0
320define amdgpu_kernel void @v_clamp_constants_to_one_f32(float addrspace(1)* %out) #0 {
321  %tid = call i32 @llvm.amdgcn.workitem.id.x()
322  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
323  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 4.0)
324  store float %med, float addrspace(1)* %out.gep
325  ret void
326}
327
328; GCN-LABEL: {{^}}v_clamp_constants_to_zero_f32:
329; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0{{$}}
330define amdgpu_kernel void @v_clamp_constants_to_zero_f32(float addrspace(1)* %out) #0 {
331  %tid = call i32 @llvm.amdgcn.workitem.id.x()
332  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
333  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float -4.0)
334  store float %med, float addrspace(1)* %out.gep
335  ret void
336}
337
338; GCN-LABEL: {{^}}v_clamp_constant_preserve_f32:
339; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0.5
340define amdgpu_kernel void @v_clamp_constant_preserve_f32(float addrspace(1)* %out) #0 {
341  %tid = call i32 @llvm.amdgcn.workitem.id.x()
342  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
343  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0.5)
344  store float %med, float addrspace(1)* %out.gep
345  ret void
346}
347
348; GCN-LABEL: {{^}}v_clamp_constant_preserve_denorm_f32:
349; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0x7fffff{{$}}
350define amdgpu_kernel void @v_clamp_constant_preserve_denorm_f32(float addrspace(1)* %out) #0 {
351  %tid = call i32 @llvm.amdgcn.workitem.id.x()
352  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
353  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float bitcast (i32 8388607 to float))
354  store float %med, float addrspace(1)* %out.gep
355  ret void
356}
357
358; GCN-LABEL: {{^}}v_clamp_constant_qnan_f32:
359; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0{{$}}
360define amdgpu_kernel void @v_clamp_constant_qnan_f32(float addrspace(1)* %out) #0 {
361  %tid = call i32 @llvm.amdgcn.workitem.id.x()
362  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
363  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0x7FF8000000000000)
364  store float %med, float addrspace(1)* %out.gep
365  ret void
366}
367
368; GCN-LABEL: {{^}}v_clamp_constant_snan_f32:
369; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0{{$}}
370define amdgpu_kernel void @v_clamp_constant_snan_f32(float addrspace(1)* %out) #0 {
371  %tid = call i32 @llvm.amdgcn.workitem.id.x()
372  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
373  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float bitcast (i32 2139095041 to float))
374  store float %med, float addrspace(1)* %out.gep
375  ret void
376}
377
378; ---------------------------------------------------------------------
379; Test non-default behaviors enabling snans and disabling dx10_clamp
380; ---------------------------------------------------------------------
381
382; GCN-LABEL: {{^}}v_clamp_f32_no_dx10_clamp:
383; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
384; GCN: v_add_f32_e32 [[ADD:v[0-9]+]], 0.5, [[A]]
385; GCN: v_med3_f32 v{{[0-9]+}}, [[ADD]], 0, 1.0
386define amdgpu_kernel void @v_clamp_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
387  %tid = call i32 @llvm.amdgcn.workitem.id.x()
388  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
389  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
390  %a = load float, float addrspace(1)* %gep0
391  %a.nnan = fadd nnan float %a, 0.5
392  %max = call float @llvm.maxnum.f32(float %a.nnan, float 0.0)
393  %med = call float @llvm.minnum.f32(float %max, float 1.0)
394
395  store float %med, float addrspace(1)* %out.gep
396  ret void
397}
398
399; GCN-LABEL: {{^}}v_clamp_f32_snan_dx10clamp:
400; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
401; GCN: v_add_f32_e64 [[ADD:v[0-9]+]], [[A]], 0.5 clamp{{$}}
402define amdgpu_kernel void @v_clamp_f32_snan_dx10clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #3 {
403  %tid = call i32 @llvm.amdgcn.workitem.id.x()
404  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
405  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
406  %a = load float, float addrspace(1)* %gep0
407  %add = fadd float %a, 0.5
408  %max = call float @llvm.maxnum.f32(float %add, float 0.0)
409  %med = call float @llvm.minnum.f32(float %max, float 1.0)
410
411  store float %med, float addrspace(1)* %out.gep
412  ret void
413}
414
415; GCN-LABEL: {{^}}v_clamp_f32_snan_no_dx10clamp:
416; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
417; GFX678: v_mul_f32_e32 [[QUIET_A:v[0-9]+]], 1.0, [[A]]
418; GFX9: v_max_f32_e32 [[QUIET_A:v[0-9]+]], [[A]], [[A]]
419; GCN: v_med3_f32 {{v[0-9]+}}, [[QUIET_A]], 0, 1.0
420define amdgpu_kernel void @v_clamp_f32_snan_no_dx10clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #4 {
421  %tid = call i32 @llvm.amdgcn.workitem.id.x()
422  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
423  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
424  %a = load float, float addrspace(1)* %gep0
425  %max = call float @llvm.maxnum.f32(float %a, float 0.0)
426  %med = call float @llvm.minnum.f32(float %max, float 1.0)
427
428  store float %med, float addrspace(1)* %out.gep
429  ret void
430}
431
432; GCN-LABEL: {{^}}v_clamp_f32_snan_no_dx10clamp_nnan_src:
433; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
434; GCN: v_add_f32_e32 [[ADD:v[0-9]+]], 1.0, [[A]]
435; GCN: v_med3_f32 v{{[0-9]+}}, [[ADD]], 0, 1.0
436define amdgpu_kernel void @v_clamp_f32_snan_no_dx10clamp_nnan_src(float addrspace(1)* %out, float addrspace(1)* %aptr) #4 {
437  %tid = call i32 @llvm.amdgcn.workitem.id.x()
438  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
439  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
440  %a = load float, float addrspace(1)* %gep0
441  %add  = fadd nnan float %a, 1.0
442  %max = call float @llvm.maxnum.f32(float %add, float 0.0)
443  %med = call float @llvm.minnum.f32(float %max, float 1.0)
444
445  store float %med, float addrspace(1)* %out.gep
446  ret void
447}
448
449; GCN-LABEL: {{^}}v_clamp_med3_aby_f32_no_dx10_clamp:
450; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
451; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
452define amdgpu_kernel void @v_clamp_med3_aby_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
453  %tid = call i32 @llvm.amdgcn.workitem.id.x()
454  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
455  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
456  %a = load float, float addrspace(1)* %gep0
457  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float %a)
458  store float %med, float addrspace(1)* %out.gep
459  ret void
460}
461
462; GCN-LABEL: {{^}}v_clamp_med3_bay_f32_no_dx10_clamp:
463; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
464; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
465define amdgpu_kernel void @v_clamp_med3_bay_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
466  %tid = call i32 @llvm.amdgcn.workitem.id.x()
467  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
468  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
469  %a = load float, float addrspace(1)* %gep0
470  %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float 0.0, float %a)
471  store float %med, float addrspace(1)* %out.gep
472  ret void
473}
474
475; GCN-LABEL: {{^}}v_clamp_med3_yab_f32_no_dx10_clamp:
476; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
477; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 0, 1.0
478define amdgpu_kernel void @v_clamp_med3_yab_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
479  %tid = call i32 @llvm.amdgcn.workitem.id.x()
480  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
481  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
482  %a = load float, float addrspace(1)* %gep0
483  %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 0.0, float 1.0)
484  store float %med, float addrspace(1)* %out.gep
485  ret void
486}
487
488; GCN-LABEL: {{^}}v_clamp_med3_yba_f32_no_dx10_clamp:
489; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
490; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 1.0, 0
491define amdgpu_kernel void @v_clamp_med3_yba_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
492  %tid = call i32 @llvm.amdgcn.workitem.id.x()
493  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
494  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
495  %a = load float, float addrspace(1)* %gep0
496  %med = call float @llvm.amdgcn.fmed3.f32(float %a, float 1.0, float 0.0)
497  store float %med, float addrspace(1)* %out.gep
498  ret void
499}
500
501; GCN-LABEL: {{^}}v_clamp_med3_ayb_f32_no_dx10_clamp:
502; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
503; GCN: v_med3_f32 v{{[0-9]+}}, 0, [[A]], 1.0
504define amdgpu_kernel void @v_clamp_med3_ayb_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
505  %tid = call i32 @llvm.amdgcn.workitem.id.x()
506  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
507  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
508  %a = load float, float addrspace(1)* %gep0
509  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %a, float 1.0)
510  store float %med, float addrspace(1)* %out.gep
511  ret void
512}
513
514; GCN-LABEL: {{^}}v_clamp_med3_bya_f32_no_dx10_clamp:
515; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
516; GCN: v_med3_f32 v{{[0-9]+}}, 1.0, [[A]], 0
517define amdgpu_kernel void @v_clamp_med3_bya_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
518  %tid = call i32 @llvm.amdgcn.workitem.id.x()
519  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
520  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
521  %a = load float, float addrspace(1)* %gep0
522  %med = call float @llvm.amdgcn.fmed3.f32(float 1.0, float %a, float 0.0)
523  store float %med, float addrspace(1)* %out.gep
524  ret void
525}
526
527; GCN-LABEL: {{^}}v_clamp_constant_qnan_f32_no_dx10_clamp:
528; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0x7fc00000
529define amdgpu_kernel void @v_clamp_constant_qnan_f32_no_dx10_clamp(float addrspace(1)* %out) #2 {
530  %tid = call i32 @llvm.amdgcn.workitem.id.x()
531  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
532  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float 0x7FF8000000000000)
533  store float %med, float addrspace(1)* %out.gep
534  ret void
535}
536
537; GCN-LABEL: {{^}}v_clamp_constant_snan_f32_no_dx10_clamp:
538; GCN: v_mov_b32_e32 v{{[0-9]+}}, 0x7f800001
539define amdgpu_kernel void @v_clamp_constant_snan_f32_no_dx10_clamp(float addrspace(1)* %out) #2 {
540  %tid = call i32 @llvm.amdgcn.workitem.id.x()
541  %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
542  %med = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 1.0, float bitcast (i32 2139095041 to float))
543  store float %med, float addrspace(1)* %out.gep
544  ret void
545}
546
547; GCN-LABEL: {{^}}v_clamp_v2f16:
548; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
549; GFX9-NOT: [[A]]
550; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] clamp{{$}}
551define amdgpu_kernel void @v_clamp_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
552  %tid = call i32 @llvm.amdgcn.workitem.id.x()
553  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
554  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
555  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
556  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> zeroinitializer)
557  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
558
559  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
560  ret void
561}
562
563; GCN-LABEL: {{^}}v_clamp_v2f16_undef_elt:
564; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
565; GFX9-NOT: [[A]]
566; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] clamp{{$}}
567define amdgpu_kernel void @v_clamp_v2f16_undef_elt(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
568  %tid = call i32 @llvm.amdgcn.workitem.id.x()
569  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
570  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
571  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
572  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half undef, half 0.0>)
573  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half undef>)
574
575  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
576  ret void
577}
578
579; GCN-LABEL: {{^}}v_clamp_v2f16_not_zero:
580; GFX9: v_pk_max_f16
581; GFX9: v_pk_min_f16
582define amdgpu_kernel void @v_clamp_v2f16_not_zero(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
583  %tid = call i32 @llvm.amdgcn.workitem.id.x()
584  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
585  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
586  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
587  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half 2.0, half 0.0>)
588  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
589
590  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
591  ret void
592}
593
594; GCN-LABEL: {{^}}v_clamp_v2f16_not_one:
595; GFX9: v_pk_max_f16
596; GFX9: v_pk_min_f16
597define amdgpu_kernel void @v_clamp_v2f16_not_one(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
598  %tid = call i32 @llvm.amdgcn.workitem.id.x()
599  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
600  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
601  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
602  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half 0.0, half 0.0>)
603  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 0.0, half 1.0>)
604
605  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
606  ret void
607}
608
609; GCN-LABEL: {{^}}v_clamp_neg_v2f16:
610; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
611; GFX9-NOT: [[A]]
612; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] neg_lo:[1,1] neg_hi:[1,1] clamp{{$}}
613define amdgpu_kernel void @v_clamp_neg_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
614  %tid = call i32 @llvm.amdgcn.workitem.id.x()
615  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
616  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
617  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
618  %fneg.a = fsub <2 x half> <half -0.0, half -0.0>, %a
619  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %fneg.a, <2 x half> zeroinitializer)
620  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
621
622  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
623  ret void
624}
625
626; GCN-LABEL: {{^}}v_clamp_negabs_v2f16:
627; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
628; GFX9: v_and_b32_e32 [[ABS:v[0-9]+]], 0x7fff7fff, [[A]]
629; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[ABS]], [[ABS]] neg_lo:[1,1] neg_hi:[1,1] clamp{{$}}
630define amdgpu_kernel void @v_clamp_negabs_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
631  %tid = call i32 @llvm.amdgcn.workitem.id.x()
632  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
633  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
634  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
635  %fabs.a = call <2 x half> @llvm.fabs.v2f16(<2 x half> %a)
636  %fneg.fabs.a = fsub <2 x half> <half -0.0, half -0.0>, %fabs.a
637
638  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %fneg.fabs.a, <2 x half> zeroinitializer)
639  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
640
641  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
642  ret void
643}
644
645; GCN-LABEL: {{^}}v_clamp_neglo_v2f16:
646; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
647; GFX9-NOT: [[A]]
648; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] neg_lo:[1,1] clamp{{$}}
649define amdgpu_kernel void @v_clamp_neglo_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
650  %tid = call i32 @llvm.amdgcn.workitem.id.x()
651  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
652  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
653  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
654  %lo = extractelement <2 x half> %a, i32 0
655  %neg.lo = fsub half -0.0, %lo
656  %neg.lo.vec = insertelement <2 x half> %a, half %neg.lo, i32 0
657  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %neg.lo.vec, <2 x half> zeroinitializer)
658  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
659
660  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
661  ret void
662}
663
664; GCN-LABEL: {{^}}v_clamp_neghi_v2f16:
665; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
666; GFX9-NOT: [[A]]
667; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] neg_hi:[1,1] clamp{{$}}
668define amdgpu_kernel void @v_clamp_neghi_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
669  %tid = call i32 @llvm.amdgcn.workitem.id.x()
670  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
671  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
672  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
673  %hi = extractelement <2 x half> %a, i32 1
674  %neg.hi = fsub half -0.0, %hi
675  %neg.hi.vec = insertelement <2 x half> %a, half %neg.hi, i32 1
676  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %neg.hi.vec, <2 x half> zeroinitializer)
677  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
678
679  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
680  ret void
681}
682
683; GCN-LABEL: {{^}}v_clamp_v2f16_shuffle:
684; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
685; GFX9-NOT: [[A]]
686; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] op_sel:[1,1] op_sel_hi:[0,0] clamp{{$}}
687define amdgpu_kernel void @v_clamp_v2f16_shuffle(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
688  %tid = call i32 @llvm.amdgcn.workitem.id.x()
689  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
690  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
691  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
692  %shuf = shufflevector <2 x half> %a, <2 x half> undef, <2 x i32> <i32 1, i32 0>
693  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %shuf, <2 x half> zeroinitializer)
694  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half 1.0>)
695
696  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
697  ret void
698}
699
700; GCN-LABEL: {{^}}v_clamp_v2f16_undef_limit_elts0:
701; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
702; GFX9-NOT: [[A]]
703; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] clamp{{$}}
704define amdgpu_kernel void @v_clamp_v2f16_undef_limit_elts0(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
705  %tid = call i32 @llvm.amdgcn.workitem.id.x()
706  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
707  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
708  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
709  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half 0.0, half undef>)
710  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half undef, half 1.0>)
711
712  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
713  ret void
714}
715
716; GCN-LABEL: {{^}}v_clamp_v2f16_undef_limit_elts1:
717; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
718; GFX9-NOT: [[A]]
719; GFX9: v_pk_max_f16 [[CLAMP:v[0-9]+]], [[A]], [[A]] clamp{{$}}
720define amdgpu_kernel void @v_clamp_v2f16_undef_limit_elts1(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %aptr) #0 {
721  %tid = call i32 @llvm.amdgcn.workitem.id.x()
722  %gep0 = getelementptr <2 x half>, <2 x half> addrspace(1)* %aptr, i32 %tid
723  %out.gep = getelementptr <2 x half>, <2 x half> addrspace(1)* %out, i32 %tid
724  %a = load <2 x half>, <2 x half> addrspace(1)* %gep0
725  %max = call <2 x half> @llvm.maxnum.v2f16(<2 x half> %a, <2 x half> <half undef, half 0.0>)
726  %med = call <2 x half> @llvm.minnum.v2f16(<2 x half> %max, <2 x half> <half 1.0, half undef>)
727
728  store <2 x half> %med, <2 x half> addrspace(1)* %out.gep
729  ret void
730}
731
732; GCN-LABEL: {{^}}v_clamp_diff_source_f32:
733; GCN: v_add_f32_e32 [[A:v[0-9]+]]
734; GCN: v_add_f32_e32 [[B:v[0-9]+]]
735; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[B]] clamp{{$}}
736define amdgpu_kernel void @v_clamp_diff_source_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0
737{
738  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 0
739  %gep1 = getelementptr float, float addrspace(1)* %aptr, i32 1
740  %gep2 = getelementptr float, float addrspace(1)* %aptr, i32 2
741  %l0 = load float, float addrspace(1)* %gep0
742  %l1 = load float, float addrspace(1)* %gep1
743  %l2 = load float, float addrspace(1)* %gep2
744  %a = fadd nsz float %l0, %l1
745  %b = fadd nsz float %l0, %l2
746  %res = call nsz float @llvm.maxnum.f32(float %a, float %b)
747  %max = call nsz float @llvm.maxnum.f32(float %res, float 0.0)
748  %min = call nsz float @llvm.minnum.f32(float %max, float 1.0)
749  %out.gep = getelementptr float, float addrspace(1)* %out, i32 3
750  store float %min, float addrspace(1)* %out.gep
751  ret void
752}
753
754declare i32 @llvm.amdgcn.workitem.id.x() #1
755declare float @llvm.fabs.f32(float) #1
756declare float @llvm.minnum.f32(float, float) #1
757declare float @llvm.maxnum.f32(float, float) #1
758declare float @llvm.amdgcn.fmed3.f32(float, float, float) #1
759declare double @llvm.fabs.f64(double) #1
760declare double @llvm.minnum.f64(double, double) #1
761declare double @llvm.maxnum.f64(double, double) #1
762declare half @llvm.fabs.f16(half) #1
763declare half @llvm.minnum.f16(half, half) #1
764declare half @llvm.maxnum.f16(half, half) #1
765declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #1
766declare <2 x half> @llvm.minnum.v2f16(<2 x half>, <2 x half>) #1
767declare <2 x half> @llvm.maxnum.v2f16(<2 x half>, <2 x half>) #1
768
769attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign,preserve-sign" }
770attributes #1 = { nounwind readnone }
771attributes #2 = { nounwind "amdgpu-dx10-clamp"="false" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-nans-fp-math"="false" }
772attributes #3 = { nounwind "amdgpu-dx10-clamp"="true" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-nans-fp-math"="false" }
773attributes #4 = { nounwind "amdgpu-dx10-clamp"="false" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-nans-fp-math"="false" }
774