1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
2
3declare float @llvm.canonicalize.f32(float) #0
4declare double @llvm.canonicalize.f64(double) #0
5
6; GCN-LABEL: {{^}}v_test_canonicalize_var_f32:
7; GCN: v_mul_f32_e32 [[REG:v[0-9]+]], 1.0, {{v[0-9]+}}
8; GCN: buffer_store_dword [[REG]]
9define void @v_test_canonicalize_var_f32(float addrspace(1)* %out) #1 {
10  %val = load float, float addrspace(1)* %out
11  %canonicalized = call float @llvm.canonicalize.f32(float %val)
12  store float %canonicalized, float addrspace(1)* %out
13  ret void
14}
15
16; GCN-LABEL: {{^}}s_test_canonicalize_var_f32:
17; GCN: v_mul_f32_e64 [[REG:v[0-9]+]], 1.0, {{s[0-9]+}}
18; GCN: buffer_store_dword [[REG]]
19define void @s_test_canonicalize_var_f32(float addrspace(1)* %out, float %val) #1 {
20  %canonicalized = call float @llvm.canonicalize.f32(float %val)
21  store float %canonicalized, float addrspace(1)* %out
22  ret void
23}
24
25; GCN-LABEL: {{^}}test_fold_canonicalize_p0_f32:
26; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0{{$}}
27; GCN: buffer_store_dword [[REG]]
28define void @test_fold_canonicalize_p0_f32(float addrspace(1)* %out) #1 {
29  %canonicalized = call float @llvm.canonicalize.f32(float 0.0)
30  store float %canonicalized, float addrspace(1)* %out
31  ret void
32}
33
34; GCN-LABEL: {{^}}test_fold_canonicalize_n0_f32:
35; GCN: v_bfrev_b32_e32 [[REG:v[0-9]+]], 1{{$}}
36; GCN: buffer_store_dword [[REG]]
37define void @test_fold_canonicalize_n0_f32(float addrspace(1)* %out) #1 {
38  %canonicalized = call float @llvm.canonicalize.f32(float -0.0)
39  store float %canonicalized, float addrspace(1)* %out
40  ret void
41}
42
43; GCN-LABEL: {{^}}test_fold_canonicalize_p1_f32:
44; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 1.0{{$}}
45; GCN: buffer_store_dword [[REG]]
46define void @test_fold_canonicalize_p1_f32(float addrspace(1)* %out) #1 {
47  %canonicalized = call float @llvm.canonicalize.f32(float 1.0)
48  store float %canonicalized, float addrspace(1)* %out
49  ret void
50}
51
52; GCN-LABEL: {{^}}test_fold_canonicalize_n1_f32:
53; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], -1.0{{$}}
54; GCN: buffer_store_dword [[REG]]
55define void @test_fold_canonicalize_n1_f32(float addrspace(1)* %out) #1 {
56  %canonicalized = call float @llvm.canonicalize.f32(float -1.0)
57  store float %canonicalized, float addrspace(1)* %out
58  ret void
59}
60
61; GCN-LABEL: {{^}}test_fold_canonicalize_literal_f32:
62; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x41800000{{$}}
63; GCN: buffer_store_dword [[REG]]
64define void @test_fold_canonicalize_literal_f32(float addrspace(1)* %out) #1 {
65  %canonicalized = call float @llvm.canonicalize.f32(float 16.0)
66  store float %canonicalized, float addrspace(1)* %out
67  ret void
68}
69
70; GCN-LABEL: {{^}}test_no_denormals_fold_canonicalize_denormal0_f32:
71; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0{{$}}
72; GCN: buffer_store_dword [[REG]]
73define void @test_no_denormals_fold_canonicalize_denormal0_f32(float addrspace(1)* %out) #1 {
74  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
75  store float %canonicalized, float addrspace(1)* %out
76  ret void
77}
78
79; GCN-LABEL: {{^}}test_denormals_fold_canonicalize_denormal0_f32:
80; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fffff{{$}}
81; GCN: buffer_store_dword [[REG]]
82define void @test_denormals_fold_canonicalize_denormal0_f32(float addrspace(1)* %out) #3 {
83  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
84  store float %canonicalized, float addrspace(1)* %out
85  ret void
86}
87
88; GCN-LABEL: {{^}}test_no_denormals_fold_canonicalize_denormal1_f32:
89; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0{{$}}
90; GCN: buffer_store_dword [[REG]]
91define void @test_no_denormals_fold_canonicalize_denormal1_f32(float addrspace(1)* %out) #1 {
92  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2155872255 to float))
93  store float %canonicalized, float addrspace(1)* %out
94  ret void
95}
96
97; GCN-LABEL: {{^}}test_denormals_fold_canonicalize_denormal1_f32:
98; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x807fffff{{$}}
99; GCN: buffer_store_dword [[REG]]
100define void @test_denormals_fold_canonicalize_denormal1_f32(float addrspace(1)* %out) #3 {
101  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2155872255 to float))
102  store float %canonicalized, float addrspace(1)* %out
103  ret void
104}
105
106; GCN-LABEL: {{^}}test_fold_canonicalize_qnan_f32:
107; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
108; GCN: buffer_store_dword [[REG]]
109define void @test_fold_canonicalize_qnan_f32(float addrspace(1)* %out) #1 {
110  %canonicalized = call float @llvm.canonicalize.f32(float 0x7FF8000000000000)
111  store float %canonicalized, float addrspace(1)* %out
112  ret void
113}
114
115; GCN-LABEL: {{^}}test_fold_canonicalize_qnan_value_neg1_f32:
116; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
117; GCN: buffer_store_dword [[REG]]
118define void @test_fold_canonicalize_qnan_value_neg1_f32(float addrspace(1)* %out) #1 {
119  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 -1 to float))
120  store float %canonicalized, float addrspace(1)* %out
121  ret void
122}
123
124; GCN-LABEL: {{^}}test_fold_canonicalize_qnan_value_neg2_f32:
125; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
126; GCN: buffer_store_dword [[REG]]
127define void @test_fold_canonicalize_qnan_value_neg2_f32(float addrspace(1)* %out) #1 {
128  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 -2 to float))
129  store float %canonicalized, float addrspace(1)* %out
130  ret void
131}
132
133; GCN-LABEL: {{^}}test_fold_canonicalize_snan0_value_f32:
134; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
135; GCN: buffer_store_dword [[REG]]
136define void @test_fold_canonicalize_snan0_value_f32(float addrspace(1)* %out) #1 {
137  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2139095041 to float))
138  store float %canonicalized, float addrspace(1)* %out
139  ret void
140}
141
142; GCN-LABEL: {{^}}test_fold_canonicalize_snan1_value_f32:
143; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
144; GCN: buffer_store_dword [[REG]]
145define void @test_fold_canonicalize_snan1_value_f32(float addrspace(1)* %out) #1 {
146  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2143289343 to float))
147  store float %canonicalized, float addrspace(1)* %out
148  ret void
149}
150
151; GCN-LABEL: {{^}}test_fold_canonicalize_snan2_value_f32:
152; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
153; GCN: buffer_store_dword [[REG]]
154define void @test_fold_canonicalize_snan2_value_f32(float addrspace(1)* %out) #1 {
155  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 4286578689 to float))
156  store float %canonicalized, float addrspace(1)* %out
157  ret void
158}
159
160; GCN-LABEL: {{^}}test_fold_canonicalize_snan3_value_f32:
161; GCN: v_mov_b32_e32 [[REG:v[0-9]+]], 0x7fc00000{{$}}
162; GCN: buffer_store_dword [[REG]]
163define void @test_fold_canonicalize_snan3_value_f32(float addrspace(1)* %out) #1 {
164  %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 4290772991 to float))
165  store float %canonicalized, float addrspace(1)* %out
166  ret void
167}
168
169; GCN-LABEL: {{^}}v_test_canonicalize_var_f64:
170; GCN: v_mul_f64 [[REG:v\[[0-9]+:[0-9]+\]]], 1.0, {{v\[[0-9]+:[0-9]+\]}}
171; GCN: buffer_store_dwordx2 [[REG]]
172define void @v_test_canonicalize_var_f64(double addrspace(1)* %out) #1 {
173  %val = load double, double addrspace(1)* %out
174  %canonicalized = call double @llvm.canonicalize.f64(double %val)
175  store double %canonicalized, double addrspace(1)* %out
176  ret void
177}
178
179; GCN-LABEL: {{^}}s_test_canonicalize_var_f64:
180; GCN: v_mul_f64 [[REG:v\[[0-9]+:[0-9]+\]]], 1.0, {{s\[[0-9]+:[0-9]+\]}}
181; GCN: buffer_store_dwordx2 [[REG]]
182define void @s_test_canonicalize_var_f64(double addrspace(1)* %out, double %val) #1 {
183  %canonicalized = call double @llvm.canonicalize.f64(double %val)
184  store double %canonicalized, double addrspace(1)* %out
185  ret void
186}
187
188; GCN-LABEL: {{^}}test_fold_canonicalize_p0_f64:
189; GCN: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
190; GCN: v_mov_b32_e32 v[[HI:[0-9]+]], v[[LO]]{{$}}
191; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
192define void @test_fold_canonicalize_p0_f64(double addrspace(1)* %out) #1 {
193  %canonicalized = call double @llvm.canonicalize.f64(double 0.0)
194  store double %canonicalized, double addrspace(1)* %out
195  ret void
196}
197
198; GCN-LABEL: {{^}}test_fold_canonicalize_n0_f64:
199; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
200; GCN-DAG: v_bfrev_b32_e32 v[[HI:[0-9]+]], 1{{$}}
201; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
202define void @test_fold_canonicalize_n0_f64(double addrspace(1)* %out) #1 {
203  %canonicalized = call double @llvm.canonicalize.f64(double -0.0)
204  store double %canonicalized, double addrspace(1)* %out
205  ret void
206}
207
208; GCN-LABEL: {{^}}test_fold_canonicalize_p1_f64:
209; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
210; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x3ff00000{{$}}
211; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
212define void @test_fold_canonicalize_p1_f64(double addrspace(1)* %out) #1 {
213  %canonicalized = call double @llvm.canonicalize.f64(double 1.0)
214  store double %canonicalized, double addrspace(1)* %out
215  ret void
216}
217
218; GCN-LABEL: {{^}}test_fold_canonicalize_n1_f64:
219; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
220; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0xbff00000{{$}}
221; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
222define void @test_fold_canonicalize_n1_f64(double addrspace(1)* %out) #1 {
223  %canonicalized = call double @llvm.canonicalize.f64(double -1.0)
224  store double %canonicalized, double addrspace(1)* %out
225  ret void
226}
227
228; GCN-LABEL: {{^}}test_fold_canonicalize_literal_f64:
229; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
230; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x40300000{{$}}
231; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
232define void @test_fold_canonicalize_literal_f64(double addrspace(1)* %out) #1 {
233  %canonicalized = call double @llvm.canonicalize.f64(double 16.0)
234  store double %canonicalized, double addrspace(1)* %out
235  ret void
236}
237
238; GCN-LABEL: {{^}}test_no_denormals_fold_canonicalize_denormal0_f64:
239; GCN: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
240; GCN: v_mov_b32_e32 v[[HI:[0-9]+]], v[[LO]]{{$}}
241; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
242define void @test_no_denormals_fold_canonicalize_denormal0_f64(double addrspace(1)* %out) #2 {
243  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 4503599627370495 to double))
244  store double %canonicalized, double addrspace(1)* %out
245  ret void
246}
247
248; GCN-LABEL: {{^}}test_denormals_fold_canonicalize_denormal0_f64:
249; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], -1{{$}}
250; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0xfffff{{$}}
251; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
252define void @test_denormals_fold_canonicalize_denormal0_f64(double addrspace(1)* %out) #3 {
253  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 4503599627370495 to double))
254  store double %canonicalized, double addrspace(1)* %out
255  ret void
256}
257
258; GCN-LABEL: {{^}}test_no_denormals_fold_canonicalize_denormal1_f64:
259; GCN: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
260; GCN: v_mov_b32_e32 v[[HI:[0-9]+]], v[[LO]]{{$}}
261; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
262define void @test_no_denormals_fold_canonicalize_denormal1_f64(double addrspace(1)* %out) #2 {
263  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 9227875636482146303 to double))
264  store double %canonicalized, double addrspace(1)* %out
265  ret void
266}
267
268; GCN-LABEL: {{^}}test_denormals_fold_canonicalize_denormal1_f64:
269; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], -1{{$}}
270; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x800fffff{{$}}
271; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
272define void @test_denormals_fold_canonicalize_denormal1_f64(double addrspace(1)* %out) #3 {
273  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 9227875636482146303 to double))
274  store double %canonicalized, double addrspace(1)* %out
275  ret void
276}
277
278; GCN-LABEL: {{^}}test_fold_canonicalize_qnan_f64:
279; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
280; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
281; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
282define void @test_fold_canonicalize_qnan_f64(double addrspace(1)* %out) #1 {
283  %canonicalized = call double @llvm.canonicalize.f64(double 0x7FF8000000000000)
284  store double %canonicalized, double addrspace(1)* %out
285  ret void
286}
287
288; GCN-LABEL: {{^}}test_fold_canonicalize_qnan_value_neg1_f64:
289; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
290; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
291; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
292define void @test_fold_canonicalize_qnan_value_neg1_f64(double addrspace(1)* %out) #1 {
293  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 -1 to double))
294  store double %canonicalized, double addrspace(1)* %out
295  ret void
296}
297
298; GCN-LABEL: {{^}}test_fold_canonicalize_qnan_value_neg2_f64:
299; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
300; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
301; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
302define void @test_fold_canonicalize_qnan_value_neg2_f64(double addrspace(1)* %out) #1 {
303  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 -2 to double))
304  store double %canonicalized, double addrspace(1)* %out
305  ret void
306}
307
308; GCN-LABEL: {{^}}test_fold_canonicalize_snan0_value_f64:
309; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
310; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
311; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
312define void @test_fold_canonicalize_snan0_value_f64(double addrspace(1)* %out) #1 {
313  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 9218868437227405313 to double))
314  store double %canonicalized, double addrspace(1)* %out
315  ret void
316}
317
318; GCN-LABEL: {{^}}test_fold_canonicalize_snan1_value_f64:
319; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
320; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
321; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
322define void @test_fold_canonicalize_snan1_value_f64(double addrspace(1)* %out) #1 {
323  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 9223372036854775807 to double))
324  store double %canonicalized, double addrspace(1)* %out
325  ret void
326}
327
328; GCN-LABEL: {{^}}test_fold_canonicalize_snan2_value_f64:
329; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
330; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
331; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
332define void @test_fold_canonicalize_snan2_value_f64(double addrspace(1)* %out) #1 {
333  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 18442240474082181121 to double))
334  store double %canonicalized, double addrspace(1)* %out
335  ret void
336}
337
338; GCN-LABEL: {{^}}test_fold_canonicalize_snan3_value_f64:
339; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7ff80000{{$}}
340; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
341; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
342define void @test_fold_canonicalize_snan3_value_f64(double addrspace(1)* %out) #1 {
343  %canonicalized = call double @llvm.canonicalize.f64(double bitcast (i64 18446744073709551615 to double))
344  store double %canonicalized, double addrspace(1)* %out
345  ret void
346}
347
348attributes #0 = { nounwind readnone }
349attributes #1 = { nounwind }
350attributes #2 = { nounwind "target-features"="-fp32-denormals,-fp64-denormals" }
351attributes #3 = { nounwind "target-features"="+fp32-denormals,+fp64-denormals" }
352