[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / known-never-nan.ll
blobc5fdc8e800cc6a04e6141669e81ee2f2620c5790
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -instcombine | FileCheck %s
4 ; This file used to contain more tests that folded to true/false,
5 ; but those are all tested identically in InstSimplify now.
6 ; If any remaining tests are made to return true/false, that
7 ; functionality/testing may be better housed in InstSimplify
8 ; rather than InstCombine.
10 define i1 @fabs_sqrt_src_maybe_nan(double %arg0, double %arg1) {
11 ; CHECK-LABEL: @fabs_sqrt_src_maybe_nan(
12 ; CHECK-NEXT:    [[FABS:%.*]] = call double @llvm.fabs.f64(double [[ARG0:%.*]])
13 ; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.sqrt.f64(double [[FABS]])
14 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
15 ; CHECK-NEXT:    ret i1 [[TMP]]
17   %fabs = call double @llvm.fabs.f64(double %arg0)
18   %op = call double @llvm.sqrt.f64(double %fabs)
19   %tmp = fcmp ord double %op, %op
20   ret i1 %tmp
23 define i1 @select_maybe_nan_lhs(i1 %cond, double %lhs, double %arg1) {
24 ; CHECK-LABEL: @select_maybe_nan_lhs(
25 ; CHECK-NEXT:    [[RHS:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00
26 ; CHECK-NEXT:    [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS:%.*]], double [[RHS]]
27 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
28 ; CHECK-NEXT:    ret i1 [[TMP]]
30   %rhs = fadd nnan double %arg1, 1.0
31   %op = select i1 %cond, double %lhs, double %rhs
32   %tmp = fcmp ord double %op, %op
33   ret i1 %tmp
36 define i1 @select_maybe_nan_rhs(i1 %cond, double %arg0, double %rhs) {
37 ; CHECK-LABEL: @select_maybe_nan_rhs(
38 ; CHECK-NEXT:    [[LHS:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
39 ; CHECK-NEXT:    [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS]], double [[RHS:%.*]]
40 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
41 ; CHECK-NEXT:    ret i1 [[TMP]]
43   %lhs = fadd nnan double %arg0, 1.0
44   %op = select i1 %cond, double %lhs, double %rhs
45   %tmp = fcmp ord double %op, %op
46   ret i1 %tmp
49 define i1 @nnan_fadd(double %arg0, double %arg1) {
50 ; CHECK-LABEL: @nnan_fadd(
51 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
52 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
53 ; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[NNAN_ARG1]]
54 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
55 ; CHECK-NEXT:    ret i1 [[TMP]]
57   %nnan.arg0 = fadd nnan double %arg0, 1.0
58   %nnan.arg1 = fadd nnan double %arg0, 2.0
59   %op = fadd double %nnan.arg0, %nnan.arg1
60   %tmp = fcmp ord double %op, %op
61   ret i1 %tmp
64 define i1 @nnan_fadd_maybe_nan_lhs(double %arg0, double %arg1) {
65 ; CHECK-LABEL: @nnan_fadd_maybe_nan_lhs(
66 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00
67 ; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG1]], [[ARG0:%.*]]
68 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
69 ; CHECK-NEXT:    ret i1 [[TMP]]
71   %nnan.arg1 = fadd nnan double %arg1, 1.0
72   %op = fadd double %arg0, %nnan.arg1
73   %tmp = fcmp ord double %op, %op
74   ret i1 %tmp
77 define i1 @nnan_fadd_maybe_nan_rhs(double %arg0, double %arg1) {
78 ; CHECK-LABEL: @nnan_fadd_maybe_nan_rhs(
79 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
80 ; CHECK-NEXT:    [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[ARG1:%.*]]
81 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
82 ; CHECK-NEXT:    ret i1 [[TMP]]
84   %nnan.arg0 = fadd nnan double %arg0, 1.0
85   %op = fadd double %nnan.arg0, %arg1
86   %tmp = fcmp ord double %op, %op
87   ret i1 %tmp
90 define i1 @nnan_fmul(double %arg0, double %arg1) {
91 ; CHECK-LABEL: @nnan_fmul(
92 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
93 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
94 ; CHECK-NEXT:    [[OP:%.*]] = fmul double [[NNAN_ARG0]], [[NNAN_ARG1]]
95 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
96 ; CHECK-NEXT:    ret i1 [[TMP]]
98   %nnan.arg0 = fadd nnan double %arg0, 1.0
99   %nnan.arg1 = fadd nnan double %arg0, 2.0
100   %op = fmul double %nnan.arg0, %nnan.arg1
101   %tmp = fcmp ord double %op, %op
102   ret i1 %tmp
105 define i1 @nnan_fsub(double %arg0, double %arg1) {
106 ; CHECK-LABEL: @nnan_fsub(
107 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
108 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
109 ; CHECK-NEXT:    [[OP:%.*]] = fsub double [[NNAN_ARG0]], [[NNAN_ARG1]]
110 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
111 ; CHECK-NEXT:    ret i1 [[TMP]]
113   %nnan.arg0 = fadd nnan double %arg0, 1.0
114   %nnan.arg1 = fadd nnan double %arg0, 2.0
115   %op = fsub double %nnan.arg0, %nnan.arg1
116   %tmp = fcmp ord double %op, %op
117   ret i1 %tmp
120 declare double @func()
122 define i1 @nnan_fneg() {
123 ; CHECK-LABEL: @nnan_fneg(
124 ; CHECK-NEXT:    [[NNAN:%.*]] = call nnan double @func()
125 ; CHECK-NEXT:    ret i1 true
127   %nnan = call nnan double @func()
128   %op = fsub double -0.0, %nnan
129   %tmp = fcmp ord double %op, %op
130   ret i1 %tmp
133 define i1 @nnan_unary_fneg() {
134 ; CHECK-LABEL: @nnan_unary_fneg(
135 ; CHECK-NEXT:    [[NNAN:%.*]] = call nnan double @func()
136 ; CHECK-NEXT:    ret i1 true
138   %nnan = call nnan double @func()
139   %op = fneg double %nnan
140   %tmp = fcmp ord double %op, %op
141   ret i1 %tmp
144 define i1 @fpext_maybe_nan(float %arg0) {
145 ; CHECK-LABEL: @fpext_maybe_nan(
146 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord float [[ARG0:%.*]], 0.000000e+00
147 ; CHECK-NEXT:    ret i1 [[TMP]]
149   %op = fpext float %arg0 to double
150   %tmp = fcmp ord double %op, %op
151   ret i1 %tmp
154 define i1 @fptrunc_maybe_nan(double %arg0) {
155 ; CHECK-LABEL: @fptrunc_maybe_nan(
156 ; CHECK-NEXT:    [[OP:%.*]] = fptrunc double [[ARG0:%.*]] to float
157 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord float [[OP]], 0.000000e+00
158 ; CHECK-NEXT:    ret i1 [[TMP]]
160   %op = fptrunc double %arg0 to float
161   %tmp = fcmp ord float %op, %op
162   ret i1 %tmp
165 define i1 @nnan_fdiv(double %arg0, double %arg1) {
166 ; CHECK-LABEL: @nnan_fdiv(
167 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
168 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
169 ; CHECK-NEXT:    [[OP:%.*]] = fdiv double [[NNAN_ARG0]], [[NNAN_ARG1]]
170 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
171 ; CHECK-NEXT:    ret i1 [[TMP]]
173   %nnan.arg0 = fadd nnan double %arg0, 1.0
174   %nnan.arg1 = fadd nnan double %arg0, 2.0
175   %op = fdiv double %nnan.arg0, %nnan.arg1
176   %tmp = fcmp ord double %op, %op
177   ret i1 %tmp
180 define i1 @nnan_frem(double %arg0, double %arg1) {
181 ; CHECK-LABEL: @nnan_frem(
182 ; CHECK-NEXT:    [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00
183 ; CHECK-NEXT:    [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00
184 ; CHECK-NEXT:    [[OP:%.*]] = frem double [[NNAN_ARG0]], [[NNAN_ARG1]]
185 ; CHECK-NEXT:    [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00
186 ; CHECK-NEXT:    ret i1 [[TMP]]
188   %nnan.arg0 = fadd nnan double %arg0, 1.0
189   %nnan.arg1 = fadd nnan double %arg0, 2.0
190   %op = frem double %nnan.arg0, %nnan.arg1
191   %tmp = fcmp ord double %op, %op
192   ret i1 %tmp
195 declare double @llvm.sqrt.f64(double)
196 declare double @llvm.fabs.f64(double)
197 declare double @llvm.canonicalize.f64(double)
198 declare double @llvm.copysign.f64(double, double)
199 declare double @llvm.exp.f64(double)
200 declare double @llvm.exp2.f64(double)
201 declare double @llvm.floor.f64(double)
202 declare double @llvm.ceil.f64(double)
203 declare double @llvm.trunc.f64(double)
204 declare double @llvm.rint.f64(double)
205 declare double @llvm.nearbyint.f64(double)
206 declare double @llvm.round.f64(double)