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)
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)
32 define double @cos_negated_arg_tail(double %x) {
33 ; ANY-LABEL: @cos_negated_arg_tail(
34 ; ANY-NEXT: [[COS:%.*]] = tail call double @cos(double [[X:%.*]])
35 ; ANY-NEXT: ret double [[COS]]
37 %neg = fsub double -0.0, %x
38 %r = tail call double @cos(double %neg)
42 define double @cos_negated_arg_musttail(double %x) {
43 ; ANY-LABEL: @cos_negated_arg_musttail(
44 ; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
45 ; ANY-NEXT: [[R:%.*]] = musttail call double @cos(double [[NEG]])
46 ; ANY-NEXT: ret double [[R]]
48 %neg = fsub double -0.0, %x
49 %r = musttail call double @cos(double %neg)
53 define double @cos_unary_negated_arg(double %x) {
54 ; ANY-LABEL: @cos_unary_negated_arg(
55 ; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])
56 ; ANY-NEXT: ret double [[COS]]
59 %r = call double @cos(double %neg)
63 define float @cosf_negated_arg(float %x) {
64 ; ANY-LABEL: @cosf_negated_arg(
65 ; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])
66 ; ANY-NEXT: ret float [[COS]]
68 %neg = fsub float -0.0, %x
69 %r = call float @cosf(float %neg)
73 define float @cosf_unary_negated_arg(float %x) {
74 ; ANY-LABEL: @cosf_unary_negated_arg(
75 ; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])
76 ; ANY-NEXT: ret float [[COS]]
79 %r = call float @cosf(float %neg)
83 define float @cosf_negated_arg_FMF(float %x) {
84 ; ANY-LABEL: @cosf_negated_arg_FMF(
85 ; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
86 ; ANY-NEXT: ret float [[COS]]
88 %neg = fsub float -0.0, %x
89 %r = call nnan reassoc float @cosf(float %neg)
93 define float @cosf_unary_negated_arg_FMF(float %x) {
94 ; ANY-LABEL: @cosf_unary_negated_arg_FMF(
95 ; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
96 ; ANY-NEXT: ret float [[COS]]
99 %r = call nnan reassoc float @cosf(float %neg)
103 ; sin(-x) -> -sin(x);
105 define double @sin_negated_arg(double %x) {
106 ; ANY-LABEL: @sin_negated_arg(
107 ; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
108 ; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]]
109 ; ANY-NEXT: ret double [[TMP2]]
111 %neg = fsub double -0.0, %x
112 %r = call double @sin(double %neg)
116 define double @sin_unary_negated_arg(double %x) {
117 ; ANY-LABEL: @sin_unary_negated_arg(
118 ; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
119 ; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]]
120 ; ANY-NEXT: ret double [[TMP2]]
122 %neg = fneg double %x
123 %r = call double @sin(double %neg)
127 define double @sin_unary_negated_arg_musttail(double %x) {
128 ; ANY-LABEL: @sin_unary_negated_arg_musttail(
129 ; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
130 ; ANY-NEXT: [[R:%.*]] = musttail call double @sin(double [[NEG]])
131 ; ANY-NEXT: ret double [[R]]
133 %neg = fneg double %x
134 %r = musttail call double @sin(double %neg)
138 define float @sinf_negated_arg(float %x) {
139 ; ANY-LABEL: @sinf_negated_arg(
140 ; ANY-NEXT: [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])
141 ; ANY-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]]
142 ; ANY-NEXT: ret float [[TMP2]]
144 %neg = fsub float -0.0, %x
145 %r = call float @sinf(float %neg)
149 define float @sinf_unary_negated_arg(float %x) {
150 ; ANY-LABEL: @sinf_unary_negated_arg(
151 ; ANY-NEXT: [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])
152 ; ANY-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]]
153 ; ANY-NEXT: ret float [[TMP2]]
156 %r = call float @sinf(float %neg)
160 define float @sinf_negated_arg_FMF(float %x) {
161 ; ANY-LABEL: @sinf_negated_arg_FMF(
162 ; ANY-NEXT: [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])
163 ; ANY-NEXT: [[TMP2:%.*]] = fneg nnan afn float [[TMP1]]
164 ; ANY-NEXT: ret float [[TMP2]]
166 %neg = fsub ninf float -0.0, %x
167 %r = call afn nnan float @sinf(float %neg)
171 define float @sinf_unary_negated_arg_FMF(float %x) {
172 ; ANY-LABEL: @sinf_unary_negated_arg_FMF(
173 ; ANY-NEXT: [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])
174 ; ANY-NEXT: [[TMP2:%.*]] = fneg nnan afn float [[TMP1]]
175 ; ANY-NEXT: ret float [[TMP2]]
177 %neg = fneg ninf float %x
178 %r = call afn nnan float @sinf(float %neg)
182 declare void @use(double)
184 define double @sin_negated_arg_extra_use(double %x) {
185 ; ANY-LABEL: @sin_negated_arg_extra_use(
186 ; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
187 ; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]])
188 ; ANY-NEXT: call void @use(double [[NEG]])
189 ; ANY-NEXT: ret double [[R]]
191 %neg = fsub double -0.0, %x
192 %r = call double @sin(double %neg)
193 call void @use(double %neg)
197 define double @sin_unary_negated_arg_extra_use(double %x) {
198 ; ANY-LABEL: @sin_unary_negated_arg_extra_use(
199 ; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
200 ; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]])
201 ; ANY-NEXT: call void @use(double [[NEG]])
202 ; ANY-NEXT: ret double [[R]]
204 %neg = fneg double %x
205 %r = call double @sin(double %neg)
206 call void @use(double %neg)
210 ; -sin(-x) --> sin(x)
211 ; PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458
213 define double @neg_sin_negated_arg(double %x) {
214 ; ANY-LABEL: @neg_sin_negated_arg(
215 ; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
216 ; ANY-NEXT: ret double [[TMP1]]
218 %neg = fsub double -0.0, %x
219 %r = call double @sin(double %neg)
220 %rn = fsub double -0.0, %r
224 define double @unary_neg_sin_unary_negated_arg(double %x) {
225 ; ANY-LABEL: @unary_neg_sin_unary_negated_arg(
226 ; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
227 ; ANY-NEXT: ret double [[TMP1]]
229 %neg = fneg double %x
230 %r = call double @sin(double %neg)
235 define double @neg_sin_unary_negated_arg(double %x) {
236 ; ANY-LABEL: @neg_sin_unary_negated_arg(
237 ; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
238 ; ANY-NEXT: ret double [[TMP1]]
240 %neg = fsub double -0.0, %x
241 %r = call double @sin(double %neg)
246 define double @unary_neg_sin_negated_arg(double %x) {
247 ; ANY-LABEL: @unary_neg_sin_negated_arg(
248 ; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])
249 ; ANY-NEXT: ret double [[TMP1]]
251 %neg = fneg double %x
252 %r = call double @sin(double %neg)
253 %rn = fsub double -0.0, %r
257 ; tan(-x) -> -tan(x);
259 define double @tan_negated_arg(double %x) {
260 ; ANY-LABEL: @tan_negated_arg(
261 ; ANY-NEXT: [[TMP1:%.*]] = call double @tan(double [[X:%.*]])
262 ; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]]
263 ; ANY-NEXT: ret double [[TMP2]]
265 %neg = fsub double -0.0, %x
266 %r = call double @tan(double %neg)
270 define double @tan_negated_arg_tail(double %x) {
271 ; ANY-LABEL: @tan_negated_arg_tail(
272 ; ANY-NEXT: [[TMP1:%.*]] = tail call double @tan(double [[X:%.*]])
273 ; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]]
274 ; ANY-NEXT: ret double [[TMP2]]
276 %neg = fsub double -0.0, %x
277 %r = tail call double @tan(double %neg)
280 define double @tan_negated_arg_musttail(double %x) {
281 ; ANY-LABEL: @tan_negated_arg_musttail(
282 ; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
283 ; ANY-NEXT: [[R:%.*]] = musttail call double @tan(double [[NEG]])
284 ; ANY-NEXT: ret double [[R]]
286 %neg = fsub double -0.0, %x
287 %r = musttail call double @tan(double %neg)
291 define double @tan_unary_negated_arg(double %x) {
292 ; ANY-LABEL: @tan_unary_negated_arg(
293 ; ANY-NEXT: [[TMP1:%.*]] = call double @tan(double [[X:%.*]])
294 ; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]]
295 ; ANY-NEXT: ret double [[TMP2]]
297 %neg = fneg double %x
298 %r = call double @tan(double %neg)
302 ; tanl(-x) -> -tanl(x);
304 define fp128 @tanl_negated_arg(fp128 %x) {
305 ; ANY-LABEL: @tanl_negated_arg(
306 ; ANY-NEXT: [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])
307 ; ANY-NEXT: [[TMP2:%.*]] = fneg fp128 [[TMP1]]
308 ; ANY-NEXT: ret fp128 [[TMP2]]
310 %neg = fsub fp128 0xL00000000000000008000000000000000, %x
311 %r = call fp128 @tanl(fp128 %neg)
315 define fp128 @tanl_unary_negated_arg(fp128 %x) {
316 ; ANY-LABEL: @tanl_unary_negated_arg(
317 ; ANY-NEXT: [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])
318 ; ANY-NEXT: [[TMP2:%.*]] = fneg fp128 [[TMP1]]
319 ; ANY-NEXT: ret fp128 [[TMP2]]
322 %r = call fp128 @tanl(fp128 %neg)
326 define float @negated_and_shrinkable_libcall(float %f) {
327 ; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(
328 ; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
329 ; NO-FLOAT-SHRINK-NEXT: [[COS1:%.*]] = call double @cos(double [[CONV1]])
330 ; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS1]] to float
331 ; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]
333 ; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(
334 ; DO-FLOAT-SHRINK-NEXT: [[COSF:%.*]] = call float @cosf(float [[F:%.*]])
335 ; DO-FLOAT-SHRINK-NEXT: ret float [[COSF]]
337 %conv1 = fpext float %f to double
338 %neg = fsub double -0.0, %conv1
339 %cos = call double @cos(double %neg)
340 %conv2 = fptrunc double %cos to float
344 define float @unary_negated_and_shrinkable_libcall(float %f) {
345 ; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(
346 ; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
347 ; NO-FLOAT-SHRINK-NEXT: [[COS1:%.*]] = call double @cos(double [[CONV1]])
348 ; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS1]] to float
349 ; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]
351 ; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(
352 ; DO-FLOAT-SHRINK-NEXT: [[COSF:%.*]] = call float @cosf(float [[F:%.*]])
353 ; DO-FLOAT-SHRINK-NEXT: ret float [[COSF]]
355 %conv1 = fpext float %f to double
356 %neg = fneg double %conv1
357 %cos = call double @cos(double %neg)
358 %conv2 = fptrunc double %cos to float
362 ; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?
364 define float @negated_and_shrinkable_intrinsic(float %f) {
365 ; ANY-LABEL: @negated_and_shrinkable_intrinsic(
366 ; ANY-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
367 ; ANY-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
368 ; ANY-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float
369 ; ANY-NEXT: ret float [[CONV2]]
371 %conv1 = fpext float %f to double
372 %neg = fsub double -0.0, %conv1
373 %cos = call double @llvm.cos.f64(double %neg)
374 %conv2 = fptrunc double %cos to float
378 define float @unary_negated_and_shrinkable_intrinsic(float %f) {
379 ; ANY-LABEL: @unary_negated_and_shrinkable_intrinsic(
380 ; ANY-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
381 ; ANY-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
382 ; ANY-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float
383 ; ANY-NEXT: ret float [[CONV2]]
385 %conv1 = fpext float %f to double
386 %neg = fneg double %conv1
387 %cos = call double @llvm.cos.f64(double %neg)
388 %conv2 = fptrunc double %cos to float