xref: /llvm-project/llvm/test/CodeGen/AMDGPU/fabs.ll (revision 6548b6354d1d990e1c98736f5e7c3de876bedc8e)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2; RUN: llc -march=amdgcn -enable-misched=0 < %s | FileCheck -check-prefixes=GCN,SI %s
3; RUN: llc -march=amdgcn -mcpu=tonga -enable-misched=0 < %s | FileCheck -check-prefixes=GCN,VI %s
4
5
6; DAGCombiner will transform:
7; (fabsf (f32 bitcast (i32 a))) => (f32 bitcast (and (i32 a), 0x7FFFFFFF))
8; unless isFabsFree returns true
9define amdgpu_kernel void @s_fabsf_fn_free(ptr addrspace(1) %out, i32 %in) {
10; SI-LABEL: s_fabsf_fn_free:
11; SI:       ; %bb.0:
12; SI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
13; SI-NEXT:    s_load_dword s4, s[4:5], 0xb
14; SI-NEXT:    s_mov_b32 s3, 0xf000
15; SI-NEXT:    s_mov_b32 s2, -1
16; SI-NEXT:    s_waitcnt lgkmcnt(0)
17; SI-NEXT:    s_bitset0_b32 s4, 31
18; SI-NEXT:    v_mov_b32_e32 v0, s4
19; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
20; SI-NEXT:    s_endpgm
21;
22; VI-LABEL: s_fabsf_fn_free:
23; VI:       ; %bb.0:
24; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
25; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
26; VI-NEXT:    s_waitcnt lgkmcnt(0)
27; VI-NEXT:    v_mov_b32_e32 v0, s0
28; VI-NEXT:    s_bitset0_b32 s2, 31
29; VI-NEXT:    v_mov_b32_e32 v1, s1
30; VI-NEXT:    v_mov_b32_e32 v2, s2
31; VI-NEXT:    flat_store_dword v[0:1], v2
32; VI-NEXT:    s_endpgm
33  %bc= bitcast i32 %in to float
34  %fabs = call float @fabsf(float %bc)
35  store float %fabs, ptr addrspace(1) %out
36  ret void
37}
38
39define amdgpu_kernel void @s_fabsf_free(ptr addrspace(1) %out, i32 %in) {
40; SI-LABEL: s_fabsf_free:
41; SI:       ; %bb.0:
42; SI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
43; SI-NEXT:    s_load_dword s4, s[4:5], 0xb
44; SI-NEXT:    s_mov_b32 s3, 0xf000
45; SI-NEXT:    s_mov_b32 s2, -1
46; SI-NEXT:    s_waitcnt lgkmcnt(0)
47; SI-NEXT:    s_bitset0_b32 s4, 31
48; SI-NEXT:    v_mov_b32_e32 v0, s4
49; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
50; SI-NEXT:    s_endpgm
51;
52; VI-LABEL: s_fabsf_free:
53; VI:       ; %bb.0:
54; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
55; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
56; VI-NEXT:    s_waitcnt lgkmcnt(0)
57; VI-NEXT:    v_mov_b32_e32 v0, s0
58; VI-NEXT:    s_bitset0_b32 s2, 31
59; VI-NEXT:    v_mov_b32_e32 v1, s1
60; VI-NEXT:    v_mov_b32_e32 v2, s2
61; VI-NEXT:    flat_store_dword v[0:1], v2
62; VI-NEXT:    s_endpgm
63  %bc= bitcast i32 %in to float
64  %fabs = call float @llvm.fabs.f32(float %bc)
65  store float %fabs, ptr addrspace(1) %out
66  ret void
67}
68
69define amdgpu_kernel void @s_fabsf_f32(ptr addrspace(1) %out, float %in) {
70; SI-LABEL: s_fabsf_f32:
71; SI:       ; %bb.0:
72; SI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
73; SI-NEXT:    s_load_dword s4, s[4:5], 0xb
74; SI-NEXT:    s_mov_b32 s3, 0xf000
75; SI-NEXT:    s_mov_b32 s2, -1
76; SI-NEXT:    s_waitcnt lgkmcnt(0)
77; SI-NEXT:    s_bitset0_b32 s4, 31
78; SI-NEXT:    v_mov_b32_e32 v0, s4
79; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
80; SI-NEXT:    s_endpgm
81;
82; VI-LABEL: s_fabsf_f32:
83; VI:       ; %bb.0:
84; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
85; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
86; VI-NEXT:    s_waitcnt lgkmcnt(0)
87; VI-NEXT:    v_mov_b32_e32 v0, s0
88; VI-NEXT:    s_bitset0_b32 s2, 31
89; VI-NEXT:    v_mov_b32_e32 v1, s1
90; VI-NEXT:    v_mov_b32_e32 v2, s2
91; VI-NEXT:    flat_store_dword v[0:1], v2
92; VI-NEXT:    s_endpgm
93  %fabs = call float @llvm.fabs.f32(float %in)
94  store float %fabs, ptr addrspace(1) %out
95  ret void
96}
97
98define amdgpu_kernel void @fabs_v2f32(ptr addrspace(1) %out, <2 x float> %in) {
99; SI-LABEL: fabs_v2f32:
100; SI:       ; %bb.0:
101; SI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x9
102; SI-NEXT:    s_mov_b32 s7, 0xf000
103; SI-NEXT:    s_mov_b32 s6, -1
104; SI-NEXT:    s_waitcnt lgkmcnt(0)
105; SI-NEXT:    s_mov_b32 s4, s0
106; SI-NEXT:    s_mov_b32 s5, s1
107; SI-NEXT:    s_and_b32 s0, s3, 0x7fffffff
108; SI-NEXT:    s_and_b32 s1, s2, 0x7fffffff
109; SI-NEXT:    v_mov_b32_e32 v0, s1
110; SI-NEXT:    v_mov_b32_e32 v1, s0
111; SI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
112; SI-NEXT:    s_endpgm
113;
114; VI-LABEL: fabs_v2f32:
115; VI:       ; %bb.0:
116; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
117; VI-NEXT:    s_waitcnt lgkmcnt(0)
118; VI-NEXT:    s_bitset0_b32 s3, 31
119; VI-NEXT:    s_bitset0_b32 s2, 31
120; VI-NEXT:    v_mov_b32_e32 v3, s1
121; VI-NEXT:    v_mov_b32_e32 v0, s2
122; VI-NEXT:    v_mov_b32_e32 v1, s3
123; VI-NEXT:    v_mov_b32_e32 v2, s0
124; VI-NEXT:    flat_store_dwordx2 v[2:3], v[0:1]
125; VI-NEXT:    s_endpgm
126  %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %in)
127  store <2 x float> %fabs, ptr addrspace(1) %out
128  ret void
129}
130
131define amdgpu_kernel void @fabsf_v4f32(ptr addrspace(1) %out, <4 x float> %in) {
132; SI-LABEL: fabsf_v4f32:
133; SI:       ; %bb.0:
134; SI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
135; SI-NEXT:    s_load_dwordx4 s[4:7], s[4:5], 0xd
136; SI-NEXT:    s_mov_b32 s3, 0xf000
137; SI-NEXT:    s_mov_b32 s2, -1
138; SI-NEXT:    s_waitcnt lgkmcnt(0)
139; SI-NEXT:    s_bitset0_b32 s7, 31
140; SI-NEXT:    s_bitset0_b32 s6, 31
141; SI-NEXT:    s_bitset0_b32 s5, 31
142; SI-NEXT:    s_bitset0_b32 s4, 31
143; SI-NEXT:    v_mov_b32_e32 v0, s4
144; SI-NEXT:    v_mov_b32_e32 v1, s5
145; SI-NEXT:    v_mov_b32_e32 v2, s6
146; SI-NEXT:    v_mov_b32_e32 v3, s7
147; SI-NEXT:    buffer_store_dwordx4 v[0:3], off, s[0:3], 0
148; SI-NEXT:    s_endpgm
149;
150; VI-LABEL: fabsf_v4f32:
151; VI:       ; %bb.0:
152; VI-NEXT:    s_load_dwordx2 s[6:7], s[4:5], 0x24
153; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x34
154; VI-NEXT:    s_waitcnt lgkmcnt(0)
155; VI-NEXT:    v_mov_b32_e32 v4, s6
156; VI-NEXT:    s_bitset0_b32 s3, 31
157; VI-NEXT:    s_bitset0_b32 s2, 31
158; VI-NEXT:    s_bitset0_b32 s1, 31
159; VI-NEXT:    s_bitset0_b32 s0, 31
160; VI-NEXT:    v_mov_b32_e32 v0, s0
161; VI-NEXT:    v_mov_b32_e32 v1, s1
162; VI-NEXT:    v_mov_b32_e32 v2, s2
163; VI-NEXT:    v_mov_b32_e32 v3, s3
164; VI-NEXT:    v_mov_b32_e32 v5, s7
165; VI-NEXT:    flat_store_dwordx4 v[4:5], v[0:3]
166; VI-NEXT:    s_endpgm
167  %fabs = call <4 x float> @llvm.fabs.v4f32(<4 x float> %in)
168  store <4 x float> %fabs, ptr addrspace(1) %out
169  ret void
170}
171
172define amdgpu_kernel void @fabsf_fn_fold(ptr addrspace(1) %out, float %in0, float %in1) {
173; SI-LABEL: fabsf_fn_fold:
174; SI:       ; %bb.0:
175; SI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x9
176; SI-NEXT:    s_mov_b32 s7, 0xf000
177; SI-NEXT:    s_mov_b32 s6, -1
178; SI-NEXT:    s_waitcnt lgkmcnt(0)
179; SI-NEXT:    s_mov_b32 s4, s0
180; SI-NEXT:    s_mov_b32 s5, s1
181; SI-NEXT:    v_mov_b32_e32 v0, s3
182; SI-NEXT:    v_mul_f32_e64 v0, |s2|, v0
183; SI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
184; SI-NEXT:    s_endpgm
185;
186; VI-LABEL: fabsf_fn_fold:
187; VI:       ; %bb.0:
188; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
189; VI-NEXT:    s_waitcnt lgkmcnt(0)
190; VI-NEXT:    v_mov_b32_e32 v0, s3
191; VI-NEXT:    v_mul_f32_e64 v2, |s2|, v0
192; VI-NEXT:    v_mov_b32_e32 v0, s0
193; VI-NEXT:    v_mov_b32_e32 v1, s1
194; VI-NEXT:    flat_store_dword v[0:1], v2
195; VI-NEXT:    s_endpgm
196  %fabs = call float @fabsf(float %in0)
197  %fmul = fmul float %fabs, %in1
198  store float %fmul, ptr addrspace(1) %out
199  ret void
200}
201
202define amdgpu_kernel void @fabs_fold(ptr addrspace(1) %out, float %in0, float %in1) {
203; SI-LABEL: fabs_fold:
204; SI:       ; %bb.0:
205; SI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x9
206; SI-NEXT:    s_mov_b32 s7, 0xf000
207; SI-NEXT:    s_mov_b32 s6, -1
208; SI-NEXT:    s_waitcnt lgkmcnt(0)
209; SI-NEXT:    s_mov_b32 s4, s0
210; SI-NEXT:    s_mov_b32 s5, s1
211; SI-NEXT:    v_mov_b32_e32 v0, s3
212; SI-NEXT:    v_mul_f32_e64 v0, |s2|, v0
213; SI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
214; SI-NEXT:    s_endpgm
215;
216; VI-LABEL: fabs_fold:
217; VI:       ; %bb.0:
218; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
219; VI-NEXT:    s_waitcnt lgkmcnt(0)
220; VI-NEXT:    v_mov_b32_e32 v0, s3
221; VI-NEXT:    v_mul_f32_e64 v2, |s2|, v0
222; VI-NEXT:    v_mov_b32_e32 v0, s0
223; VI-NEXT:    v_mov_b32_e32 v1, s1
224; VI-NEXT:    flat_store_dword v[0:1], v2
225; VI-NEXT:    s_endpgm
226  %fabs = call float @llvm.fabs.f32(float %in0)
227  %fmul = fmul float %fabs, %in1
228  store float %fmul, ptr addrspace(1) %out
229  ret void
230}
231
232define amdgpu_kernel void @bitpreserve_fabsf_f32(ptr addrspace(1) %out, float %in) {
233; SI-LABEL: bitpreserve_fabsf_f32:
234; SI:       ; %bb.0:
235; SI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
236; SI-NEXT:    s_load_dword s4, s[4:5], 0xb
237; SI-NEXT:    s_mov_b32 s3, 0xf000
238; SI-NEXT:    s_mov_b32 s2, -1
239; SI-NEXT:    s_waitcnt lgkmcnt(0)
240; SI-NEXT:    v_add_f32_e64 v0, |s4|, 1.0
241; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
242; SI-NEXT:    s_endpgm
243;
244; VI-LABEL: bitpreserve_fabsf_f32:
245; VI:       ; %bb.0:
246; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
247; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
248; VI-NEXT:    s_waitcnt lgkmcnt(0)
249; VI-NEXT:    v_mov_b32_e32 v0, s0
250; VI-NEXT:    v_add_f32_e64 v2, |s2|, 1.0
251; VI-NEXT:    v_mov_b32_e32 v1, s1
252; VI-NEXT:    flat_store_dword v[0:1], v2
253; VI-NEXT:    s_endpgm
254  %in.bc = bitcast float %in to i32
255  %int.abs = and i32 %in.bc, 2147483647
256  %bc = bitcast i32 %int.abs to float
257  %fadd = fadd float %bc, 1.0
258  store float %fadd, ptr addrspace(1) %out
259  ret void
260}
261
262declare float @fabsf(float) readnone
263declare float @llvm.fabs.f32(float) readnone
264declare <2 x float> @llvm.fabs.v2f32(<2 x float>) readnone
265declare <4 x float> @llvm.fabs.v4f32(<4 x float>) readnone
266;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
267; GCN: {{.*}}
268