xref: /llvm-project/llvm/test/Transforms/InstCombine/cos-1.ll (revision 37462944513731af2743d95e5dd40bdbeefd6460)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S                             | FileCheck %s --check-prefixes=ANY,NO-FLOAT-SHRINK
3; RUN: opt < %s -passes=instcombine -enable-double-float-shrink -S | FileCheck %s --check-prefixes=ANY,DO-FLOAT-SHRINK
4
5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6
7declare double @cos(double)
8declare double @llvm.cos.f64(double)
9declare float @cosf(float)
10declare float @llvm.cos.f32(float)
11
12declare double @sin(double)
13declare double @llvm.sin.f64(double)
14declare float @sinf(float)
15declare float @llvm.sin.f32(float)
16
17declare double @tan(double)
18declare fp128 @tanl(fp128)
19
20declare double @fabs(double)
21declare double @llvm.fabs.f64(double)
22declare float @fabsf(float)
23declare float @llvm.fabs.f32(float)
24
25declare double @llvm.copysign(double, double)
26declare float @llvm.copysign.f32(float, float)
27
28; cos(-x) -> cos(x);
29
30define double @cos_negated_arg(double %x) {
31; ANY-LABEL: @cos_negated_arg(
32; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
33; ANY-NEXT:    ret double [[COS]]
34;
35  %neg = fsub double -0.0, %x
36  %r = call double @cos(double %neg)
37  ret double %r
38}
39
40define double @cos_negated_arg_tail(double %x) {
41; ANY-LABEL: @cos_negated_arg_tail(
42; ANY-NEXT:    [[COS:%.*]] = tail call double @cos(double [[X:%.*]])
43; ANY-NEXT:    ret double [[COS]]
44;
45  %neg = fsub double -0.0, %x
46  %r = tail call double @cos(double %neg)
47  ret double %r
48}
49
50define double @cos_negated_arg_musttail(double %x) {
51; ANY-LABEL: @cos_negated_arg_musttail(
52; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
53; ANY-NEXT:    [[R:%.*]] = musttail call double @cos(double [[NEG]])
54; ANY-NEXT:    ret double [[R]]
55;
56  %neg = fsub double -0.0, %x
57  %r = musttail call double @cos(double %neg)
58  ret double %r
59}
60
61define double @cos_unary_negated_arg(double %x) {
62; ANY-LABEL: @cos_unary_negated_arg(
63; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
64; ANY-NEXT:    ret double [[COS]]
65;
66  %neg = fneg double %x
67  %r = call double @cos(double %neg)
68  ret double %r
69}
70
71define float @cosf_negated_arg(float %x) {
72; ANY-LABEL: @cosf_negated_arg(
73; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
74; ANY-NEXT:    ret float [[COS]]
75;
76  %neg = fsub float -0.0, %x
77  %r = call float @cosf(float %neg)
78  ret float %r
79}
80
81define float @cosf_unary_negated_arg(float %x) {
82; ANY-LABEL: @cosf_unary_negated_arg(
83; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
84; ANY-NEXT:    ret float [[COS]]
85;
86  %neg = fneg float %x
87  %r = call float @cosf(float %neg)
88  ret float %r
89}
90
91define float @cosf_negated_arg_FMF(float %x) {
92; ANY-LABEL: @cosf_negated_arg_FMF(
93; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
94; ANY-NEXT:    ret float [[COS]]
95;
96  %neg = fsub float -0.0, %x
97  %r = call nnan reassoc float @cosf(float %neg)
98  ret float %r
99}
100
101define float @cosf_unary_negated_arg_FMF(float %x) {
102; ANY-LABEL: @cosf_unary_negated_arg_FMF(
103; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
104; ANY-NEXT:    ret float [[COS]]
105;
106  %neg = fneg float %x
107  %r = call nnan reassoc float @cosf(float %neg)
108  ret float %r
109}
110
111; cos(fabs(x)) -> cos(x)
112
113define double @cos_unary_fabs_arg(double %x) {
114; ANY-LABEL: @cos_unary_fabs_arg(
115; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
116; ANY-NEXT:    ret double [[COS]]
117;
118  %fabs = tail call double @llvm.fabs.f64(double %x)
119  %r = call double @cos(double %fabs)
120  ret double %r
121}
122
123define float @cosf_unary_fabs_arg(float %x) {
124; ANY-LABEL: @cosf_unary_fabs_arg(
125; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
126; ANY-NEXT:    ret float [[COS]]
127;
128  %fabs = tail call float @llvm.fabs.f32(float %x)
129  %r = call float @cosf(float %fabs)
130  ret float %r
131}
132
133define float @cosf_unary_fabs_arg_FMF(float %x) {
134; ANY-LABEL: @cosf_unary_fabs_arg_FMF(
135; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
136; ANY-NEXT:    ret float [[COS]]
137;
138  %fabs = tail call float @llvm.fabs.f32(float %x)
139  %r = call nnan reassoc float @cosf(float %fabs)
140  ret float %r
141}
142
143; cos(copysign(x, y)) -> cos(x)
144
145define double @cos_copysign_arg(double %x, double %y) {
146; ANY-LABEL: @cos_copysign_arg(
147; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
148; ANY-NEXT:    ret double [[COS]]
149;
150  %copysign = tail call double @llvm.copysign(double %x, double %y)
151  %r = call double @cos(double %copysign)
152  ret double %r
153}
154
155
156define float @cosf_unary_copysign_arg(float %x) {
157; ANY-LABEL: @cosf_unary_copysign_arg(
158; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
159; ANY-NEXT:    ret float [[COS]]
160;
161  %copysign = tail call float @llvm.copysign.f32(float %x, float 1.0)
162  %r = call float @cosf(float %copysign)
163  ret float %r
164}
165
166define float @cosf_copysign_arg_FMF(float %x, float %y) {
167; ANY-LABEL: @cosf_copysign_arg_FMF(
168; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
169; ANY-NEXT:    ret float [[COS]]
170;
171  %copysign = tail call float @llvm.copysign.f32(float %x, float %y)
172  %r = call nnan reassoc float @cosf(float %copysign)
173  ret float %r
174}
175
176; sin(-x) -> -sin(x);
177
178define double @sin_negated_arg(double %x) {
179; ANY-LABEL: @sin_negated_arg(
180; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
181; ANY-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
182; ANY-NEXT:    ret double [[R]]
183;
184  %neg = fsub double -0.0, %x
185  %r = call double @sin(double %neg)
186  ret double %r
187}
188
189define double @sin_unary_negated_arg(double %x) {
190; ANY-LABEL: @sin_unary_negated_arg(
191; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
192; ANY-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
193; ANY-NEXT:    ret double [[R]]
194;
195  %neg = fneg double %x
196  %r = call double @sin(double %neg)
197  ret double %r
198}
199
200define double @sin_unary_negated_arg_musttail(double %x) {
201; ANY-LABEL: @sin_unary_negated_arg_musttail(
202; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
203; ANY-NEXT:    [[R:%.*]] = musttail call double @sin(double [[NEG]])
204; ANY-NEXT:    ret double [[R]]
205;
206  %neg = fneg double %x
207  %r = musttail call double @sin(double %neg)
208  ret double %r
209}
210
211define float @sinf_negated_arg(float %x) {
212; ANY-LABEL: @sinf_negated_arg(
213; ANY-NEXT:    [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])
214; ANY-NEXT:    [[R:%.*]] = fneg float [[TMP1]]
215; ANY-NEXT:    ret float [[R]]
216;
217  %neg = fsub float -0.0, %x
218  %r = call float @sinf(float %neg)
219  ret float %r
220}
221
222define float @sinf_unary_negated_arg(float %x) {
223; ANY-LABEL: @sinf_unary_negated_arg(
224; ANY-NEXT:    [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])
225; ANY-NEXT:    [[R:%.*]] = fneg float [[TMP1]]
226; ANY-NEXT:    ret float [[R]]
227;
228  %neg = fneg float %x
229  %r = call float @sinf(float %neg)
230  ret float %r
231}
232
233define float @sinf_negated_arg_FMF(float %x) {
234; ANY-LABEL: @sinf_negated_arg_FMF(
235; ANY-NEXT:    [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])
236; ANY-NEXT:    [[R:%.*]] = fneg nnan afn float [[TMP1]]
237; ANY-NEXT:    ret float [[R]]
238;
239  %neg = fsub ninf float -0.0, %x
240  %r = call afn nnan float @sinf(float %neg)
241  ret float %r
242}
243
244define float @sinf_unary_negated_arg_FMF(float %x) {
245; ANY-LABEL: @sinf_unary_negated_arg_FMF(
246; ANY-NEXT:    [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])
247; ANY-NEXT:    [[R:%.*]] = fneg nnan afn float [[TMP1]]
248; ANY-NEXT:    ret float [[R]]
249;
250  %neg = fneg ninf float %x
251  %r = call afn nnan float @sinf(float %neg)
252  ret float %r
253}
254
255declare void @use(double)
256
257define double @sin_negated_arg_extra_use(double %x) {
258; ANY-LABEL: @sin_negated_arg_extra_use(
259; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
260; ANY-NEXT:    [[R:%.*]] = call double @sin(double [[NEG]])
261; ANY-NEXT:    call void @use(double [[NEG]])
262; ANY-NEXT:    ret double [[R]]
263;
264  %neg = fsub double -0.0, %x
265  %r = call double @sin(double %neg)
266  call void @use(double %neg)
267  ret double %r
268}
269
270define double @sin_unary_negated_arg_extra_use(double %x) {
271; ANY-LABEL: @sin_unary_negated_arg_extra_use(
272; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
273; ANY-NEXT:    [[R:%.*]] = call double @sin(double [[NEG]])
274; ANY-NEXT:    call void @use(double [[NEG]])
275; ANY-NEXT:    ret double [[R]]
276;
277  %neg = fneg double %x
278  %r = call double @sin(double %neg)
279  call void @use(double %neg)
280  ret double %r
281}
282
283; -sin(-x) --> sin(x)
284; PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458
285
286define double @neg_sin_negated_arg(double %x) {
287; ANY-LABEL: @neg_sin_negated_arg(
288; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
289; ANY-NEXT:    ret double [[TMP1]]
290;
291  %neg = fsub double -0.0, %x
292  %r = call double @sin(double %neg)
293  %rn = fsub double -0.0, %r
294  ret double %rn
295}
296
297define double @unary_neg_sin_unary_negated_arg(double %x) {
298; ANY-LABEL: @unary_neg_sin_unary_negated_arg(
299; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
300; ANY-NEXT:    ret double [[TMP1]]
301;
302  %neg = fneg double %x
303  %r = call double @sin(double %neg)
304  %rn = fneg double %r
305  ret double %rn
306}
307
308define double @neg_sin_unary_negated_arg(double %x) {
309; ANY-LABEL: @neg_sin_unary_negated_arg(
310; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
311; ANY-NEXT:    ret double [[TMP1]]
312;
313  %neg = fsub double -0.0, %x
314  %r = call double @sin(double %neg)
315  %rn = fneg double %r
316  ret double %rn
317}
318
319define double @unary_neg_sin_negated_arg(double %x) {
320; ANY-LABEL: @unary_neg_sin_negated_arg(
321; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
322; ANY-NEXT:    ret double [[TMP1]]
323;
324  %neg = fneg double %x
325  %r = call double @sin(double %neg)
326  %rn = fsub double -0.0, %r
327  ret double %rn
328}
329
330; tan(-x) -> -tan(x);
331
332define double @tan_negated_arg(double %x) {
333; ANY-LABEL: @tan_negated_arg(
334; ANY-NEXT:    [[TMP1:%.*]] = call double @tan(double [[X:%.*]])
335; ANY-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
336; ANY-NEXT:    ret double [[R]]
337;
338  %neg = fsub double -0.0, %x
339  %r = call double @tan(double %neg)
340  ret double %r
341}
342
343define double @tan_negated_arg_tail(double %x) {
344; ANY-LABEL: @tan_negated_arg_tail(
345; ANY-NEXT:    [[TMP1:%.*]] = tail call double @tan(double [[X:%.*]])
346; ANY-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
347; ANY-NEXT:    ret double [[R]]
348;
349  %neg = fsub double -0.0, %x
350  %r = tail call double @tan(double %neg)
351  ret double %r
352}
353define double @tan_negated_arg_musttail(double %x) {
354; ANY-LABEL: @tan_negated_arg_musttail(
355; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
356; ANY-NEXT:    [[R:%.*]] = musttail call double @tan(double [[NEG]])
357; ANY-NEXT:    ret double [[R]]
358;
359  %neg = fsub double -0.0, %x
360  %r = musttail call double @tan(double %neg)
361  ret double %r
362}
363
364define double @tan_unary_negated_arg(double %x) {
365; ANY-LABEL: @tan_unary_negated_arg(
366; ANY-NEXT:    [[TMP1:%.*]] = call double @tan(double [[X:%.*]])
367; ANY-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
368; ANY-NEXT:    ret double [[R]]
369;
370  %neg = fneg double %x
371  %r = call double @tan(double %neg)
372  ret double %r
373}
374
375; tanl(-x) -> -tanl(x);
376
377define fp128 @tanl_negated_arg(fp128 %x) {
378; ANY-LABEL: @tanl_negated_arg(
379; ANY-NEXT:    [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])
380; ANY-NEXT:    [[R:%.*]] = fneg fp128 [[TMP1]]
381; ANY-NEXT:    ret fp128 [[R]]
382;
383  %neg = fsub fp128 0xL00000000000000008000000000000000, %x
384  %r = call fp128 @tanl(fp128 %neg)
385  ret fp128 %r
386}
387
388define fp128 @tanl_unary_negated_arg(fp128 %x) {
389; ANY-LABEL: @tanl_unary_negated_arg(
390; ANY-NEXT:    [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])
391; ANY-NEXT:    [[R:%.*]] = fneg fp128 [[TMP1]]
392; ANY-NEXT:    ret fp128 [[R]]
393;
394  %neg = fneg fp128 %x
395  %r = call fp128 @tanl(fp128 %neg)
396  ret fp128 %r
397}
398
399define float @negated_and_shrinkable_libcall(float %f) {
400; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(
401; NO-FLOAT-SHRINK-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
402; NO-FLOAT-SHRINK-NEXT:    [[COS1:%.*]] = call double @cos(double [[CONV1]])
403; NO-FLOAT-SHRINK-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS1]] to float
404; NO-FLOAT-SHRINK-NEXT:    ret float [[CONV2]]
405;
406; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(
407; DO-FLOAT-SHRINK-NEXT:    [[COSF:%.*]] = call float @cosf(float [[F:%.*]])
408; DO-FLOAT-SHRINK-NEXT:    ret float [[COSF]]
409;
410  %conv1 = fpext float %f to double
411  %neg = fsub double -0.0, %conv1
412  %cos = call double @cos(double %neg)
413  %conv2 = fptrunc double %cos to float
414  ret float %conv2
415}
416
417define float @unary_negated_and_shrinkable_libcall(float %f) {
418; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(
419; NO-FLOAT-SHRINK-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
420; NO-FLOAT-SHRINK-NEXT:    [[COS1:%.*]] = call double @cos(double [[CONV1]])
421; NO-FLOAT-SHRINK-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS1]] to float
422; NO-FLOAT-SHRINK-NEXT:    ret float [[CONV2]]
423;
424; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(
425; DO-FLOAT-SHRINK-NEXT:    [[COSF:%.*]] = call float @cosf(float [[F:%.*]])
426; DO-FLOAT-SHRINK-NEXT:    ret float [[COSF]]
427;
428  %conv1 = fpext float %f to double
429  %neg = fneg double %conv1
430  %cos = call double @cos(double %neg)
431  %conv2 = fptrunc double %cos to float
432  ret float %conv2
433}
434
435; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?
436
437define float @negated_and_shrinkable_intrinsic(float %f) {
438; ANY-LABEL: @negated_and_shrinkable_intrinsic(
439; ANY-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
440; ANY-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
441; ANY-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
442; ANY-NEXT:    ret float [[CONV2]]
443;
444  %conv1 = fpext float %f to double
445  %neg = fsub double -0.0, %conv1
446  %cos = call double @llvm.cos.f64(double %neg)
447  %conv2 = fptrunc double %cos to float
448  ret float %conv2
449}
450
451define float @unary_negated_and_shrinkable_intrinsic(float %f) {
452; ANY-LABEL: @unary_negated_and_shrinkable_intrinsic(
453; ANY-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
454; ANY-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
455; ANY-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
456; ANY-NEXT:    ret float [[CONV2]]
457;
458  %conv1 = fpext float %f to double
459  %neg = fneg double %conv1
460  %cos = call double @llvm.cos.f64(double %neg)
461  %conv2 = fptrunc double %cos to float
462  ret float %conv2
463}
464