[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / cos-1.ll
blob6b2474ed1d089ce05e621308acd0e7cca5be029e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S                             | FileCheck %s --check-prefixes=ANY,NO-FLOAT-SHRINK
3 ; RUN: opt < %s -instcombine -enable-double-float-shrink -S | FileCheck %s --check-prefixes=ANY,DO-FLOAT-SHRINK
5 target 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"
7 declare double @cos(double)
8 declare double @llvm.cos.f64(double)
9 declare float @cosf(float)
10 declare float @llvm.cos.f32(float)
12 declare double @sin(double)
13 declare double @llvm.sin.f64(double)
14 declare float @sinf(float)
15 declare float @llvm.sin.f32(float)
17 declare double @tan(double)
18 declare fp128 @tanl(fp128)
20 ; cos(-x) -> cos(x);
22 define double @cos_negated_arg(double %x) {
23 ; ANY-LABEL: @cos_negated_arg(
24 ; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
25 ; ANY-NEXT:    ret double [[COS]]
27   %neg = fsub double -0.0, %x
28   %r = call double @cos(double %neg)
29   ret double %r
32 define double @cos_unary_negated_arg(double %x) {
33 ; ANY-LABEL: @cos_unary_negated_arg(
34 ; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
35 ; ANY-NEXT:    ret double [[COS]]
37   %neg = fneg double %x
38   %r = call double @cos(double %neg)
39   ret double %r
42 define float @cosf_negated_arg(float %x) {
43 ; ANY-LABEL: @cosf_negated_arg(
44 ; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
45 ; ANY-NEXT:    ret float [[COS]]
47   %neg = fsub float -0.0, %x
48   %r = call float @cosf(float %neg)
49   ret float %r
52 define float @cosf_unary_negated_arg(float %x) {
53 ; ANY-LABEL: @cosf_unary_negated_arg(
54 ; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
55 ; ANY-NEXT:    ret float [[COS]]
57   %neg = fneg float %x
58   %r = call float @cosf(float %neg)
59   ret float %r
62 define float @cosf_negated_arg_FMF(float %x) {
63 ; ANY-LABEL: @cosf_negated_arg_FMF(
64 ; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
65 ; ANY-NEXT:    ret float [[COS]]
67   %neg = fsub float -0.0, %x
68   %r = call nnan reassoc float @cosf(float %neg)
69   ret float %r
72 define float @cosf_unary_negated_arg_FMF(float %x) {
73 ; ANY-LABEL: @cosf_unary_negated_arg_FMF(
74 ; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
75 ; ANY-NEXT:    ret float [[COS]]
77   %neg = fneg float %x
78   %r = call nnan reassoc float @cosf(float %neg)
79   ret float %r
82 ; sin(-x) -> -sin(x);
84 define double @sin_negated_arg(double %x) {
85 ; ANY-LABEL: @sin_negated_arg(
86 ; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
87 ; ANY-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
88 ; ANY-NEXT:    ret double [[TMP2]]
90   %neg = fsub double -0.0, %x
91   %r = call double @sin(double %neg)
92   ret double %r
95 define double @sin_unary_negated_arg(double %x) {
96 ; ANY-LABEL: @sin_unary_negated_arg(
97 ; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
98 ; ANY-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
99 ; ANY-NEXT:    ret double [[TMP2]]
101   %neg = fneg double %x
102   %r = call double @sin(double %neg)
103   ret double %r
106 define float @sinf_negated_arg(float %x) {
107 ; ANY-LABEL: @sinf_negated_arg(
108 ; ANY-NEXT:    [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])
109 ; ANY-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
110 ; ANY-NEXT:    ret float [[TMP2]]
112   %neg = fsub float -0.0, %x
113   %r = call float @sinf(float %neg)
114   ret float %r
117 define float @sinf_unary_negated_arg(float %x) {
118 ; ANY-LABEL: @sinf_unary_negated_arg(
119 ; ANY-NEXT:    [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])
120 ; ANY-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
121 ; ANY-NEXT:    ret float [[TMP2]]
123   %neg = fneg float %x
124   %r = call float @sinf(float %neg)
125   ret float %r
128 define float @sinf_negated_arg_FMF(float %x) {
129 ; ANY-LABEL: @sinf_negated_arg_FMF(
130 ; ANY-NEXT:    [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])
131 ; ANY-NEXT:    [[TMP2:%.*]] = fneg nnan afn float [[TMP1]]
132 ; ANY-NEXT:    ret float [[TMP2]]
134   %neg = fsub ninf float -0.0, %x
135   %r = call afn nnan float @sinf(float %neg)
136   ret float %r
139 define float @sinf_unary_negated_arg_FMF(float %x) {
140 ; ANY-LABEL: @sinf_unary_negated_arg_FMF(
141 ; ANY-NEXT:    [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])
142 ; ANY-NEXT:    [[TMP2:%.*]] = fneg nnan afn float [[TMP1]]
143 ; ANY-NEXT:    ret float [[TMP2]]
145   %neg = fneg ninf float %x
146   %r = call afn nnan float @sinf(float %neg)
147   ret float %r
150 declare void @use(double)
152 define double @sin_negated_arg_extra_use(double %x) {
153 ; ANY-LABEL: @sin_negated_arg_extra_use(
154 ; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
155 ; ANY-NEXT:    [[R:%.*]] = call double @sin(double [[NEG]])
156 ; ANY-NEXT:    call void @use(double [[NEG]])
157 ; ANY-NEXT:    ret double [[R]]
159   %neg = fsub double -0.0, %x
160   %r = call double @sin(double %neg)
161   call void @use(double %neg)
162   ret double %r
165 define double @sin_unary_negated_arg_extra_use(double %x) {
166 ; ANY-LABEL: @sin_unary_negated_arg_extra_use(
167 ; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
168 ; ANY-NEXT:    [[R:%.*]] = call double @sin(double [[NEG]])
169 ; ANY-NEXT:    call void @use(double [[NEG]])
170 ; ANY-NEXT:    ret double [[R]]
172   %neg = fneg double %x
173   %r = call double @sin(double %neg)
174   call void @use(double %neg)
175   ret double %r
178 ; -sin(-x) --> sin(x)
179 ; PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458
181 define double @neg_sin_negated_arg(double %x) {
182 ; ANY-LABEL: @neg_sin_negated_arg(
183 ; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
184 ; ANY-NEXT:    ret double [[TMP1]]
186   %neg = fsub double -0.0, %x
187   %r = call double @sin(double %neg)
188   %rn = fsub double -0.0, %r
189   ret double %rn
192 define double @unary_neg_sin_unary_negated_arg(double %x) {
193 ; ANY-LABEL: @unary_neg_sin_unary_negated_arg(
194 ; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
195 ; ANY-NEXT:    ret double [[TMP1]]
197   %neg = fneg double %x
198   %r = call double @sin(double %neg)
199   %rn = fneg double %r
200   ret double %rn
203 define double @neg_sin_unary_negated_arg(double %x) {
204 ; ANY-LABEL: @neg_sin_unary_negated_arg(
205 ; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
206 ; ANY-NEXT:    ret double [[TMP1]]
208   %neg = fsub double -0.0, %x
209   %r = call double @sin(double %neg)
210   %rn = fneg double %r
211   ret double %rn
214 define double @unary_neg_sin_negated_arg(double %x) {
215 ; ANY-LABEL: @unary_neg_sin_negated_arg(
216 ; ANY-NEXT:    [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
217 ; ANY-NEXT:    ret double [[TMP1]]
219   %neg = fneg double %x
220   %r = call double @sin(double %neg)
221   %rn = fsub double -0.0, %r
222   ret double %rn
225 ; tan(-x) -> -tan(x);
227 define double @tan_negated_arg(double %x) {
228 ; ANY-LABEL: @tan_negated_arg(
229 ; ANY-NEXT:    [[TMP1:%.*]] = call double @tan(double [[X:%.*]])
230 ; ANY-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
231 ; ANY-NEXT:    ret double [[TMP2]]
233   %neg = fsub double -0.0, %x
234   %r = call double @tan(double %neg)
235   ret double %r
238 define double @tan_unary_negated_arg(double %x) {
239 ; ANY-LABEL: @tan_unary_negated_arg(
240 ; ANY-NEXT:    [[TMP1:%.*]] = call double @tan(double [[X:%.*]])
241 ; ANY-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
242 ; ANY-NEXT:    ret double [[TMP2]]
244   %neg = fneg double %x
245   %r = call double @tan(double %neg)
246   ret double %r
249 ; tanl(-x) -> -tanl(x);
251 define fp128 @tanl_negated_arg(fp128 %x) {
252 ; ANY-LABEL: @tanl_negated_arg(
253 ; ANY-NEXT:    [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])
254 ; ANY-NEXT:    [[TMP2:%.*]] = fneg fp128 [[TMP1]]
255 ; ANY-NEXT:    ret fp128 [[TMP2]]
257   %neg = fsub fp128 0xL00000000000000008000000000000000, %x
258   %r = call fp128 @tanl(fp128 %neg)
259   ret fp128 %r
262 define fp128 @tanl_unary_negated_arg(fp128 %x) {
263 ; ANY-LABEL: @tanl_unary_negated_arg(
264 ; ANY-NEXT:    [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])
265 ; ANY-NEXT:    [[TMP2:%.*]] = fneg fp128 [[TMP1]]
266 ; ANY-NEXT:    ret fp128 [[TMP2]]
268   %neg = fneg fp128 %x
269   %r = call fp128 @tanl(fp128 %neg)
270   ret fp128 %r
273 define float @negated_and_shrinkable_libcall(float %f) {
274 ; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(
275 ; NO-FLOAT-SHRINK-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
276 ; NO-FLOAT-SHRINK-NEXT:    [[COS1:%.*]] = call double @cos(double [[CONV1]])
277 ; NO-FLOAT-SHRINK-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS1]] to float
278 ; NO-FLOAT-SHRINK-NEXT:    ret float [[CONV2]]
280 ; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(
281 ; DO-FLOAT-SHRINK-NEXT:    [[COSF:%.*]] = call float @cosf(float [[F:%.*]])
282 ; DO-FLOAT-SHRINK-NEXT:    ret float [[COSF]]
284   %conv1 = fpext float %f to double
285   %neg = fsub double -0.0, %conv1
286   %cos = call double @cos(double %neg)
287   %conv2 = fptrunc double %cos to float
288   ret float %conv2
291 define float @unary_negated_and_shrinkable_libcall(float %f) {
292 ; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(
293 ; NO-FLOAT-SHRINK-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
294 ; NO-FLOAT-SHRINK-NEXT:    [[COS1:%.*]] = call double @cos(double [[CONV1]])
295 ; NO-FLOAT-SHRINK-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS1]] to float
296 ; NO-FLOAT-SHRINK-NEXT:    ret float [[CONV2]]
298 ; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(
299 ; DO-FLOAT-SHRINK-NEXT:    [[COSF:%.*]] = call float @cosf(float [[F:%.*]])
300 ; DO-FLOAT-SHRINK-NEXT:    ret float [[COSF]]
302   %conv1 = fpext float %f to double
303   %neg = fneg double %conv1
304   %cos = call double @cos(double %neg)
305   %conv2 = fptrunc double %cos to float
306   ret float %conv2
309 ; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?
311 define float @negated_and_shrinkable_intrinsic(float %f) {
312 ; ANY-LABEL: @negated_and_shrinkable_intrinsic(
313 ; ANY-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
314 ; ANY-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
315 ; ANY-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
316 ; ANY-NEXT:    ret float [[CONV2]]
318   %conv1 = fpext float %f to double
319   %neg = fsub double -0.0, %conv1
320   %cos = call double @llvm.cos.f64(double %neg)
321   %conv2 = fptrunc double %cos to float
322   ret float %conv2
325 define float @unary_negated_and_shrinkable_intrinsic(float %f) {
326 ; ANY-LABEL: @unary_negated_and_shrinkable_intrinsic(
327 ; ANY-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
328 ; ANY-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
329 ; ANY-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
330 ; ANY-NEXT:    ret float [[CONV2]]
332   %conv1 = fpext float %f to double
333   %neg = fneg double %conv1
334   %cos = call double @llvm.cos.f64(double %neg)
335   %conv2 = fptrunc double %cos to float
336   ret float %conv2