1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -global-isel -march=amdgcn -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=SI %s
3; RUN: llc -global-isel -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=VI %s
4; RUN: llc -global-isel -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GFX9 %s
5
6define amdgpu_kernel void @v_test_global_nnans_med3_f32_pat0_srcmod0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) #2 {
7; SI-LABEL: v_test_global_nnans_med3_f32_pat0_srcmod0:
8; SI:       ; %bb.0:
9; SI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x9
10; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
11; SI-NEXT:    v_mov_b32_e32 v1, 0
12; SI-NEXT:    s_mov_b32 s10, 0
13; SI-NEXT:    s_mov_b32 s11, 0xf000
14; SI-NEXT:    s_waitcnt lgkmcnt(0)
15; SI-NEXT:    s_mov_b64 s[8:9], s[2:3]
16; SI-NEXT:    buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
17; SI-NEXT:    s_waitcnt vmcnt(0)
18; SI-NEXT:    s_mov_b64 s[8:9], s[4:5]
19; SI-NEXT:    buffer_load_dword v3, v[0:1], s[8:11], 0 addr64 glc
20; SI-NEXT:    s_waitcnt vmcnt(0)
21; SI-NEXT:    s_mov_b64 s[8:9], s[6:7]
22; SI-NEXT:    buffer_load_dword v4, v[0:1], s[8:11], 0 addr64 glc
23; SI-NEXT:    s_waitcnt vmcnt(0)
24; SI-NEXT:    v_sub_f32_e32 v2, 0x80000000, v2
25; SI-NEXT:    v_med3_f32 v2, v2, v3, v4
26; SI-NEXT:    s_mov_b64 s[2:3], s[10:11]
27; SI-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
28; SI-NEXT:    s_endpgm
29;
30; VI-LABEL: v_test_global_nnans_med3_f32_pat0_srcmod0:
31; VI:       ; %bb.0:
32; VI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
33; VI-NEXT:    v_lshlrev_b32_e32 v8, 2, v0
34; VI-NEXT:    s_waitcnt lgkmcnt(0)
35; VI-NEXT:    v_mov_b32_e32 v0, s2
36; VI-NEXT:    v_mov_b32_e32 v1, s3
37; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v8
38; VI-NEXT:    v_mov_b32_e32 v2, s4
39; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
40; VI-NEXT:    v_mov_b32_e32 v3, s5
41; VI-NEXT:    v_add_u32_e32 v2, vcc, v2, v8
42; VI-NEXT:    v_mov_b32_e32 v4, s6
43; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
44; VI-NEXT:    v_mov_b32_e32 v5, s7
45; VI-NEXT:    v_add_u32_e32 v4, vcc, v4, v8
46; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v5, vcc
47; VI-NEXT:    flat_load_dword v0, v[0:1] glc
48; VI-NEXT:    s_waitcnt vmcnt(0)
49; VI-NEXT:    flat_load_dword v1, v[2:3] glc
50; VI-NEXT:    s_waitcnt vmcnt(0)
51; VI-NEXT:    flat_load_dword v2, v[4:5] glc
52; VI-NEXT:    s_waitcnt vmcnt(0)
53; VI-NEXT:    v_mov_b32_e32 v7, s1
54; VI-NEXT:    v_mov_b32_e32 v6, s0
55; VI-NEXT:    v_add_u32_e32 v6, vcc, v6, v8
56; VI-NEXT:    v_addc_u32_e32 v7, vcc, 0, v7, vcc
57; VI-NEXT:    v_sub_f32_e32 v0, 0x80000000, v0
58; VI-NEXT:    v_med3_f32 v0, v0, v1, v2
59; VI-NEXT:    flat_store_dword v[6:7], v0
60; VI-NEXT:    s_endpgm
61;
62; GFX9-LABEL: v_test_global_nnans_med3_f32_pat0_srcmod0:
63; GFX9:       ; %bb.0:
64; GFX9-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
65; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
66; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
67; GFX9-NEXT:    global_load_dword v1, v0, s[2:3] glc
68; GFX9-NEXT:    s_waitcnt vmcnt(0)
69; GFX9-NEXT:    global_load_dword v2, v0, s[4:5] glc
70; GFX9-NEXT:    s_waitcnt vmcnt(0)
71; GFX9-NEXT:    global_load_dword v3, v0, s[6:7] glc
72; GFX9-NEXT:    s_waitcnt vmcnt(0)
73; GFX9-NEXT:    v_sub_f32_e32 v1, 0x80000000, v1
74; GFX9-NEXT:    v_med3_f32 v1, v1, v2, v3
75; GFX9-NEXT:    global_store_dword v0, v1, s[0:1]
76; GFX9-NEXT:    s_endpgm
77  %tid = call i32 @llvm.amdgcn.workitem.id.x()
78  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
79  %gep1 = getelementptr float, float addrspace(1)* %bptr, i32 %tid
80  %gep2 = getelementptr float, float addrspace(1)* %cptr, i32 %tid
81  %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
82  %a = load volatile float, float addrspace(1)* %gep0
83  %b = load volatile float, float addrspace(1)* %gep1
84  %c = load volatile float, float addrspace(1)* %gep2
85  %a.fneg = fsub float -0.0, %a
86  %tmp0 = call float @llvm.minnum.f32(float %a.fneg, float %b)
87  %tmp1 = call float @llvm.maxnum.f32(float %a.fneg, float %b)
88  %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c)
89  %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
90  store float %med3, float addrspace(1)* %outgep
91  ret void
92}
93
94define amdgpu_kernel void @v_test_no_global_nnans_med3_f32_pat0_srcmod0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) #1 {
95; SI-LABEL: v_test_no_global_nnans_med3_f32_pat0_srcmod0:
96; SI:       ; %bb.0:
97; SI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x9
98; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
99; SI-NEXT:    v_mov_b32_e32 v1, 0
100; SI-NEXT:    s_mov_b32 s10, 0
101; SI-NEXT:    s_mov_b32 s11, 0xf000
102; SI-NEXT:    s_waitcnt lgkmcnt(0)
103; SI-NEXT:    s_mov_b64 s[8:9], s[2:3]
104; SI-NEXT:    buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
105; SI-NEXT:    s_waitcnt vmcnt(0)
106; SI-NEXT:    s_mov_b64 s[8:9], s[4:5]
107; SI-NEXT:    buffer_load_dword v3, v[0:1], s[8:11], 0 addr64 glc
108; SI-NEXT:    s_waitcnt vmcnt(0)
109; SI-NEXT:    s_mov_b64 s[8:9], s[6:7]
110; SI-NEXT:    buffer_load_dword v4, v[0:1], s[8:11], 0 addr64 glc
111; SI-NEXT:    s_waitcnt vmcnt(0)
112; SI-NEXT:    v_sub_f32_e32 v2, 0x80000000, v2
113; SI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
114; SI-NEXT:    v_mul_f32_e32 v3, 1.0, v3
115; SI-NEXT:    v_min_f32_e32 v5, v2, v3
116; SI-NEXT:    v_max_f32_e32 v2, v2, v3
117; SI-NEXT:    v_mul_f32_e32 v3, 1.0, v4
118; SI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
119; SI-NEXT:    v_min_f32_e32 v2, v2, v3
120; SI-NEXT:    v_mul_f32_e32 v3, 1.0, v5
121; SI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
122; SI-NEXT:    v_max_f32_e32 v2, v3, v2
123; SI-NEXT:    s_mov_b64 s[2:3], s[10:11]
124; SI-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
125; SI-NEXT:    s_endpgm
126;
127; VI-LABEL: v_test_no_global_nnans_med3_f32_pat0_srcmod0:
128; VI:       ; %bb.0:
129; VI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
130; VI-NEXT:    v_lshlrev_b32_e32 v6, 2, v0
131; VI-NEXT:    s_waitcnt lgkmcnt(0)
132; VI-NEXT:    v_mov_b32_e32 v0, s2
133; VI-NEXT:    v_mov_b32_e32 v1, s3
134; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
135; VI-NEXT:    v_mov_b32_e32 v2, s4
136; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
137; VI-NEXT:    v_mov_b32_e32 v3, s5
138; VI-NEXT:    v_add_u32_e32 v2, vcc, v2, v6
139; VI-NEXT:    v_mov_b32_e32 v4, s6
140; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
141; VI-NEXT:    v_mov_b32_e32 v5, s7
142; VI-NEXT:    v_add_u32_e32 v4, vcc, v4, v6
143; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v5, vcc
144; VI-NEXT:    flat_load_dword v7, v[0:1] glc
145; VI-NEXT:    s_waitcnt vmcnt(0)
146; VI-NEXT:    flat_load_dword v2, v[2:3] glc
147; VI-NEXT:    s_waitcnt vmcnt(0)
148; VI-NEXT:    flat_load_dword v3, v[4:5] glc
149; VI-NEXT:    s_waitcnt vmcnt(0)
150; VI-NEXT:    v_mov_b32_e32 v0, s0
151; VI-NEXT:    v_mov_b32_e32 v1, s1
152; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
153; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
154; VI-NEXT:    v_sub_f32_e32 v4, 0x80000000, v7
155; VI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
156; VI-NEXT:    v_mul_f32_e32 v4, 1.0, v4
157; VI-NEXT:    v_min_f32_e32 v5, v4, v2
158; VI-NEXT:    v_max_f32_e32 v2, v4, v2
159; VI-NEXT:    v_mul_f32_e32 v3, 1.0, v3
160; VI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
161; VI-NEXT:    v_min_f32_e32 v2, v2, v3
162; VI-NEXT:    v_mul_f32_e32 v3, 1.0, v5
163; VI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
164; VI-NEXT:    v_max_f32_e32 v2, v3, v2
165; VI-NEXT:    flat_store_dword v[0:1], v2
166; VI-NEXT:    s_endpgm
167;
168; GFX9-LABEL: v_test_no_global_nnans_med3_f32_pat0_srcmod0:
169; GFX9:       ; %bb.0:
170; GFX9-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
171; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
172; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
173; GFX9-NEXT:    global_load_dword v1, v0, s[2:3] glc
174; GFX9-NEXT:    s_waitcnt vmcnt(0)
175; GFX9-NEXT:    global_load_dword v2, v0, s[4:5] glc
176; GFX9-NEXT:    s_waitcnt vmcnt(0)
177; GFX9-NEXT:    global_load_dword v3, v0, s[6:7] glc
178; GFX9-NEXT:    s_waitcnt vmcnt(0)
179; GFX9-NEXT:    v_sub_f32_e32 v1, 0x80000000, v1
180; GFX9-NEXT:    v_max_f32_e32 v2, v2, v2
181; GFX9-NEXT:    v_max_f32_e32 v1, v1, v1
182; GFX9-NEXT:    v_min_f32_e32 v4, v1, v2
183; GFX9-NEXT:    v_max_f32_e32 v1, v1, v2
184; GFX9-NEXT:    v_max_f32_e32 v3, v3, v3
185; GFX9-NEXT:    v_max_f32_e32 v1, v1, v1
186; GFX9-NEXT:    v_min_f32_e32 v1, v1, v3
187; GFX9-NEXT:    v_max_f32_e32 v2, v4, v4
188; GFX9-NEXT:    v_max_f32_e32 v1, v1, v1
189; GFX9-NEXT:    v_max_f32_e32 v1, v2, v1
190; GFX9-NEXT:    global_store_dword v0, v1, s[0:1]
191; GFX9-NEXT:    s_endpgm
192  %tid = call i32 @llvm.amdgcn.workitem.id.x()
193  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
194  %gep1 = getelementptr float, float addrspace(1)* %bptr, i32 %tid
195  %gep2 = getelementptr float, float addrspace(1)* %cptr, i32 %tid
196  %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
197  %a = load volatile float, float addrspace(1)* %gep0
198  %b = load volatile float, float addrspace(1)* %gep1
199  %c = load volatile float, float addrspace(1)* %gep2
200  %a.fneg = fsub float -0.0, %a
201  %tmp0 = call float @llvm.minnum.f32(float %a.fneg, float %b)
202  %tmp1 = call float @llvm.maxnum.f32(float %a.fneg, float %b)
203  %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c)
204  %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
205  store float %med3, float addrspace(1)* %outgep
206  ret void
207}
208
209define amdgpu_kernel void @v_test_global_nnans_med3_f32_pat0_srcmod012(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) #2 {
210; SI-LABEL: v_test_global_nnans_med3_f32_pat0_srcmod012:
211; SI:       ; %bb.0:
212; SI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x9
213; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
214; SI-NEXT:    v_mov_b32_e32 v1, 0
215; SI-NEXT:    s_mov_b32 s10, 0
216; SI-NEXT:    s_mov_b32 s11, 0xf000
217; SI-NEXT:    s_waitcnt lgkmcnt(0)
218; SI-NEXT:    s_mov_b64 s[8:9], s[2:3]
219; SI-NEXT:    buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
220; SI-NEXT:    s_waitcnt vmcnt(0)
221; SI-NEXT:    s_mov_b64 s[8:9], s[4:5]
222; SI-NEXT:    buffer_load_dword v3, v[0:1], s[8:11], 0 addr64 glc
223; SI-NEXT:    s_waitcnt vmcnt(0)
224; SI-NEXT:    s_mov_b64 s[8:9], s[6:7]
225; SI-NEXT:    buffer_load_dword v4, v[0:1], s[8:11], 0 addr64 glc
226; SI-NEXT:    s_waitcnt vmcnt(0)
227; SI-NEXT:    s_mov_b32 s2, 0x80000000
228; SI-NEXT:    v_sub_f32_e32 v2, s2, v2
229; SI-NEXT:    v_sub_f32_e64 v4, s2, |v4|
230; SI-NEXT:    v_med3_f32 v2, v2, |v3|, v4
231; SI-NEXT:    s_mov_b64 s[2:3], s[10:11]
232; SI-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
233; SI-NEXT:    s_endpgm
234;
235; VI-LABEL: v_test_global_nnans_med3_f32_pat0_srcmod012:
236; VI:       ; %bb.0:
237; VI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
238; VI-NEXT:    v_lshlrev_b32_e32 v6, 2, v0
239; VI-NEXT:    s_waitcnt lgkmcnt(0)
240; VI-NEXT:    v_mov_b32_e32 v0, s2
241; VI-NEXT:    v_mov_b32_e32 v1, s3
242; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
243; VI-NEXT:    v_mov_b32_e32 v2, s4
244; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
245; VI-NEXT:    v_mov_b32_e32 v3, s5
246; VI-NEXT:    v_add_u32_e32 v2, vcc, v2, v6
247; VI-NEXT:    v_mov_b32_e32 v4, s6
248; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
249; VI-NEXT:    v_mov_b32_e32 v5, s7
250; VI-NEXT:    v_add_u32_e32 v4, vcc, v4, v6
251; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v5, vcc
252; VI-NEXT:    flat_load_dword v7, v[0:1] glc
253; VI-NEXT:    s_waitcnt vmcnt(0)
254; VI-NEXT:    flat_load_dword v2, v[2:3] glc
255; VI-NEXT:    s_waitcnt vmcnt(0)
256; VI-NEXT:    flat_load_dword v3, v[4:5] glc
257; VI-NEXT:    s_waitcnt vmcnt(0)
258; VI-NEXT:    v_mov_b32_e32 v0, s0
259; VI-NEXT:    s_mov_b32 s2, 0x80000000
260; VI-NEXT:    v_mov_b32_e32 v1, s1
261; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
262; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
263; VI-NEXT:    v_sub_f32_e32 v4, s2, v7
264; VI-NEXT:    v_sub_f32_e64 v3, s2, |v3|
265; VI-NEXT:    v_med3_f32 v2, v4, |v2|, v3
266; VI-NEXT:    flat_store_dword v[0:1], v2
267; VI-NEXT:    s_endpgm
268;
269; GFX9-LABEL: v_test_global_nnans_med3_f32_pat0_srcmod012:
270; GFX9:       ; %bb.0:
271; GFX9-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
272; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
273; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
274; GFX9-NEXT:    global_load_dword v1, v0, s[2:3] glc
275; GFX9-NEXT:    s_waitcnt vmcnt(0)
276; GFX9-NEXT:    global_load_dword v2, v0, s[4:5] glc
277; GFX9-NEXT:    s_waitcnt vmcnt(0)
278; GFX9-NEXT:    global_load_dword v3, v0, s[6:7] glc
279; GFX9-NEXT:    s_waitcnt vmcnt(0)
280; GFX9-NEXT:    s_mov_b32 s2, 0x80000000
281; GFX9-NEXT:    v_sub_f32_e32 v1, s2, v1
282; GFX9-NEXT:    v_sub_f32_e64 v3, s2, |v3|
283; GFX9-NEXT:    v_med3_f32 v1, v1, |v2|, v3
284; GFX9-NEXT:    global_store_dword v0, v1, s[0:1]
285; GFX9-NEXT:    s_endpgm
286  %tid = call i32 @llvm.amdgcn.workitem.id.x()
287  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
288  %gep1 = getelementptr float, float addrspace(1)* %bptr, i32 %tid
289  %gep2 = getelementptr float, float addrspace(1)* %cptr, i32 %tid
290  %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
291  %a = load volatile float, float addrspace(1)* %gep0
292  %b = load volatile float, float addrspace(1)* %gep1
293  %c = load volatile float, float addrspace(1)* %gep2
294
295  %a.fneg = fsub float -0.0, %a
296  %b.fabs = call float @llvm.fabs.f32(float %b)
297  %c.fabs = call float @llvm.fabs.f32(float %c)
298  %c.fabs.fneg = fsub float -0.0, %c.fabs
299
300  %tmp0 = call float @llvm.minnum.f32(float %a.fneg, float %b.fabs)
301  %tmp1 = call float @llvm.maxnum.f32(float %a.fneg, float %b.fabs)
302  %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c.fabs.fneg)
303  %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
304
305  store float %med3, float addrspace(1)* %outgep
306  ret void
307}
308
309define amdgpu_kernel void @v_test_global_nnans_med3_f32_pat0_negabs012(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) #2 {
310; SI-LABEL: v_test_global_nnans_med3_f32_pat0_negabs012:
311; SI:       ; %bb.0:
312; SI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x9
313; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
314; SI-NEXT:    v_mov_b32_e32 v1, 0
315; SI-NEXT:    s_mov_b32 s10, 0
316; SI-NEXT:    s_mov_b32 s11, 0xf000
317; SI-NEXT:    s_waitcnt lgkmcnt(0)
318; SI-NEXT:    s_mov_b64 s[8:9], s[2:3]
319; SI-NEXT:    buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
320; SI-NEXT:    s_waitcnt vmcnt(0)
321; SI-NEXT:    s_mov_b64 s[8:9], s[4:5]
322; SI-NEXT:    buffer_load_dword v3, v[0:1], s[8:11], 0 addr64 glc
323; SI-NEXT:    s_waitcnt vmcnt(0)
324; SI-NEXT:    s_mov_b64 s[8:9], s[6:7]
325; SI-NEXT:    buffer_load_dword v4, v[0:1], s[8:11], 0 addr64 glc
326; SI-NEXT:    s_waitcnt vmcnt(0)
327; SI-NEXT:    s_mov_b32 s2, 0x80000000
328; SI-NEXT:    v_sub_f32_e64 v2, s2, |v2|
329; SI-NEXT:    v_sub_f32_e64 v3, s2, |v3|
330; SI-NEXT:    v_sub_f32_e64 v4, s2, |v4|
331; SI-NEXT:    v_med3_f32 v2, v2, v3, v4
332; SI-NEXT:    s_mov_b64 s[2:3], s[10:11]
333; SI-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
334; SI-NEXT:    s_endpgm
335;
336; VI-LABEL: v_test_global_nnans_med3_f32_pat0_negabs012:
337; VI:       ; %bb.0:
338; VI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
339; VI-NEXT:    v_lshlrev_b32_e32 v6, 2, v0
340; VI-NEXT:    s_waitcnt lgkmcnt(0)
341; VI-NEXT:    v_mov_b32_e32 v0, s2
342; VI-NEXT:    v_mov_b32_e32 v1, s3
343; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
344; VI-NEXT:    v_mov_b32_e32 v2, s4
345; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
346; VI-NEXT:    v_mov_b32_e32 v3, s5
347; VI-NEXT:    v_add_u32_e32 v2, vcc, v2, v6
348; VI-NEXT:    v_mov_b32_e32 v4, s6
349; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
350; VI-NEXT:    v_mov_b32_e32 v5, s7
351; VI-NEXT:    v_add_u32_e32 v4, vcc, v4, v6
352; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v5, vcc
353; VI-NEXT:    flat_load_dword v7, v[0:1] glc
354; VI-NEXT:    s_waitcnt vmcnt(0)
355; VI-NEXT:    flat_load_dword v2, v[2:3] glc
356; VI-NEXT:    s_waitcnt vmcnt(0)
357; VI-NEXT:    flat_load_dword v3, v[4:5] glc
358; VI-NEXT:    s_waitcnt vmcnt(0)
359; VI-NEXT:    s_mov_b32 s2, 0x80000000
360; VI-NEXT:    v_mov_b32_e32 v0, s0
361; VI-NEXT:    v_mov_b32_e32 v1, s1
362; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
363; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
364; VI-NEXT:    v_sub_f32_e64 v4, s2, |v7|
365; VI-NEXT:    v_sub_f32_e64 v2, s2, |v2|
366; VI-NEXT:    v_sub_f32_e64 v3, s2, |v3|
367; VI-NEXT:    v_med3_f32 v2, v4, v2, v3
368; VI-NEXT:    flat_store_dword v[0:1], v2
369; VI-NEXT:    s_endpgm
370;
371; GFX9-LABEL: v_test_global_nnans_med3_f32_pat0_negabs012:
372; GFX9:       ; %bb.0:
373; GFX9-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
374; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
375; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
376; GFX9-NEXT:    global_load_dword v1, v0, s[2:3] glc
377; GFX9-NEXT:    s_waitcnt vmcnt(0)
378; GFX9-NEXT:    global_load_dword v2, v0, s[4:5] glc
379; GFX9-NEXT:    s_waitcnt vmcnt(0)
380; GFX9-NEXT:    global_load_dword v3, v0, s[6:7] glc
381; GFX9-NEXT:    s_waitcnt vmcnt(0)
382; GFX9-NEXT:    s_mov_b32 s2, 0x80000000
383; GFX9-NEXT:    v_sub_f32_e64 v1, s2, |v1|
384; GFX9-NEXT:    v_sub_f32_e64 v2, s2, |v2|
385; GFX9-NEXT:    v_sub_f32_e64 v3, s2, |v3|
386; GFX9-NEXT:    v_med3_f32 v1, v1, v2, v3
387; GFX9-NEXT:    global_store_dword v0, v1, s[0:1]
388; GFX9-NEXT:    s_endpgm
389  %tid = call i32 @llvm.amdgcn.workitem.id.x()
390  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
391  %gep1 = getelementptr float, float addrspace(1)* %bptr, i32 %tid
392  %gep2 = getelementptr float, float addrspace(1)* %cptr, i32 %tid
393  %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
394  %a = load volatile float, float addrspace(1)* %gep0
395  %b = load volatile float, float addrspace(1)* %gep1
396  %c = load volatile float, float addrspace(1)* %gep2
397
398  %a.fabs = call float @llvm.fabs.f32(float %a)
399  %a.fabs.fneg = fsub float -0.0, %a.fabs
400  %b.fabs = call float @llvm.fabs.f32(float %b)
401  %b.fabs.fneg = fsub float -0.0, %b.fabs
402  %c.fabs = call float @llvm.fabs.f32(float %c)
403  %c.fabs.fneg = fsub float -0.0, %c.fabs
404
405  %tmp0 = call float @llvm.minnum.f32(float %a.fabs.fneg, float %b.fabs.fneg)
406  %tmp1 = call float @llvm.maxnum.f32(float %a.fabs.fneg, float %b.fabs.fneg)
407  %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c.fabs.fneg)
408  %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
409
410  store float %med3, float addrspace(1)* %outgep
411  ret void
412}
413
414define amdgpu_kernel void @v_nnan_inputs_med3_f32_pat0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) #1 {
415; SI-LABEL: v_nnan_inputs_med3_f32_pat0:
416; SI:       ; %bb.0:
417; SI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x9
418; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
419; SI-NEXT:    v_mov_b32_e32 v1, 0
420; SI-NEXT:    s_mov_b32 s10, 0
421; SI-NEXT:    s_mov_b32 s11, 0xf000
422; SI-NEXT:    s_waitcnt lgkmcnt(0)
423; SI-NEXT:    s_mov_b64 s[8:9], s[2:3]
424; SI-NEXT:    buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
425; SI-NEXT:    s_waitcnt vmcnt(0)
426; SI-NEXT:    s_mov_b64 s[8:9], s[4:5]
427; SI-NEXT:    buffer_load_dword v3, v[0:1], s[8:11], 0 addr64 glc
428; SI-NEXT:    s_waitcnt vmcnt(0)
429; SI-NEXT:    s_mov_b64 s[8:9], s[6:7]
430; SI-NEXT:    buffer_load_dword v4, v[0:1], s[8:11], 0 addr64 glc
431; SI-NEXT:    s_waitcnt vmcnt(0)
432; SI-NEXT:    v_add_f32_e32 v2, 1.0, v2
433; SI-NEXT:    v_add_f32_e32 v3, 2.0, v3
434; SI-NEXT:    v_add_f32_e32 v4, 4.0, v4
435; SI-NEXT:    v_med3_f32 v2, v2, v3, v4
436; SI-NEXT:    s_mov_b64 s[2:3], s[10:11]
437; SI-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
438; SI-NEXT:    s_endpgm
439;
440; VI-LABEL: v_nnan_inputs_med3_f32_pat0:
441; VI:       ; %bb.0:
442; VI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
443; VI-NEXT:    v_lshlrev_b32_e32 v6, 2, v0
444; VI-NEXT:    s_waitcnt lgkmcnt(0)
445; VI-NEXT:    v_mov_b32_e32 v0, s2
446; VI-NEXT:    v_mov_b32_e32 v1, s3
447; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
448; VI-NEXT:    v_mov_b32_e32 v2, s4
449; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
450; VI-NEXT:    v_mov_b32_e32 v3, s5
451; VI-NEXT:    v_add_u32_e32 v2, vcc, v2, v6
452; VI-NEXT:    v_mov_b32_e32 v4, s6
453; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
454; VI-NEXT:    v_mov_b32_e32 v5, s7
455; VI-NEXT:    v_add_u32_e32 v4, vcc, v4, v6
456; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v5, vcc
457; VI-NEXT:    flat_load_dword v7, v[0:1] glc
458; VI-NEXT:    s_waitcnt vmcnt(0)
459; VI-NEXT:    flat_load_dword v2, v[2:3] glc
460; VI-NEXT:    s_waitcnt vmcnt(0)
461; VI-NEXT:    flat_load_dword v3, v[4:5] glc
462; VI-NEXT:    s_waitcnt vmcnt(0)
463; VI-NEXT:    v_mov_b32_e32 v0, s0
464; VI-NEXT:    v_mov_b32_e32 v1, s1
465; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
466; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
467; VI-NEXT:    v_add_f32_e32 v4, 1.0, v7
468; VI-NEXT:    v_add_f32_e32 v2, 2.0, v2
469; VI-NEXT:    v_add_f32_e32 v3, 4.0, v3
470; VI-NEXT:    v_med3_f32 v2, v4, v2, v3
471; VI-NEXT:    flat_store_dword v[0:1], v2
472; VI-NEXT:    s_endpgm
473;
474; GFX9-LABEL: v_nnan_inputs_med3_f32_pat0:
475; GFX9:       ; %bb.0:
476; GFX9-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
477; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
478; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
479; GFX9-NEXT:    global_load_dword v1, v0, s[2:3] glc
480; GFX9-NEXT:    s_waitcnt vmcnt(0)
481; GFX9-NEXT:    global_load_dword v2, v0, s[4:5] glc
482; GFX9-NEXT:    s_waitcnt vmcnt(0)
483; GFX9-NEXT:    global_load_dword v3, v0, s[6:7] glc
484; GFX9-NEXT:    s_waitcnt vmcnt(0)
485; GFX9-NEXT:    v_add_f32_e32 v1, 1.0, v1
486; GFX9-NEXT:    v_add_f32_e32 v2, 2.0, v2
487; GFX9-NEXT:    v_add_f32_e32 v3, 4.0, v3
488; GFX9-NEXT:    v_med3_f32 v1, v1, v2, v3
489; GFX9-NEXT:    global_store_dword v0, v1, s[0:1]
490; GFX9-NEXT:    s_endpgm
491  %tid = call i32 @llvm.amdgcn.workitem.id.x()
492  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
493  %gep1 = getelementptr float, float addrspace(1)* %bptr, i32 %tid
494  %gep2 = getelementptr float, float addrspace(1)* %cptr, i32 %tid
495  %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
496  %a = load volatile float, float addrspace(1)* %gep0
497  %b = load volatile float, float addrspace(1)* %gep1
498  %c = load volatile float, float addrspace(1)* %gep2
499
500  %a.nnan = fadd nnan float %a, 1.0
501  %b.nnan = fadd nnan float %b, 2.0
502  %c.nnan = fadd nnan float %c, 4.0
503
504  %tmp0 = call float @llvm.minnum.f32(float %a.nnan, float %b.nnan)
505  %tmp1 = call float @llvm.maxnum.f32(float %a.nnan, float %b.nnan)
506  %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c.nnan)
507  %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
508  store float %med3, float addrspace(1)* %outgep
509  ret void
510}
511
512
513; ---------------------------------------------------------------------
514; Negative patterns
515; ---------------------------------------------------------------------
516
517define amdgpu_kernel void @v_test_safe_med3_f32_pat0_multi_use0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) #1 {
518; SI-LABEL: v_test_safe_med3_f32_pat0_multi_use0:
519; SI:       ; %bb.0:
520; SI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x9
521; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
522; SI-NEXT:    v_mov_b32_e32 v1, 0
523; SI-NEXT:    s_mov_b32 s10, 0
524; SI-NEXT:    s_mov_b32 s11, 0xf000
525; SI-NEXT:    s_waitcnt lgkmcnt(0)
526; SI-NEXT:    s_mov_b64 s[8:9], s[2:3]
527; SI-NEXT:    buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
528; SI-NEXT:    s_waitcnt vmcnt(0)
529; SI-NEXT:    s_mov_b64 s[8:9], s[4:5]
530; SI-NEXT:    buffer_load_dword v3, v[0:1], s[8:11], 0 addr64 glc
531; SI-NEXT:    s_waitcnt vmcnt(0)
532; SI-NEXT:    s_mov_b32 s2, -1
533; SI-NEXT:    s_mov_b32 s3, s11
534; SI-NEXT:    s_mov_b64 s[8:9], s[6:7]
535; SI-NEXT:    buffer_load_dword v4, v[0:1], s[8:11], 0 addr64 glc
536; SI-NEXT:    s_waitcnt vmcnt(0)
537; SI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
538; SI-NEXT:    v_mul_f32_e32 v3, 1.0, v3
539; SI-NEXT:    v_min_f32_e32 v5, v2, v3
540; SI-NEXT:    v_max_f32_e32 v2, v2, v3
541; SI-NEXT:    v_mul_f32_e32 v3, 1.0, v4
542; SI-NEXT:    buffer_store_dword v5, off, s[0:3], 0
543; SI-NEXT:    s_waitcnt vmcnt(0)
544; SI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
545; SI-NEXT:    v_min_f32_e32 v2, v2, v3
546; SI-NEXT:    v_mul_f32_e32 v3, 1.0, v5
547; SI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
548; SI-NEXT:    v_max_f32_e32 v2, v3, v2
549; SI-NEXT:    s_mov_b64 s[2:3], s[10:11]
550; SI-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
551; SI-NEXT:    s_endpgm
552;
553; VI-LABEL: v_test_safe_med3_f32_pat0_multi_use0:
554; VI:       ; %bb.0:
555; VI-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
556; VI-NEXT:    v_lshlrev_b32_e32 v6, 2, v0
557; VI-NEXT:    s_waitcnt lgkmcnt(0)
558; VI-NEXT:    v_mov_b32_e32 v0, s2
559; VI-NEXT:    v_mov_b32_e32 v1, s3
560; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
561; VI-NEXT:    v_mov_b32_e32 v2, s4
562; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
563; VI-NEXT:    v_mov_b32_e32 v3, s5
564; VI-NEXT:    v_add_u32_e32 v2, vcc, v2, v6
565; VI-NEXT:    v_mov_b32_e32 v4, s6
566; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
567; VI-NEXT:    v_mov_b32_e32 v5, s7
568; VI-NEXT:    v_add_u32_e32 v4, vcc, v4, v6
569; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v5, vcc
570; VI-NEXT:    flat_load_dword v7, v[0:1] glc
571; VI-NEXT:    s_waitcnt vmcnt(0)
572; VI-NEXT:    flat_load_dword v2, v[2:3] glc
573; VI-NEXT:    s_waitcnt vmcnt(0)
574; VI-NEXT:    flat_load_dword v3, v[4:5] glc
575; VI-NEXT:    s_waitcnt vmcnt(0)
576; VI-NEXT:    v_mov_b32_e32 v0, s0
577; VI-NEXT:    v_mov_b32_e32 v1, s1
578; VI-NEXT:    v_add_u32_e32 v0, vcc, v0, v6
579; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
580; VI-NEXT:    v_mul_f32_e32 v4, 1.0, v7
581; VI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
582; VI-NEXT:    v_min_f32_e32 v5, v4, v2
583; VI-NEXT:    v_max_f32_e32 v2, v4, v2
584; VI-NEXT:    v_mul_f32_e32 v3, 1.0, v3
585; VI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
586; VI-NEXT:    v_min_f32_e32 v2, v2, v3
587; VI-NEXT:    v_mul_f32_e32 v3, 1.0, v5
588; VI-NEXT:    v_mul_f32_e32 v2, 1.0, v2
589; VI-NEXT:    v_max_f32_e32 v2, v3, v2
590; VI-NEXT:    flat_store_dword v[0:1], v5
591; VI-NEXT:    s_waitcnt vmcnt(0)
592; VI-NEXT:    flat_store_dword v[0:1], v2
593; VI-NEXT:    s_endpgm
594;
595; GFX9-LABEL: v_test_safe_med3_f32_pat0_multi_use0:
596; GFX9:       ; %bb.0:
597; GFX9-NEXT:    s_load_dwordx8 s[0:7], s[0:1], 0x24
598; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
599; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
600; GFX9-NEXT:    global_load_dword v1, v0, s[2:3] glc
601; GFX9-NEXT:    s_waitcnt vmcnt(0)
602; GFX9-NEXT:    global_load_dword v2, v0, s[4:5] glc
603; GFX9-NEXT:    s_waitcnt vmcnt(0)
604; GFX9-NEXT:    global_load_dword v3, v0, s[6:7] glc
605; GFX9-NEXT:    s_waitcnt vmcnt(0)
606; GFX9-NEXT:    v_max_f32_e32 v1, v1, v1
607; GFX9-NEXT:    v_max_f32_e32 v2, v2, v2
608; GFX9-NEXT:    v_min_f32_e32 v4, v1, v2
609; GFX9-NEXT:    v_max_f32_e32 v1, v1, v2
610; GFX9-NEXT:    global_store_dword v[0:1], v4, off
611; GFX9-NEXT:    s_waitcnt vmcnt(0)
612; GFX9-NEXT:    v_max_f32_e32 v3, v3, v3
613; GFX9-NEXT:    v_max_f32_e32 v1, v1, v1
614; GFX9-NEXT:    v_min_f32_e32 v1, v1, v3
615; GFX9-NEXT:    v_max_f32_e32 v2, v4, v4
616; GFX9-NEXT:    v_max_f32_e32 v1, v1, v1
617; GFX9-NEXT:    v_max_f32_e32 v1, v2, v1
618; GFX9-NEXT:    global_store_dword v0, v1, s[0:1]
619; GFX9-NEXT:    s_endpgm
620  %tid = call i32 @llvm.amdgcn.workitem.id.x()
621  %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
622  %gep1 = getelementptr float, float addrspace(1)* %bptr, i32 %tid
623  %gep2 = getelementptr float, float addrspace(1)* %cptr, i32 %tid
624  %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
625  %a = load volatile float, float addrspace(1)* %gep0
626  %b = load volatile float, float addrspace(1)* %gep1
627  %c = load volatile float, float addrspace(1)* %gep2
628  %tmp0 = call float @llvm.minnum.f32(float %a, float %b)
629  store volatile float %tmp0, float addrspace(1)* undef
630  %tmp1 = call float @llvm.maxnum.f32(float %a, float %b)
631  %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c)
632  %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
633  store float %med3, float addrspace(1)* %outgep
634  ret void
635}
636
637declare i32 @llvm.amdgcn.workitem.id.x() #0
638declare float @llvm.fabs.f32(float) #0
639declare float @llvm.minnum.f32(float, float) #0
640declare float @llvm.maxnum.f32(float, float) #0
641declare double @llvm.minnum.f64(double, double) #0
642declare double @llvm.maxnum.f64(double, double) #0
643declare half @llvm.fabs.f16(half) #0
644declare half @llvm.minnum.f16(half, half) #0
645declare half @llvm.maxnum.f16(half, half) #0
646
647attributes #0 = { nounwind readnone }
648attributes #1 = { nounwind "unsafe-fp-math"="false" "no-nans-fp-math"="false" }
649attributes #2 = { nounwind "unsafe-fp-math"="false" "no-nans-fp-math"="true" }
650