• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -S -instcombine < %s | FileCheck %s
2target 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"
3target triple = "x86_64-apple-macosx10.8.0"
4
5define i1 @test1(float %x, float %y) {
6; CHECK-LABEL: @test1(
7; CHECK-NEXT:    [[CEIL:%.*]] = call float @llvm.ceil.f32(float %x)
8; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[CEIL]], %y
9; CHECK-NEXT:    ret i1 [[CMP]]
10;
11  %x.ext = fpext float %x to double
12  %ceil = call double @ceil(double %x.ext) nounwind readnone
13  %ext.y = fpext float %y to double
14  %cmp = fcmp oeq double %ceil, %ext.y
15  ret i1 %cmp
16}
17
18define i1 @test1_intrin(float %x, float %y) {
19; CHECK-LABEL: @test1_intrin(
20; CHECK-NEXT:    [[CEIL:%.*]] = call float @llvm.ceil.f32(float %x)
21; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[CEIL]], %y
22; CHECK-NEXT:    ret i1 [[CMP]]
23;
24  %x.ext = fpext float %x to double
25  %ceil = call double @llvm.ceil.f64(double %x.ext) nounwind readnone
26  %ext.y = fpext float %y to double
27  %cmp = fcmp oeq double %ceil, %ext.y
28  ret i1 %cmp
29}
30
31define i1 @test2(float %x, float %y) {
32; CHECK-LABEL: @test2(
33; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float %x)
34; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FABS]], %y
35; CHECK-NEXT:    ret i1 [[CMP]]
36;
37  %x.ext = fpext float %x to double
38  %fabs = call double @fabs(double %x.ext) nounwind readnone
39  %y.ext = fpext float %y to double
40  %cmp = fcmp oeq double %fabs, %y.ext
41  ret i1 %cmp
42}
43
44define i1 @test2_intrin(float %x, float %y) {
45; CHECK-LABEL: @test2_intrin(
46; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float %x)
47; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FABS]], %y
48; CHECK-NEXT:    ret i1 [[CMP]]
49;
50  %x.ext = fpext float %x to double
51  %fabs = call double @llvm.fabs.f64(double %x.ext) nounwind readnone
52  %y.ext = fpext float %y to double
53  %cmp = fcmp oeq double %fabs, %y.ext
54  ret i1 %cmp
55}
56
57define i1 @fmf_test2(float %x, float %y) {
58; CHECK-LABEL: @fmf_test2(
59; CHECK-NEXT:    [[TMP1:%.*]] = call nnan float @llvm.fabs.f32(float %x)
60; CHECK-NEXT:    [[TMP2:%.*]] = fcmp oeq float [[TMP1]], %y
61; CHECK-NEXT:    ret i1 [[TMP2]]
62;
63  %1 = fpext float %x to double
64  %2 = call nnan double @fabs(double %1) nounwind readnone
65  %3 = fpext float %y to double
66  %4 = fcmp oeq double %2, %3
67  ret i1 %4
68}
69
70define i1 @test3(float %x, float %y) {
71; CHECK-LABEL: @test3(
72; CHECK-NEXT:    [[FLOOR:%.*]] = call float @llvm.floor.f32(float %x)
73; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FLOOR]], %y
74; CHECK-NEXT:    ret i1 [[CMP]]
75;
76  %x.ext = fpext float %x to double
77  %floor = call double @floor(double %x.ext) nounwind readnone
78  %y.ext = fpext float %y to double
79  %cmp = fcmp oeq double %floor, %y.ext
80  ret i1 %cmp
81}
82
83
84define i1 @test3_intrin(float %x, float %y) {
85; CHECK-LABEL: @test3_intrin(
86; CHECK-NEXT:    [[FLOOR:%.*]] = call float @llvm.floor.f32(float %x)
87; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FLOOR]], %y
88; CHECK-NEXT:    ret i1 [[CMP]]
89;
90  %x.ext = fpext float %x to double
91  %floor = call double @llvm.floor.f64(double %x.ext) nounwind readnone
92  %y.ext = fpext float %y to double
93  %cmp = fcmp oeq double %floor, %y.ext
94  ret i1 %cmp
95}
96
97define i1 @test4(float %x, float %y) {
98; CHECK-LABEL: @test4(
99; CHECK-NEXT:    [[NEARBYINT:%.*]] = call float @llvm.nearbyint.f32(float %x)
100; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[NEARBYINT]], %y
101; CHECK-NEXT:    ret i1 [[CMP]]
102;
103  %x.ext = fpext float %x to double
104  %nearbyint = call double @nearbyint(double %x.ext) nounwind
105  %y.ext = fpext float %y to double
106  %cmp = fcmp oeq double %nearbyint, %y.ext
107  ret i1 %cmp
108}
109
110define i1 @shrink_nearbyint_intrin(float %x, float %y) {
111; CHECK-LABEL: @shrink_nearbyint_intrin(
112; CHECK-NEXT:    [[NEARBYINT:%.*]] = call float @llvm.nearbyint.f32(float %x)
113; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[NEARBYINT]], %y
114; CHECK-NEXT:    ret i1 [[CMP]]
115;
116  %x.ext = fpext float %x to double
117  %nearbyint = call double @llvm.nearbyint.f64(double %x.ext) nounwind
118  %y.ext = fpext float %y to double
119  %cmp = fcmp oeq double %nearbyint, %y.ext
120  ret i1 %cmp
121}
122
123define i1 @test5(float %x, float %y) {
124; CHECK-LABEL: @test5(
125; CHECK-NEXT:    [[RINT:%.*]] = call float @llvm.rint.f32(float %x)
126; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[RINT]], %y
127; CHECK-NEXT:    ret i1 [[CMP]]
128;
129  %x.ext = fpext float %x to double
130  %rint = call double @rint(double %x.ext) nounwind
131  %y.ext = fpext float %y to double
132  %cmp = fcmp oeq double %rint, %y.ext
133  ret i1 %cmp
134}
135
136define i1 @test6(float %x, float %y) {
137; CHECK-LABEL: @test6(
138; CHECK-NEXT:    [[ROUND:%.*]] = call float @llvm.round.f32(float %x)
139; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ROUND]], %y
140; CHECK-NEXT:    ret i1 [[CMP]]
141;
142  %x.ext = fpext float %x to double
143  %round = call double @round(double %x.ext) nounwind readnone
144  %y.ext = fpext float %y to double
145  %cmp = fcmp oeq double %round, %y.ext
146  ret i1 %cmp
147}
148
149define i1 @test6_intrin(float %x, float %y) {
150; CHECK-LABEL: @test6_intrin(
151; CHECK-NEXT:    [[ROUND:%.*]] = call float @llvm.round.f32(float %x)
152; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ROUND]], %y
153; CHECK-NEXT:    ret i1 [[CMP]]
154;
155  %x.ext = fpext float %x to double
156  %round = call double @llvm.round.f64(double %x.ext) nounwind readnone
157  %y.ext = fpext float %y to double
158  %cmp = fcmp oeq double %round, %y.ext
159  ret i1 %cmp
160}
161
162define i1 @test7(float %x, float %y) {
163; CHECK-LABEL: @test7(
164; CHECK-NEXT:    [[TRUNC:%.*]] = call float @llvm.trunc.f32(float %x)
165; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[TRUNC]], %y
166; CHECK-NEXT:    ret i1 [[CMP]]
167;
168  %x.ext = fpext float %x to double
169  %trunc = call double @trunc(double %x.ext) nounwind
170  %y.ext = fpext float %y to double
171  %cmp = fcmp oeq double %trunc, %y.ext
172  ret i1 %cmp
173}
174
175define i1 @test7_intrin(float %x, float %y) {
176; CHECK-LABEL: @test7_intrin(
177; CHECK-NEXT:    [[TRUNC:%.*]] = call float @llvm.trunc.f32(float %x)
178; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[TRUNC]], %y
179; CHECK-NEXT:    ret i1 [[CMP]]
180;
181  %x.ext = fpext float %x to double
182  %trunc = call double @llvm.trunc.f64(double %x.ext) nounwind
183  %y.ext = fpext float %y to double
184  %cmp = fcmp oeq double %trunc, %y.ext
185  ret i1 %cmp
186}
187
188define i1 @test8(float %x, float %y) {
189; CHECK-LABEL: @test8(
190; CHECK-NEXT:    [[CEIL:%.*]] = call float @llvm.ceil.f32(float %x)
191; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[CEIL]], %y
192; CHECK-NEXT:    ret i1 [[CMP]]
193;
194  %x.ext = fpext float %x to double
195  %y.ext = fpext float %y to double
196  %ceil = call double @ceil(double %x.ext) nounwind readnone
197  %cmp = fcmp oeq double %y.ext, %ceil
198  ret i1 %cmp
199}
200
201define i1 @test8_intrin(float %x, float %y) {
202; CHECK-LABEL: @test8_intrin(
203; CHECK-NEXT:    [[CEIL:%.*]] = call float @llvm.ceil.f32(float %x)
204; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[CEIL]], %y
205; CHECK-NEXT:    ret i1 [[CMP]]
206;
207  %x.ext = fpext float %x to double
208  %y.ext = fpext float %y to double
209  %ceil = call double @llvm.ceil.f64(double %x.ext) nounwind readnone
210  %cmp = fcmp oeq double %y.ext, %ceil
211  ret i1 %cmp
212}
213
214define i1 @test9(float %x, float %y) {
215; CHECK-LABEL: @test9(
216; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float %x)
217; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FABS]], %y
218; CHECK-NEXT:    ret i1 [[CMP]]
219;
220  %x.ext = fpext float %x to double
221  %y.ext = fpext float %y to double
222  %fabs = call double @fabs(double %x.ext) nounwind readnone
223  %cmp = fcmp oeq double %y.ext, %fabs
224  ret i1 %cmp
225}
226
227define i1 @test9_intrin(float %x, float %y) {
228; CHECK-LABEL: @test9_intrin(
229; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float %x)
230; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FABS]], %y
231; CHECK-NEXT:    ret i1 [[CMP]]
232;
233  %x.ext = fpext float %x to double
234  %y.ext = fpext float %y to double
235  %fabs = call double @llvm.fabs.f64(double %x.ext) nounwind readnone
236  %cmp = fcmp oeq double %y.ext, %fabs
237  ret i1 %cmp
238}
239
240define i1 @test10(float %x, float %y) {
241; CHECK-LABEL: @test10(
242; CHECK-NEXT:    [[FLOOR:%.*]] = call float @llvm.floor.f32(float %x)
243; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FLOOR]], %y
244; CHECK-NEXT:    ret i1 [[CMP]]
245;
246  %x.ext = fpext float %x to double
247  %y.ext = fpext float %y to double
248  %floor = call double @floor(double %x.ext) nounwind readnone
249  %cmp = fcmp oeq double %floor, %y.ext
250  ret i1 %cmp
251}
252
253define i1 @test10_intrin(float %x, float %y) {
254; CHECK-LABEL: @test10_intrin(
255; CHECK-NEXT:    [[FLOOR:%.*]] = call float @llvm.floor.f32(float %x)
256; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FLOOR]], %y
257; CHECK-NEXT:    ret i1 [[CMP]]
258;
259  %x.ext = fpext float %x to double
260  %y.ext = fpext float %y to double
261  %floor = call double @llvm.floor.f64(double %x.ext) nounwind readnone
262  %cmp = fcmp oeq double %floor, %y.ext
263  ret i1 %cmp
264}
265
266define i1 @test11(float %x, float %y) {
267; CHECK-LABEL: @test11(
268; CHECK-NEXT:    [[NEARBYINT:%.*]] = call float @llvm.nearbyint.f32(float %x)
269; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[NEARBYINT]], %y
270; CHECK-NEXT:    ret i1 [[CMP]]
271;
272  %x.ext = fpext float %x to double
273  %y.ext = fpext float %y to double
274  %nearbyint = call double @nearbyint(double %x.ext) nounwind
275  %cmp = fcmp oeq double %nearbyint, %y.ext
276  ret i1 %cmp
277}
278
279define i1 @test11_intrin(float %x, float %y) {
280; CHECK-LABEL: @test11_intrin(
281; CHECK-NEXT:    [[NEARBYINT:%.*]] = call float @llvm.nearbyint.f32(float %x)
282; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[NEARBYINT]], %y
283; CHECK-NEXT:    ret i1 [[CMP]]
284;
285  %x.ext = fpext float %x to double
286  %y.ext = fpext float %y to double
287  %nearbyint = call double @llvm.nearbyint.f64(double %x.ext) nounwind
288  %cmp = fcmp oeq double %nearbyint, %y.ext
289  ret i1 %cmp
290}
291
292define i1 @test12(float %x, float %y) {
293; CHECK-LABEL: @test12(
294; CHECK-NEXT:    [[RINT:%.*]] = call float @llvm.rint.f32(float %x)
295; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[RINT]], %y
296; CHECK-NEXT:    ret i1 [[CMP]]
297;
298  %x.ext = fpext float %x to double
299  %y.ext = fpext float %y to double
300  %rint = call double @rint(double %x.ext) nounwind
301  %cmp = fcmp oeq double %y.ext, %rint
302  ret i1 %cmp
303}
304
305define i1 @test13(float %x, float %y) {
306; CHECK-LABEL: @test13(
307; CHECK-NEXT:    [[ROUND:%.*]] = call float @llvm.round.f32(float %x)
308; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ROUND]], %y
309; CHECK-NEXT:    ret i1 [[CMP]]
310;
311  %x.ext = fpext float %x to double
312  %y.ext = fpext float %y to double
313  %round = call double @round(double %x.ext) nounwind readnone
314  %cmp = fcmp oeq double %y.ext, %round
315  ret i1 %cmp
316}
317
318define i1 @test13_intrin(float %x, float %y) {
319; CHECK-LABEL: @test13_intrin(
320; CHECK-NEXT:    [[ROUND:%.*]] = call float @llvm.round.f32(float %x)
321; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ROUND]], %y
322; CHECK-NEXT:    ret i1 [[CMP]]
323;
324  %x.ext = fpext float %x to double
325  %y.ext = fpext float %y to double
326  %round = call double @llvm.round.f64(double %x.ext) nounwind readnone
327  %cmp = fcmp oeq double %y.ext, %round
328  ret i1 %cmp
329}
330
331define i1 @test14(float %x, float %y) {
332; CHECK-LABEL: @test14(
333; CHECK-NEXT:    [[TRUNC:%.*]] = call float @llvm.trunc.f32(float %x)
334; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[TRUNC]], %y
335; CHECK-NEXT:    ret i1 [[CMP]]
336;
337  %x.ext = fpext float %x to double
338  %y.ext = fpext float %y to double
339  %trunc = call double @trunc(double %x.ext) nounwind
340  %cmp = fcmp oeq double %y.ext, %trunc
341  ret i1 %cmp
342}
343
344define i1 @test14_intrin(float %x, float %y) {
345; CHECK-LABEL: @test14_intrin(
346; CHECK-NEXT:    [[TRUNC:%.*]] = call float @llvm.trunc.f32(float %x)
347; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[TRUNC]], %y
348; CHECK-NEXT:    ret i1 [[CMP]]
349;
350  %x.ext = fpext float %x to double
351  %y.ext = fpext float %y to double
352  %trunc = call double @llvm.trunc.f64(double %x.ext) nounwind
353  %cmp = fcmp oeq double %y.ext, %trunc
354  ret i1 %cmp
355}
356
357define i1 @test15(float %x, float %y, float %z) {
358; CHECK-LABEL: @test15(
359; CHECK-NEXT:    [[FMINF:%.*]] = call float @fminf(float %x, float %y) #0
360; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq float [[FMINF]], %z
361; CHECK-NEXT:    ret i1 [[TMP1]]
362;
363  %1 = fpext float %x to double
364  %2 = fpext float %y to double
365  %3 = call double @fmin(double %1, double %2) nounwind
366  %4 = fpext float %z to double
367  %5 = fcmp oeq double %3, %4
368  ret i1 %5
369}
370
371define i1 @test16(float %x, float %y, float %z) {
372; CHECK-LABEL: @test16(
373; CHECK-NEXT:    [[FMINF:%.*]] = call float @fminf(float %x, float %y) #0
374; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq float [[FMINF]], %z
375; CHECK-NEXT:    ret i1 [[TMP1]]
376;
377  %1 = fpext float %z to double
378  %2 = fpext float %x to double
379  %3 = fpext float %y to double
380  %4 = call double @fmin(double %2, double %3) nounwind
381  %5 = fcmp oeq double %1, %4
382  ret i1 %5
383}
384
385define i1 @test17(float %x, float %y, float %z) {
386; CHECK-LABEL: @test17(
387; CHECK-NEXT:    [[FMAXF:%.*]] = call float @fmaxf(float %x, float %y) #0
388; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq float [[FMAXF]], %z
389; CHECK-NEXT:    ret i1 [[TMP1]]
390;
391  %1 = fpext float %x to double
392  %2 = fpext float %y to double
393  %3 = call double @fmax(double %1, double %2) nounwind
394  %4 = fpext float %z to double
395  %5 = fcmp oeq double %3, %4
396  ret i1 %5
397}
398
399define i1 @test18(float %x, float %y, float %z) {
400; CHECK-LABEL: @test18(
401; CHECK-NEXT:    [[FMAXF:%.*]] = call float @fmaxf(float %x, float %y) #0
402; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq float [[FMAXF]], %z
403; CHECK-NEXT:    ret i1 [[TMP1]]
404;
405  %1 = fpext float %z to double
406  %2 = fpext float %x to double
407  %3 = fpext float %y to double
408  %4 = call double @fmax(double %2, double %3) nounwind
409  %5 = fcmp oeq double %1, %4
410  ret i1 %5
411}
412
413define i1 @test19(float %x, float %y, float %z) {
414; CHECK-LABEL: @test19(
415; CHECK-NEXT:    [[COPYSIGNF:%.*]] = call float @copysignf(float %x, float %y) #0
416; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq float [[COPYSIGNF]], %z
417; CHECK-NEXT:    ret i1 [[TMP1]]
418;
419  %1 = fpext float %x to double
420  %2 = fpext float %y to double
421  %3 = call double @copysign(double %1, double %2) nounwind
422  %4 = fpext float %z to double
423  %5 = fcmp oeq double %3, %4
424  ret i1 %5
425}
426
427define i1 @test20(float %x, float %y) {
428; CHECK-LABEL: @test20(
429; CHECK-NEXT:    [[FMINF:%.*]] = call float @fminf(float 1.000000e+00, float %x) #0
430; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq float [[FMINF]], %y
431; CHECK-NEXT:    ret i1 [[TMP1]]
432;
433  %1 = fpext float %y to double
434  %2 = fpext float %x to double
435  %3 = call double @fmin(double 1.000000e+00, double %2) nounwind
436  %4 = fcmp oeq double %1, %3
437  ret i1 %4
438}
439
440; should not be changed to fminf as the constant would lose precision
441
442define i1 @test21(float %x, float %y) {
443; CHECK-LABEL: @test21(
444; CHECK-NEXT:    [[TMP1:%.*]] = fpext float %y to double
445; CHECK-NEXT:    [[TMP2:%.*]] = fpext float %x to double
446; CHECK-NEXT:    [[TMP3:%.*]] = call double @fmin(double 1.300000e+00, double [[TMP2]]) #2
447; CHECK-NEXT:    [[TMP4:%.*]] = fcmp oeq double [[TMP3]], [[TMP1]]
448; CHECK-NEXT:    ret i1 [[TMP4]]
449;
450  %1 = fpext float %y to double
451  %2 = fpext float %x to double
452  %3 = call double @fmin(double 1.300000e+00, double %2) nounwind
453  %4 = fcmp oeq double %1, %3
454  ret i1 %4
455}
456
457declare double @fabs(double) nounwind readnone
458declare double @ceil(double) nounwind readnone
459declare double @copysign(double, double) nounwind readnone
460declare double @floor(double) nounwind readnone
461declare double @nearbyint(double) nounwind readnone
462declare double @rint(double) nounwind readnone
463declare double @round(double) nounwind readnone
464declare double @trunc(double) nounwind readnone
465declare double @fmin(double, double) nounwind readnone
466declare double @fmax(double, double) nounwind readnone
467
468declare double @llvm.fabs.f64(double) nounwind readnone
469declare double @llvm.ceil.f64(double) nounwind readnone
470declare double @llvm.floor.f64(double) nounwind readnone
471declare double @llvm.nearbyint.f64(double) nounwind readnone
472declare double @llvm.round.f64(double) nounwind readnone
473declare double @llvm.trunc.f64(double) nounwind readnone
474