1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -instsimplify | FileCheck %s
3
4declare double @func()
5
6define i1 @nnan_call() {
7; CHECK-LABEL: @nnan_call(
8; CHECK-NEXT:    [[OP:%.*]] = call nnan double @func()
9; CHECK-NEXT:    ret i1 true
10;
11  %op = call nnan double @func()
12  %tmp = fcmp ord double %op, %op
13  ret i1 %tmp
14}
15
16define i1 @nnan_fabs_src(double %arg) {
17; CHECK-LABEL: @nnan_fabs_src(
18; CHECK-NEXT:    ret i1 false
19;
20  %nnan = fadd nnan double %arg, 1.0
21  %op = call double @llvm.fabs.f64(double %nnan)
22  %tmp = fcmp uno double %op, %op
23  ret i1 %tmp
24}
25
26define i1 @nnan_canonicalize_src(double %arg) {
27; CHECK-LABEL: @nnan_canonicalize_src(
28; CHECK-NEXT:    ret i1 true
29;
30  %nnan = fadd nnan double %arg, 1.0
31  %op = call double @llvm.canonicalize.f64(double %nnan)
32  %tmp = fcmp ord double %op, %op
33  ret i1 %tmp
34}
35
36define i1 @nnan_copysign_src(double %arg0, double %arg1) {
37; CHECK-LABEL: @nnan_copysign_src(
38; CHECK-NEXT:    ret i1 false
39;
40  %nnan = fadd nnan double %arg0, 1.0
41  %op = call double @llvm.copysign.f64(double %nnan, double %arg1)
42  %tmp = fcmp uno double %op, %op
43  ret i1 %tmp
44}
45
46define i1 @fabs_sqrt_src(double %arg0, double %arg1) {
47; CHECK-LABEL: @fabs_sqrt_src(
48; CHECK-NEXT:    ret i1 true
49;
50  %nnan = fadd nnan double %arg0, 1.0
51  %fabs = call double @llvm.fabs.f64(double %nnan)
52  %op = call double @llvm.sqrt.f64(double %fabs)
53  %tmp = fcmp ord double %op, %op
54  ret i1 %tmp
55}
56
57define i1 @fabs_sqrt_src_maybe_nan(double %arg0, double %arg1) {
58; CHECK-LABEL: @fabs_sqrt_src_maybe_nan(
59; CHECK-NEXT:    [[FABS:%.*]] = call double @llvm.fabs.f64(double [[ARG0:%.*]])
60; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.sqrt.f64(double [[FABS]])
61; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
62; CHECK-NEXT:    ret i1 [[TMP]]
63;
64  %fabs = call double @llvm.fabs.f64(double %arg0)
65  %op = call double @llvm.sqrt.f64(double %fabs)
66  %tmp = fcmp uno double %op, %op
67  ret i1 %tmp
68}
69
70define i1 @exp_nnan_src(double %arg) {
71; CHECK-LABEL: @exp_nnan_src(
72; CHECK-NEXT:    ret i1 true
73;
74  %nnan = fadd nnan double %arg, 1.0
75  %op = call double @llvm.exp.f64(double %nnan)
76  %tmp = fcmp ord double %op, %op
77  ret i1 %tmp
78}
79
80define i1 @exp2_nnan_src(double %arg) {
81; CHECK-LABEL: @exp2_nnan_src(
82; CHECK-NEXT:    ret i1 false
83;
84  %nnan = fadd nnan double %arg, 1.0
85  %op = call double @llvm.exp2.f64(double %nnan)
86  %tmp = fcmp uno double %op, %op
87  ret i1 %tmp
88}
89
90define i1 @floor_nnan_src(double %arg) {
91; CHECK-LABEL: @floor_nnan_src(
92; CHECK-NEXT:    ret i1 true
93;
94  %nnan = fadd nnan double %arg, 1.0
95  %op = call double @llvm.floor.f64(double %nnan)
96  %tmp = fcmp ord double %op, %op
97  ret i1 %tmp
98}
99
100define i1 @ceil_nnan_src(double %arg) {
101; CHECK-LABEL: @ceil_nnan_src(
102; CHECK-NEXT:    ret i1 false
103;
104  %nnan = fadd nnan double %arg, 1.0
105  %op = call double @llvm.ceil.f64(double %nnan)
106  %tmp = fcmp uno double %op, %op
107  ret i1 %tmp
108}
109
110define i1 @trunc_nnan_src(double %arg) {
111; CHECK-LABEL: @trunc_nnan_src(
112; CHECK-NEXT:    ret i1 true
113;
114  %nnan = fadd nnan double %arg, 1.0
115  %op = call double @llvm.trunc.f64(double %nnan)
116  %tmp = fcmp ord double %op, %op
117  ret i1 %tmp
118}
119
120define i1 @rint_nnan_src(double %arg) {
121; CHECK-LABEL: @rint_nnan_src(
122; CHECK-NEXT:    ret i1 false
123;
124  %nnan = fadd nnan double %arg, 1.0
125  %op = call double @llvm.rint.f64(double %nnan)
126  %tmp = fcmp uno double %op, %op
127  ret i1 %tmp
128}
129
130define i1 @nearbyint_nnan_src(double %arg) {
131; CHECK-LABEL: @nearbyint_nnan_src(
132; CHECK-NEXT:    ret i1 true
133;
134  %nnan = fadd nnan double %arg, 1.0
135  %op = call double @llvm.nearbyint.f64(double %nnan)
136  %tmp = fcmp ord double %op, %op
137  ret i1 %tmp
138}
139
140define i1 @round_nnan_src(double %arg) {
141; CHECK-LABEL: @round_nnan_src(
142; CHECK-NEXT:    ret i1 false
143;
144  %nnan = fadd nnan double %arg, 1.0
145  %op = call double @llvm.round.f64(double %nnan)
146  %tmp = fcmp uno double %op, %op
147  ret i1 %tmp
148}
149
150define i1 @roundeven_nnan_src(double %arg) {
151; CHECK-LABEL: @roundeven_nnan_src(
152; CHECK-NEXT:    ret i1 false
153;
154  %nnan = fadd nnan double %arg, 1.0
155  %op = call double @llvm.roundeven.f64(double %nnan)
156  %tmp = fcmp uno double %op, %op
157  ret i1 %tmp
158}
159
160define i1 @known_nan_select(i1 %cond, double %arg0, double %arg1) {
161; CHECK-LABEL: @known_nan_select(
162; CHECK-NEXT:    ret i1 true
163;
164  %lhs = fadd nnan double %arg0, 1.0
165  %rhs = fadd nnan double %arg1, 2.0
166  %op = select i1 %cond, double %lhs, double %rhs
167  %tmp = fcmp ord double %op, %op
168  ret i1 %tmp
169}
170
171define i1 @nnan_ninf_known_nan_select(i1 %cond, double %arg0, double %arg1) {
172; CHECK-LABEL: @nnan_ninf_known_nan_select(
173; CHECK-NEXT:    ret i1 true
174;
175  %lhs = fadd nnan ninf double %arg0, 1.0
176  %rhs = fadd nnan ninf double %arg1, 2.0
177  %op = select i1 %cond, double %lhs, double %rhs
178  %mul = fmul double %op, 2.0
179  %tmp = fcmp ord double %mul, %mul
180  ret i1 %tmp
181}
182
183define i1 @select_maybe_nan_lhs(i1 %cond, double %lhs, double %arg1) {
184; CHECK-LABEL: @select_maybe_nan_lhs(
185; CHECK-NEXT:    [[RHS:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00
186; CHECK-NEXT:    [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS:%.*]], double [[RHS]]
187; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
188; CHECK-NEXT:    ret i1 [[TMP]]
189;
190  %rhs = fadd nnan double %arg1, 1.0
191  %op = select i1 %cond, double %lhs, double %rhs
192  %tmp = fcmp uno double %op, %op
193  ret i1 %tmp
194}
195
196define i1 @select_maybe_nan_rhs(i1 %cond, double %arg0, double %rhs) {
197; CHECK-LABEL: @select_maybe_nan_rhs(
198; CHECK-NEXT:    [[LHS:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
199; CHECK-NEXT:    [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS]], double [[RHS:%.*]]
200; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
201; CHECK-NEXT:    ret i1 [[TMP]]
202;
203  %lhs = fadd nnan double %arg0, 1.0
204  %op = select i1 %cond, double %lhs, double %rhs
205  %tmp = fcmp ord double %op, %op
206  ret i1 %tmp
207}
208
209define i1 @nnan_fadd(double %arg0, double %arg1) {
210; CHECK-LABEL: @nnan_fadd(
211; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
212; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
213; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[NNAN_ARG1]]
214; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
215; CHECK-NEXT:    ret i1 [[TMP]]
216;
217  %nnan.arg0 = fadd nnan double %arg0, 1.0
218  %nnan.arg1 = fadd nnan double %arg0, 2.0
219  %op = fadd double %nnan.arg0, %nnan.arg1
220  %tmp = fcmp uno double %op, %op
221  ret i1 %tmp
222}
223
224define i1 @nnan_fadd_maybe_nan_lhs(double %arg0, double %arg1) {
225; CHECK-LABEL: @nnan_fadd_maybe_nan_lhs(
226; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00
227; CHECK-NEXT:    [[OP:%.*]] = fadd double [[ARG0:%.*]], [[NNAN_ARG1]]
228; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
229; CHECK-NEXT:    ret i1 [[TMP]]
230;
231  %nnan.arg1 = fadd nnan double %arg1, 1.0
232  %op = fadd double %arg0, %nnan.arg1
233  %tmp = fcmp ord double %op, %op
234  ret i1 %tmp
235}
236
237define i1 @nnan_fadd_maybe_nan_rhs(double %arg0, double %arg1) {
238; CHECK-LABEL: @nnan_fadd_maybe_nan_rhs(
239; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
240; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[ARG1:%.*]]
241; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
242; CHECK-NEXT:    ret i1 [[TMP]]
243;
244  %nnan.arg0 = fadd nnan double %arg0, 1.0
245  %op = fadd double %nnan.arg0, %arg1
246  %tmp = fcmp uno double %op, %op
247  ret i1 %tmp
248}
249
250define i1 @nnan_fmul(double %arg0, double %arg1) {
251; CHECK-LABEL: @nnan_fmul(
252; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
253; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
254; CHECK-NEXT:    [[OP:%.*]] = fmul double [[NNAN_ARG0]], [[NNAN_ARG1]]
255; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
256; CHECK-NEXT:    ret i1 [[TMP]]
257;
258  %nnan.arg0 = fadd nnan double %arg0, 1.0
259  %nnan.arg1 = fadd nnan double %arg0, 2.0
260  %op = fmul double %nnan.arg0, %nnan.arg1
261  %tmp = fcmp ord double %op, %op
262  ret i1 %tmp
263}
264
265define i1 @nnan_fsub(double %arg0, double %arg1) {
266; CHECK-LABEL: @nnan_fsub(
267; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
268; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
269; CHECK-NEXT:    [[OP:%.*]] = fsub double [[NNAN_ARG0]], [[NNAN_ARG1]]
270; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
271; CHECK-NEXT:    ret i1 [[TMP]]
272;
273  %nnan.arg0 = fadd nnan double %arg0, 1.0
274  %nnan.arg1 = fadd nnan double %arg0, 2.0
275  %op = fsub double %nnan.arg0, %nnan.arg1
276  %tmp = fcmp uno double %op, %op
277  ret i1 %tmp
278}
279
280define i1 @nnan_binary_fneg() {
281; CHECK-LABEL: @nnan_binary_fneg(
282; CHECK-NEXT:    [[NNAN:%.*]] = call nnan double @func()
283; CHECK-NEXT:    ret i1 true
284;
285  %nnan = call nnan double @func()
286  %op = fsub double -0.0, %nnan
287  %tmp = fcmp ord double %op, %op
288  ret i1 %tmp
289}
290
291define i1 @nnan_unary_fneg() {
292; CHECK-LABEL: @nnan_unary_fneg(
293; CHECK-NEXT:    [[NNAN:%.*]] = call nnan double @func()
294; CHECK-NEXT:    [[OP:%.*]] = fneg double [[NNAN]]
295; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
296; CHECK-NEXT:    ret i1 [[TMP]]
297;
298  %nnan = call nnan double @func()
299  %op = fneg double %nnan
300  %tmp = fcmp ord double %op, %op
301  ret i1 %tmp
302}
303
304define i1 @sitofp(i32 %arg0) {
305; CHECK-LABEL: @sitofp(
306; CHECK-NEXT:    ret i1 false
307;
308  %op = sitofp i32 %arg0 to double
309  %tmp = fcmp uno double %op, %op
310  ret i1 %tmp
311}
312
313define i1 @uitofp(i32 %arg0) {
314; CHECK-LABEL: @uitofp(
315; CHECK-NEXT:    ret i1 true
316;
317  %op = uitofp i32 %arg0 to double
318  %tmp = fcmp ord double %op, %op
319  ret i1 %tmp
320}
321
322define i1 @uitofp_add(i32 %arg0) {
323; CHECK-LABEL: @uitofp_add(
324; CHECK-NEXT:    ret i1 true
325;
326  %op = uitofp i32 %arg0 to double
327  %add = fadd double %op, %op
328  %tmp = fcmp ord double %add, %add
329  ret i1 %tmp
330}
331
332define i1 @uitofp_add_big(i1024 %arg0) {
333; CHECK-LABEL: @uitofp_add_big(
334; CHECK-NEXT:    [[OP:%.*]] = uitofp i1024 [[ARG0:%.*]] to double
335; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[OP]], [[OP]]
336; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[ADD]], [[ADD]]
337; CHECK-NEXT:    ret i1 [[TMP]]
338;
339  %op = uitofp i1024 %arg0 to double
340  %add = fadd double %op, %op
341  %tmp = fcmp ord double %add, %add
342  ret i1 %tmp
343}
344
345define i1 @fpext(float %arg0) {
346; CHECK-LABEL: @fpext(
347; CHECK-NEXT:    ret i1 false
348;
349  %arg0.nnan = fadd nnan float %arg0, 1.0
350  %op = fpext float %arg0.nnan to double
351  %tmp = fcmp uno double %op, %op
352  ret i1 %tmp
353}
354
355define i1 @fpext_maybe_nan(float %arg0) {
356; CHECK-LABEL: @fpext_maybe_nan(
357; CHECK-NEXT:    [[OP:%.*]] = fpext float [[ARG0:%.*]] to double
358; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
359; CHECK-NEXT:    ret i1 [[TMP]]
360;
361  %op = fpext float %arg0 to double
362  %tmp = fcmp ord double %op, %op
363  ret i1 %tmp
364}
365
366define i1 @fptrunc(double %arg0) {
367; CHECK-LABEL: @fptrunc(
368; CHECK-NEXT:    ret i1 false
369;
370  %arg0.nnan = fadd nnan double %arg0, 1.0
371  %op = fptrunc double %arg0.nnan to float
372  %tmp = fcmp uno float %op, %op
373  ret i1 %tmp
374}
375
376define i1 @fptrunc_maybe_nan(double %arg0) {
377; CHECK-LABEL: @fptrunc_maybe_nan(
378; CHECK-NEXT:    [[OP:%.*]] = fptrunc double [[ARG0:%.*]] to float
379; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord float [[OP]], [[OP]]
380; CHECK-NEXT:    ret i1 [[TMP]]
381;
382  %op = fptrunc double %arg0 to float
383  %tmp = fcmp ord float %op, %op
384  ret i1 %tmp
385}
386
387define i1 @nnan_fdiv(double %arg0, double %arg1) {
388; CHECK-LABEL: @nnan_fdiv(
389; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
390; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
391; CHECK-NEXT:    [[OP:%.*]] = fdiv double [[NNAN_ARG0]], [[NNAN_ARG1]]
392; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
393; CHECK-NEXT:    ret i1 [[TMP]]
394;
395  %nnan.arg0 = fadd nnan double %arg0, 1.0
396  %nnan.arg1 = fadd nnan double %arg0, 2.0
397  %op = fdiv double %nnan.arg0, %nnan.arg1
398  %tmp = fcmp uno double %op, %op
399  ret i1 %tmp
400}
401
402define i1 @nnan_frem(double %arg0, double %arg1) {
403; CHECK-LABEL: @nnan_frem(
404; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
405; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
406; CHECK-NEXT:    [[OP:%.*]] = frem double [[NNAN_ARG0]], [[NNAN_ARG1]]
407; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
408; CHECK-NEXT:    ret i1 [[TMP]]
409;
410  %nnan.arg0 = fadd nnan double %arg0, 1.0
411  %nnan.arg1 = fadd nnan double %arg0, 2.0
412  %op = frem double %nnan.arg0, %nnan.arg1
413  %tmp = fcmp ord double %op, %op
414  ret i1 %tmp
415}
416
417declare double @llvm.sqrt.f64(double)
418declare double @llvm.fabs.f64(double)
419declare double @llvm.canonicalize.f64(double)
420declare double @llvm.copysign.f64(double, double)
421declare double @llvm.exp.f64(double)
422declare double @llvm.exp2.f64(double)
423declare double @llvm.floor.f64(double)
424declare double @llvm.ceil.f64(double)
425declare double @llvm.trunc.f64(double)
426declare double @llvm.rint.f64(double)
427declare double @llvm.nearbyint.f64(double)
428declare double @llvm.round.f64(double)
429declare double @llvm.roundeven.f64(double)
430