[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / SCCP / ip-ranges-casts.ll
blobb39f2985b8a389fd8e4f7dcbde88ef8a3149132c
1 ; RUN: opt < %s -ipsccp -S | FileCheck %s
3 ; x = [100, 301)
4 define internal i1 @f.trunc(i32 %x) {
5 ; CHECK-LABEL: define internal i1 @f.trunc(i32 %x) {
6 ; CHECK-NEXT:    %t.1 = trunc i32 %x to i16
7 ; CHECK-NEXT:    %c.2 = icmp sgt i16 %t.1, 299
8 ; CHECK-NEXT:    %c.4 = icmp slt i16 %t.1, 101
9 ; CHECK-NEXT:    %res.1 = add i1 false, %c.2
10 ; CHECK-NEXT:    %res.2 = add i1 %res.1, false
11 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4
12 ; CHECK-NEXT:    %t.2 = trunc i32 %x to i8
13 ; CHECK-NEXT:    %c.5 = icmp sgt i8 %t.2, 44
14 ; CHECK-NEXT:    %c.6 = icmp sgt i8 %t.2, 43
15 ; CHECK-NEXT:    %c.7 = icmp slt i8 %t.2, 100
16 ; CHECK-NEXT:    %c.8 = icmp slt i8 %t.2, 101
17 ; CHECK-NEXT:    %res.4 = add i1 %res.3, %c.5
18 ; CHECK-NEXT:    %res.5 = add i1 %res.4, %c.6
19 ; CHECK-NEXT:    %res.6 = add i1 %res.5, %c.7
20 ; CHECK-NEXT:    %res.7 = add i1 %res.6, %c.8
21 ; CHECK-NEXT:    ret i1 %res.7
23   %t.1 = trunc i32 %x to i16
24   %c.1 = icmp sgt i16 %t.1, 300
25   %c.2 = icmp sgt i16 %t.1, 299
26   %c.3 = icmp slt i16 %t.1, 100
27   %c.4 = icmp slt i16 %t.1, 101
28   %res.1 = add i1 %c.1, %c.2
29   %res.2 = add i1 %res.1, %c.3
30   %res.3 = add i1 %res.2, %c.4
31   %t.2 = trunc i32 %x to i8
32   %c.5 = icmp sgt i8 %t.2, 300
33   %c.6 = icmp sgt i8 %t.2, 299
34   %c.7 = icmp slt i8 %t.2, 100
35   %c.8 = icmp slt i8 %t.2, 101
36   %res.4 = add i1 %res.3, %c.5
37   %res.5 = add i1 %res.4, %c.6
38   %res.6 = add i1 %res.5, %c.7
39   %res.7 = add i1 %res.6, %c.8
40   ret i1 %res.7
43 define i1 @caller1() {
44 ; CHECK-LABEL:  define i1 @caller1() {
45 ; CHECK-NEXT:    %call.1 = tail call i1 @f.trunc(i32 100)
46 ; CHECK-NEXT:    %call.2 = tail call i1 @f.trunc(i32 300)
47 ; CHECK-NEXT:    %res = and i1 %call.1, %call.2
48 ; CHECK-NEXT:    ret i1 %res
50   %call.1 = tail call i1 @f.trunc(i32 100)
51   %call.2 = tail call i1 @f.trunc(i32 300)
52   %res = and i1 %call.1, %call.2
53   ret i1 %res
57 ; x = [100, 301)
58 define internal i1 @f.zext(i32 %x, i32 %y) {
59 ; CHECK-LABEL: define internal i1 @f.zext(i32 %x, i32 %y) {
60 ; CHECK-NEXT:    %t.1 = zext i32 %x to i64
61 ; CHECK-NEXT:    %c.2 = icmp sgt i64 %t.1, 299
62 ; CHECK-NEXT:    %c.4 = icmp slt i64 %t.1, 101
63 ; CHECK-NEXT:    %res.1 = add i1 false, %c.2
64 ; CHECK-NEXT:    %res.2 = add i1 %res.1, false
65 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4
66 ; CHECK-NEXT:    %t.2 = zext i32 %y to i64
67 ; CHECK-NEXT:    %c.5 = icmp sgt i64 %t.2, 300
68 ; CHECK-NEXT:    %c.6 = icmp sgt i64 %t.2, 299
69 ; CHECK-NEXT:    %c.8 = icmp slt i64 %t.2, 1
70 ; CHECK-NEXT:    %res.4 = add i1 %res.3, %c.5
71 ; CHECK-NEXT:    %res.5 = add i1 %res.4, %c.6
72 ; CHECK-NEXT:    %res.6 = add i1 %res.5, false
73 ; CHECK-NEXT:    %res.7 = add i1 %res.6, %c.8
74 ; CHECK-NEXT:    ret i1 %res.7
76   %t.1 = zext i32 %x to i64
77   %c.1 = icmp sgt i64 %t.1, 300
78   %c.2 = icmp sgt i64 %t.1, 299
79   %c.3 = icmp slt i64 %t.1, 100
80   %c.4 = icmp slt i64 %t.1, 101
81   %res.1 = add i1 %c.1, %c.2
82   %res.2 = add i1 %res.1, %c.3
83   %res.3 = add i1 %res.2, %c.4
84   %t.2 = zext i32 %y to i64
85   %c.5 = icmp sgt i64 %t.2, 300
86   %c.6 = icmp sgt i64 %t.2, 299
87   %c.7 = icmp slt i64 %t.2, 0
88   %c.8 = icmp slt i64 %t.2, 1
89   %res.4 = add i1 %res.3, %c.5
90   %res.5 = add i1 %res.4, %c.6
91   %res.6 = add i1 %res.5, %c.7
92   %res.7 = add i1 %res.6, %c.8
93   ret i1 %res.7
96 define i1 @caller.zext() {
97 ; CHECK-LABEL:  define i1 @caller.zext() {
98 ; CHECK-NEXT:    %call.1 = tail call i1 @f.zext(i32 100, i32 -120)
99 ; CHECK-NEXT:    %call.2 = tail call i1 @f.zext(i32 300, i32 900)
100 ; CHECK-NEXT:    %res = and i1 %call.1, %call.2
101 ; CHECK-NEXT:    ret i1 %res
103   %call.1 = tail call i1 @f.zext(i32 100, i32 -120)
104   %call.2 = tail call i1 @f.zext(i32 300, i32 900)
105   %res = and i1 %call.1, %call.2
106   ret i1 %res
109 ; x = [100, 301)
110 define internal i1 @f.sext(i32 %x, i32 %y) {
111 ; CHECK-LABEL: define internal i1 @f.sext(i32 %x, i32 %y) {
112 ; CHECK-NEXT:    [[T_1:%.*]] = zext i32 %x to i64
113 ; CHECK-NEXT:    %c.2 = icmp sgt i64 [[T_1]], 299
114 ; CHECK-NEXT:    %c.4 = icmp slt i64 [[T_1]], 101
115 ; CHECK-NEXT:    %res.1 = add i1 false, %c.2
116 ; CHECK-NEXT:    %res.2 = add i1 %res.1, false
117 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4
118 ; CHECK-NEXT:    %t.2 = sext i32 %y to i64
119 ; CHECK-NEXT:    %c.6 = icmp sgt i64 %t.2, 899
120 ; CHECK-NEXT:    %c.8 = icmp slt i64 %t.2, -119
121 ; CHECK-NEXT:    %res.4 = add i1 %res.3, false
122 ; CHECK-NEXT:    %res.5 = add i1 %res.4, %c.6
123 ; CHECK-NEXT:    %res.6 = add i1 %res.5, false
124 ; CHECK-NEXT:    %res.7 = add i1 %res.6, %c.8
125 ; CHECK-NEXT:    ret i1 %res.7
127   %t.1 = sext i32 %x to i64
128   %c.1 = icmp sgt i64 %t.1, 300
129   %c.2 = icmp sgt i64 %t.1, 299
130   %c.3 = icmp slt i64 %t.1, 100
131   %c.4 = icmp slt i64 %t.1, 101
132   %res.1 = add i1 %c.1, %c.2
133   %res.2 = add i1 %res.1, %c.3
134   %res.3 = add i1 %res.2, %c.4
135   %t.2 = sext i32 %y to i64
136   %c.5 = icmp sgt i64 %t.2, 900
137   %c.6 = icmp sgt i64 %t.2, 899
138   %c.7 = icmp slt i64 %t.2, -120
139   %c.8 = icmp slt i64 %t.2, -119
140   %res.4 = add i1 %res.3, %c.5
141   %res.5 = add i1 %res.4, %c.6
142   %res.6 = add i1 %res.5, %c.7
143   %res.7 = add i1 %res.6, %c.8
144   ret i1 %res.7
147 define i1 @caller.sext() {
148 ; CHECK-LABEL:  define i1 @caller.sext() {
149 ; CHECK-NEXT:    %call.1 = tail call i1 @f.sext(i32 100, i32 -120)
150 ; CHECK-NEXT:    %call.2 = tail call i1 @f.sext(i32 300, i32 900)
151 ; CHECK-NEXT:    %res = and i1 %call.1, %call.2
152 ; CHECK-NEXT:    ret i1 %res
154   %call.1 = tail call i1 @f.sext(i32 100, i32 -120)
155   %call.2 = tail call i1 @f.sext(i32 300, i32 900)
156   %res = and i1 %call.1, %call.2
157   ret i1 %res
160 ; There's nothing we can do besides going to the full range or overdefined.
161 define internal i1 @f.fptosi(i32 %x) {
162 ; CHECK-LABEL: define internal i1 @f.fptosi(i32 %x) {
163 ; CHECK-NEXT:    %to.double = sitofp i32 %x to double
164 ; CHECK-NEXT:    %add = fadd double 0.000000e+00, %to.double
165 ; CHECK-NEXT:    %to.i32 = fptosi double %add to i32
166 ; CHECK-NEXT:    %c.1 = icmp sgt i32 %to.i32, 300
167 ; CHECK-NEXT:    %c.2 = icmp sgt i32 %to.i32, 299
168 ; CHECK-NEXT:    %c.3 = icmp slt i32 %to.i32, 100
169 ; CHECK-NEXT:    %c.4 = icmp slt i32 %to.i32, 101
170 ; CHECK-NEXT:    %res.1 = add i1 %c.1, %c.2
171 ; CHECK-NEXT:    %res.2 = add i1 %res.1, %c.3
172 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4
173 ; CHECK-NEXT:    ret i1 %res.3
175   %to.double = sitofp i32 %x to double
176   %add = fadd double 0.000000e+00, %to.double
177   %to.i32 = fptosi double %add to i32
178   %c.1 = icmp sgt i32 %to.i32, 300
179   %c.2 = icmp sgt i32 %to.i32, 299
180   %c.3 = icmp slt i32 %to.i32, 100
181   %c.4 = icmp slt i32 %to.i32, 101
182   %res.1 = add i1 %c.1, %c.2
183   %res.2 = add i1 %res.1, %c.3
184   %res.3 = add i1 %res.2, %c.4
185   ret i1 %res.3
188 define i1 @caller.fptosi() {
189 ; CHECK-LABEL:  define i1 @caller.fptosi() {
190 ; CHECK-NEXT:    %call.1 = tail call i1 @f.fptosi(i32 100)
191 ; CHECK-NEXT:    %call.2 = tail call i1 @f.fptosi(i32 300)
192 ; CHECK-NEXT:    %res = and i1 %call.1, %call.2
193 ; CHECK-NEXT:    ret i1 %res
195   %call.1 = tail call i1 @f.fptosi(i32 100)
196   %call.2 = tail call i1 @f.fptosi(i32 300)
197   %res = and i1 %call.1, %call.2
198   ret i1 %res
201 ; There's nothing we can do besides going to the full range or overdefined.
202 define internal i1 @f.fpext(i16 %x) {
203 ; CHECK-LABEL: define internal i1 @f.fpext(i16 %x) {
204 ; CHECK-NEXT:    %to.float = sitofp i16 %x to float
205 ; CHECK-NEXT:    %to.double = fpext float %to.float to double
206 ; CHECK-NEXT:    %to.i64 = fptoui float %to.float to i64
207 ; CHECK-NEXT:    %c.1 = icmp sgt i64 %to.i64, 300
208 ; CHECK-NEXT:    %c.2 = icmp sgt i64 %to.i64, 299
209 ; CHECK-NEXT:    %c.3 = icmp slt i64 %to.i64, 100
210 ; CHECK-NEXT:    %c.4 = icmp slt i64 %to.i64, 101
211 ; CHECK-NEXT:    %res.1 = add i1 %c.1, %c.2
212 ; CHECK-NEXT:    %res.2 = add i1 %res.1, %c.3
213 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4
214 ; CHECK-NEXT:    ret i1 %res.3
216   %to.float = sitofp i16 %x to float
217   %to.double = fpext float %to.float  to double
218   %to.i64= fptoui float %to.float to i64
219   %c.1 = icmp sgt i64 %to.i64, 300
220   %c.2 = icmp sgt i64 %to.i64, 299
221   %c.3 = icmp slt i64 %to.i64, 100
222   %c.4 = icmp slt i64 %to.i64, 101
223   %res.1 = add i1 %c.1, %c.2
224   %res.2 = add i1 %res.1, %c.3
225   %res.3 = add i1 %res.2, %c.4
226   ret i1 %res.3
229 ; There's nothing we can do besides going to the full range or overdefined.
230 define i1 @caller.fpext() {
231 ; CHECK-LABEL:  define i1 @caller.fpext() {
232 ; CHECK-NEXT:    %call.1 = tail call i1 @f.fpext(i16 100)
233 ; CHECK-NEXT:    %call.2 = tail call i1 @f.fpext(i16 300)
234 ; CHECK-NEXT:    %res = and i1 %call.1, %call.2
235 ; CHECK-NEXT:    ret i1 %res
237   %call.1 = tail call i1 @f.fpext(i16 100)
238   %call.2 = tail call i1 @f.fpext(i16 300)
239   %res = and i1 %call.1, %call.2
240   ret i1 %res
243 ; There's nothing we can do besides going to the full range or overdefined.
244 define internal i1 @f.inttoptr.ptrtoint(i64 %x) {
245 ; CHECK-LABEL: define internal i1 @f.inttoptr.ptrtoint(i64 %x) {
246 ; CHECK-NEXT:    %to.ptr = inttoptr i64 %x to i8*
247 ; CHECK-NEXT:    %to.i64 = ptrtoint i8* %to.ptr to i64
248 ; CHECK-NEXT:    %c.1 = icmp sgt i64 %to.i64, 300
249 ; CHECK-NEXT:    %c.2 = icmp sgt i64 %to.i64, 299
250 ; CHECK-NEXT:    %c.3 = icmp slt i64 %to.i64, 100
251 ; CHECK-NEXT:    %c.4 = icmp slt i64 %to.i64, 101
252 ; CHECK-NEXT:    %res.1 = add i1 %c.1, %c.2
253 ; CHECK-NEXT:    %res.2 = add i1 %res.1, %c.3
254 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4
255 ; CHECK-NEXT:    ret i1 %res.3
257   %to.ptr = inttoptr i64 %x to i8*
258   %to.i64 = ptrtoint i8* %to.ptr to i64
259   %c.1 = icmp sgt i64 %to.i64, 300
260   %c.2 = icmp sgt i64 %to.i64, 299
261   %c.3 = icmp slt i64 %to.i64, 100
262   %c.4 = icmp slt i64 %to.i64, 101
263   %res.1 = add i1 %c.1, %c.2
264   %res.2 = add i1 %res.1, %c.3
265   %res.3 = add i1 %res.2, %c.4
266   ret i1 %res.3
269 define i1 @caller.inttoptr.ptrtoint() {
270 ; CHECK-LABEL:  define i1 @caller.inttoptr.ptrtoint() {
271 ; CHECK-NEXT:    %call.1 = tail call i1 @f.inttoptr.ptrtoint(i64 100)
272 ; CHECK-NEXT:    %call.2 = tail call i1 @f.inttoptr.ptrtoint(i64 300)
273 ; CHECK-NEXT:    %res = and i1 %call.1, %call.2
274 ; CHECK-NEXT:    ret i1 %res
276   %call.1 = tail call i1 @f.inttoptr.ptrtoint(i64 100)
277   %call.2 = tail call i1 @f.inttoptr.ptrtoint(i64 300)
278   %res = and i1 %call.1, %call.2
279   ret i1 %res
282 ; Make sure we do not create constant ranges for int to fp casts.
283 define i1 @int_range_to_double_cast(i32 %a) {
284 ; CHECK-LABEL: define i1 @int_range_to_double_cast(i32 %a)
285 ; CHECK-NEXT:    %r = and i32 %a, 255
286 ; CHECK-NEXT:    %tmp4 = sitofp i32 %r to double
287 ; CHECK-NEXT:    %tmp10 = fadd double 0.000000e+00, %tmp4
288 ; CHECK-NEXT:    %tmp11 = fcmp olt double %tmp4, %tmp10
289 ; CHECK-NEXT:    ret i1 %tmp11
291   %r = and i32 %a, 255
292   %tmp4 = sitofp i32 %r to double
293   %tmp10 = fadd double 0.000000e+00, %tmp4
294   %tmp11 = fcmp olt double %tmp4, %tmp10
295   ret i1 %tmp11
298 ; Make sure we do not use ranges to propagate info from vectors.
299 define i16 @vector_binop_and_cast() {
300 ; CHECK-LABEL: define i16 @vector_binop_and_cast(
301 ; CHECK-NEXT:  entry:
302 ; CHECK-NEXT:    %vecinit7 = insertelement <8 x i16> <i16 undef, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, i16 undef, i32 0
303 ; CHECK-NEXT:    %rem = srem <8 x i16> <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>, %vecinit7
304 ; CHECK-NEXT:    %0 = bitcast <8 x i16> %rem to i128
305 ; CHECK-NEXT:    %1 = trunc i128 %0 to i16
306 ; CHECK-NEXT:    ret i16 %1
307 entry:
308   %vecinit7 = insertelement <8 x i16> <i16 undef, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, i16 undef, i32 0
309   %rem = srem <8 x i16> <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>, %vecinit7
310   %0 = bitcast <8 x i16> %rem to i128
311   %1 = trunc i128 %0 to i16
312   ret i16 %1