[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstSimplify / known-never-nan.ll
blob37cfc932aa43a920dca7c08da1261640f352fcc4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -instsimplify | FileCheck %s
4 declare double @func()
6 define i1 @nnan_call() {
7 ; CHECK-LABEL: @nnan_call(
8 ; CHECK-NEXT:    [[OP:%.*]] = call nnan double @func()
9 ; CHECK-NEXT:    ret i1 true
11   %op = call nnan double @func()
12   %tmp = fcmp ord double %op, %op
13   ret i1 %tmp
16 define i1 @nnan_fabs_src(double %arg) {
17 ; CHECK-LABEL: @nnan_fabs_src(
18 ; CHECK-NEXT:    ret i1 false
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
26 define i1 @nnan_canonicalize_src(double %arg) {
27 ; CHECK-LABEL: @nnan_canonicalize_src(
28 ; CHECK-NEXT:    ret i1 true
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
36 define i1 @nnan_copysign_src(double %arg0, double %arg1) {
37 ; CHECK-LABEL: @nnan_copysign_src(
38 ; CHECK-NEXT:    ret i1 false
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
46 define i1 @fabs_sqrt_src(double %arg0, double %arg1) {
47 ; CHECK-LABEL: @fabs_sqrt_src(
48 ; CHECK-NEXT:    ret i1 true
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
57 define 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]]
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
70 define i1 @exp_nnan_src(double %arg) {
71 ; CHECK-LABEL: @exp_nnan_src(
72 ; CHECK-NEXT:    ret i1 true
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
80 define i1 @exp2_nnan_src(double %arg) {
81 ; CHECK-LABEL: @exp2_nnan_src(
82 ; CHECK-NEXT:    ret i1 false
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
90 define i1 @floor_nnan_src(double %arg) {
91 ; CHECK-LABEL: @floor_nnan_src(
92 ; CHECK-NEXT:    ret i1 true
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
100 define i1 @ceil_nnan_src(double %arg) {
101 ; CHECK-LABEL: @ceil_nnan_src(
102 ; CHECK-NEXT:    ret i1 false
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
110 define i1 @trunc_nnan_src(double %arg) {
111 ; CHECK-LABEL: @trunc_nnan_src(
112 ; CHECK-NEXT:    ret i1 true
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
120 define i1 @rint_nnan_src(double %arg) {
121 ; CHECK-LABEL: @rint_nnan_src(
122 ; CHECK-NEXT:    ret i1 false
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
130 define i1 @nearbyint_nnan_src(double %arg) {
131 ; CHECK-LABEL: @nearbyint_nnan_src(
132 ; CHECK-NEXT:    ret i1 true
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
140 define i1 @round_nnan_src(double %arg) {
141 ; CHECK-LABEL: @round_nnan_src(
142 ; CHECK-NEXT:    ret i1 false
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
150 define i1 @known_nan_select(i1 %cond, double %arg0, double %arg1) {
151 ; CHECK-LABEL: @known_nan_select(
152 ; CHECK-NEXT:    ret i1 true
154   %lhs = fadd nnan double %arg0, 1.0
155   %rhs = fadd nnan double %arg1, 2.0
156   %op = select i1 %cond, double %lhs, double %rhs
157   %tmp = fcmp ord double %op, %op
158   ret i1 %tmp
161 define i1 @select_maybe_nan_lhs(i1 %cond, double %lhs, double %arg1) {
162 ; CHECK-LABEL: @select_maybe_nan_lhs(
163 ; CHECK-NEXT:    [[RHS:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00
164 ; CHECK-NEXT:    [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS:%.*]], double [[RHS]]
165 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
166 ; CHECK-NEXT:    ret i1 [[TMP]]
168   %rhs = fadd nnan double %arg1, 1.0
169   %op = select i1 %cond, double %lhs, double %rhs
170   %tmp = fcmp uno double %op, %op
171   ret i1 %tmp
174 define i1 @select_maybe_nan_rhs(i1 %cond, double %arg0, double %rhs) {
175 ; CHECK-LABEL: @select_maybe_nan_rhs(
176 ; CHECK-NEXT:    [[LHS:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
177 ; CHECK-NEXT:    [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS]], double [[RHS:%.*]]
178 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
179 ; CHECK-NEXT:    ret i1 [[TMP]]
181   %lhs = fadd nnan double %arg0, 1.0
182   %op = select i1 %cond, double %lhs, double %rhs
183   %tmp = fcmp ord double %op, %op
184   ret i1 %tmp
187 define i1 @nnan_fadd(double %arg0, double %arg1) {
188 ; CHECK-LABEL: @nnan_fadd(
189 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
190 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
191 ; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[NNAN_ARG1]]
192 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
193 ; CHECK-NEXT:    ret i1 [[TMP]]
195   %nnan.arg0 = fadd nnan double %arg0, 1.0
196   %nnan.arg1 = fadd nnan double %arg0, 2.0
197   %op = fadd double %nnan.arg0, %nnan.arg1
198   %tmp = fcmp uno double %op, %op
199   ret i1 %tmp
202 define i1 @nnan_fadd_maybe_nan_lhs(double %arg0, double %arg1) {
203 ; CHECK-LABEL: @nnan_fadd_maybe_nan_lhs(
204 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00
205 ; CHECK-NEXT:    [[OP:%.*]] = fadd double [[ARG0:%.*]], [[NNAN_ARG1]]
206 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
207 ; CHECK-NEXT:    ret i1 [[TMP]]
209   %nnan.arg1 = fadd nnan double %arg1, 1.0
210   %op = fadd double %arg0, %nnan.arg1
211   %tmp = fcmp ord double %op, %op
212   ret i1 %tmp
215 define i1 @nnan_fadd_maybe_nan_rhs(double %arg0, double %arg1) {
216 ; CHECK-LABEL: @nnan_fadd_maybe_nan_rhs(
217 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
218 ; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[ARG1:%.*]]
219 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
220 ; CHECK-NEXT:    ret i1 [[TMP]]
222   %nnan.arg0 = fadd nnan double %arg0, 1.0
223   %op = fadd double %nnan.arg0, %arg1
224   %tmp = fcmp uno double %op, %op
225   ret i1 %tmp
228 define i1 @nnan_fmul(double %arg0, double %arg1) {
229 ; CHECK-LABEL: @nnan_fmul(
230 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
231 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
232 ; CHECK-NEXT:    [[OP:%.*]] = fmul double [[NNAN_ARG0]], [[NNAN_ARG1]]
233 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
234 ; CHECK-NEXT:    ret i1 [[TMP]]
236   %nnan.arg0 = fadd nnan double %arg0, 1.0
237   %nnan.arg1 = fadd nnan double %arg0, 2.0
238   %op = fmul double %nnan.arg0, %nnan.arg1
239   %tmp = fcmp ord double %op, %op
240   ret i1 %tmp
243 define i1 @nnan_fsub(double %arg0, double %arg1) {
244 ; CHECK-LABEL: @nnan_fsub(
245 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
246 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
247 ; CHECK-NEXT:    [[OP:%.*]] = fsub double [[NNAN_ARG0]], [[NNAN_ARG1]]
248 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
249 ; CHECK-NEXT:    ret i1 [[TMP]]
251   %nnan.arg0 = fadd nnan double %arg0, 1.0
252   %nnan.arg1 = fadd nnan double %arg0, 2.0
253   %op = fsub double %nnan.arg0, %nnan.arg1
254   %tmp = fcmp uno double %op, %op
255   ret i1 %tmp
258 define i1 @nnan_binary_fneg() {
259 ; CHECK-LABEL: @nnan_binary_fneg(
260 ; CHECK-NEXT:    [[NNAN:%.*]] = call nnan double @func()
261 ; CHECK-NEXT:    [[OP:%.*]] = fsub double -0.000000e+00, [[NNAN]]
262 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
263 ; CHECK-NEXT:    ret i1 [[TMP]]
265   %nnan = call nnan double @func()
266   %op = fsub double -0.0, %nnan
267   %tmp = fcmp ord double %op, %op
268   ret i1 %tmp
271 define i1 @nnan_unary_fneg() {
272 ; CHECK-LABEL: @nnan_unary_fneg(
273 ; CHECK-NEXT:    [[NNAN:%.*]] = call nnan double @func()
274 ; CHECK-NEXT:    [[OP:%.*]] = fneg double [[NNAN]]
275 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
276 ; CHECK-NEXT:    ret i1 [[TMP]]
278   %nnan = call nnan double @func()
279   %op = fneg double %nnan
280   %tmp = fcmp ord double %op, %op
281   ret i1 %tmp
284 define i1 @sitofp(i32 %arg0) {
285 ; CHECK-LABEL: @sitofp(
286 ; CHECK-NEXT:    ret i1 false
288   %op = sitofp i32 %arg0 to double
289   %tmp = fcmp uno double %op, %op
290   ret i1 %tmp
293 define i1 @uitofp(i32 %arg0) {
294 ; CHECK-LABEL: @uitofp(
295 ; CHECK-NEXT:    ret i1 true
297   %op = uitofp i32 %arg0 to double
298   %tmp = fcmp ord double %op, %op
299   ret i1 %tmp
302 define i1 @fpext(float %arg0) {
303 ; CHECK-LABEL: @fpext(
304 ; CHECK-NEXT:    ret i1 false
306   %arg0.nnan = fadd nnan float %arg0, 1.0
307   %op = fpext float %arg0.nnan to double
308   %tmp = fcmp uno double %op, %op
309   ret i1 %tmp
312 define i1 @fpext_maybe_nan(float %arg0) {
313 ; CHECK-LABEL: @fpext_maybe_nan(
314 ; CHECK-NEXT:    [[OP:%.*]] = fpext float [[ARG0:%.*]] to double
315 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
316 ; CHECK-NEXT:    ret i1 [[TMP]]
318   %op = fpext float %arg0 to double
319   %tmp = fcmp ord double %op, %op
320   ret i1 %tmp
323 define i1 @fptrunc(double %arg0) {
324 ; CHECK-LABEL: @fptrunc(
325 ; CHECK-NEXT:    ret i1 false
327   %arg0.nnan = fadd nnan double %arg0, 1.0
328   %op = fptrunc double %arg0.nnan to float
329   %tmp = fcmp uno float %op, %op
330   ret i1 %tmp
333 define i1 @fptrunc_maybe_nan(double %arg0) {
334 ; CHECK-LABEL: @fptrunc_maybe_nan(
335 ; CHECK-NEXT:    [[OP:%.*]] = fptrunc double [[ARG0:%.*]] to float
336 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord float [[OP]], [[OP]]
337 ; CHECK-NEXT:    ret i1 [[TMP]]
339   %op = fptrunc double %arg0 to float
340   %tmp = fcmp ord float %op, %op
341   ret i1 %tmp
344 define i1 @nnan_fdiv(double %arg0, double %arg1) {
345 ; CHECK-LABEL: @nnan_fdiv(
346 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
347 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
348 ; CHECK-NEXT:    [[OP:%.*]] = fdiv double [[NNAN_ARG0]], [[NNAN_ARG1]]
349 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp uno double [[OP]], [[OP]]
350 ; CHECK-NEXT:    ret i1 [[TMP]]
352   %nnan.arg0 = fadd nnan double %arg0, 1.0
353   %nnan.arg1 = fadd nnan double %arg0, 2.0
354   %op = fdiv double %nnan.arg0, %nnan.arg1
355   %tmp = fcmp uno double %op, %op
356   ret i1 %tmp
359 define i1 @nnan_frem(double %arg0, double %arg1) {
360 ; CHECK-LABEL: @nnan_frem(
361 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
362 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
363 ; CHECK-NEXT:    [[OP:%.*]] = frem double [[NNAN_ARG0]], [[NNAN_ARG1]]
364 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], [[OP]]
365 ; CHECK-NEXT:    ret i1 [[TMP]]
367   %nnan.arg0 = fadd nnan double %arg0, 1.0
368   %nnan.arg1 = fadd nnan double %arg0, 2.0
369   %op = frem double %nnan.arg0, %nnan.arg1
370   %tmp = fcmp ord double %op, %op
371   ret i1 %tmp
374 declare double @llvm.sqrt.f64(double)
375 declare double @llvm.fabs.f64(double)
376 declare double @llvm.canonicalize.f64(double)
377 declare double @llvm.copysign.f64(double, double)
378 declare double @llvm.exp.f64(double)
379 declare double @llvm.exp2.f64(double)
380 declare double @llvm.floor.f64(double)
381 declare double @llvm.ceil.f64(double)
382 declare double @llvm.trunc.f64(double)
383 declare double @llvm.rint.f64(double)
384 declare double @llvm.nearbyint.f64(double)
385 declare double @llvm.round.f64(double)