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
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 declare double @fabs(double)
21 declare double @llvm.fabs.f64(double)
22 declare float @fabsf(float)
23 declare float @llvm.fabs.f32(float)
25 declare double @llvm.copysign(double, double)
26 declare float @llvm.copysign.f32(float, float)
30 define 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]]
35 %neg = fsub double -0.0, %x
36 %r = call double @cos(double %neg)
40 define 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]]
45 %neg = fsub double -0.0, %x
46 %r = tail call double @cos(double %neg)
50 define 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]]
56 %neg = fsub double -0.0, %x
57 %r = musttail call double @cos(double %neg)
61 define 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]]
67 %r = call double @cos(double %neg)
71 define 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]]
76 %neg = fsub float -0.0, %x
77 %r = call float @cosf(float %neg)
81 define 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]]
87 %r = call float @cosf(float %neg)
91 define 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]]
96 %neg = fsub float -0.0, %x
97 %r = call nnan reassoc float @cosf(float %neg)
101 define 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]]
107 %r = call nnan reassoc float @cosf(float %neg)
111 ; cos(fabs(x)) -> cos(x)
113 define 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]]
118 %fabs = tail call double @llvm.fabs.f64(double %x)
119 %r = call double @cos(double %fabs)
123 define 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]]
128 %fabs = tail call float @llvm.fabs.f32(float %x)
129 %r = call float @cosf(float %fabs)
133 define 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]]
138 %fabs = tail call float @llvm.fabs.f32(float %x)
139 %r = call nnan reassoc float @cosf(float %fabs)
143 ; cos(copysign(x, y)) -> cos(x)
145 define 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]]
150 %copysign = tail call double @llvm.copysign(double %x, double %y)
151 %r = call double @cos(double %copysign)
156 define 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]]
161 %copysign = tail call float @llvm.copysign.f32(float %x, float 1.0)
162 %r = call float @cosf(float %copysign)
166 define 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]]
171 %copysign = tail call float @llvm.copysign.f32(float %x, float %y)
172 %r = call nnan reassoc float @cosf(float %copysign)
176 ; sin(-x) -> -sin(x);
178 define 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]]
184 %neg = fsub double -0.0, %x
185 %r = call double @sin(double %neg)
189 define 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]]
195 %neg = fneg double %x
196 %r = call double @sin(double %neg)
200 define 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]]
206 %neg = fneg double %x
207 %r = musttail call double @sin(double %neg)
211 define 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]]
217 %neg = fsub float -0.0, %x
218 %r = call float @sinf(float %neg)
222 define 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]]
229 %r = call float @sinf(float %neg)
233 define 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]]
239 %neg = fsub ninf float -0.0, %x
240 %r = call afn nnan float @sinf(float %neg)
244 define 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]]
250 %neg = fneg ninf float %x
251 %r = call afn nnan float @sinf(float %neg)
255 declare void @use(double)
257 define 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]]
264 %neg = fsub double -0.0, %x
265 %r = call double @sin(double %neg)
266 call void @use(double %neg)
270 define 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]]
277 %neg = fneg double %x
278 %r = call double @sin(double %neg)
279 call void @use(double %neg)
283 ; -sin(-x) --> sin(x)
284 ; PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458
286 define 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]]
291 %neg = fsub double -0.0, %x
292 %r = call double @sin(double %neg)
293 %rn = fsub double -0.0, %r
297 define 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]]
302 %neg = fneg double %x
303 %r = call double @sin(double %neg)
308 define 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]]
313 %neg = fsub double -0.0, %x
314 %r = call double @sin(double %neg)
319 define 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]]
324 %neg = fneg double %x
325 %r = call double @sin(double %neg)
326 %rn = fsub double -0.0, %r
330 ; tan(-x) -> -tan(x);
332 define 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]]
338 %neg = fsub double -0.0, %x
339 %r = call double @tan(double %neg)
343 define 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]]
349 %neg = fsub double -0.0, %x
350 %r = tail call double @tan(double %neg)
353 define 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]]
359 %neg = fsub double -0.0, %x
360 %r = musttail call double @tan(double %neg)
364 define 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]]
370 %neg = fneg double %x
371 %r = call double @tan(double %neg)
375 ; tanl(-x) -> -tanl(x);
377 define 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]]
383 %neg = fsub fp128 0xL00000000000000008000000000000000, %x
384 %r = call fp128 @tanl(fp128 %neg)
388 define 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]]
395 %r = call fp128 @tanl(fp128 %neg)
399 define 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]]
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]]
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
417 define 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]]
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]]
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
435 ; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?
437 define 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]]
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
451 define 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]]
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