1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
6 define void @test_unsigned_too_large(i128 %x) {
7 ; CHECK-LABEL: @test_unsigned_too_large(
9 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i128 [[X:%.*]], 12345678901234123123123
10 ; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
12 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i128 [[X]], -12345678901234123123123
13 ; CHECK-NEXT: call void @use(i1 [[C_2]])
14 ; CHECK-NEXT: [[C_3:%.*]] = icmp uge i128 [[X]], -12345678901234123123123
15 ; CHECK-NEXT: call void @use(i1 [[C_3]])
16 ; CHECK-NEXT: [[C_4:%.*]] = icmp uge i128 [[X]], -12345678901234123123123
17 ; CHECK-NEXT: call void @use(i1 [[C_4]])
18 ; CHECK-NEXT: ret void
20 ; CHECK-NEXT: ret void
23 %c.1 = icmp ule i128 %x, 12345678901234123123123
24 br i1 %c.1, label %bb1, label %bb2
27 %c.2 = icmp ult i128 %x, -12345678901234123123123
28 call void @use(i1 %c.2)
29 %c.3 = icmp uge i128 %x, -12345678901234123123123
30 call void @use(i1 %c.3)
31 %c.4 = icmp uge i128 %x, -12345678901234123123123
32 call void @use(i1 %c.4)
39 define void @test_signed_too_large(i128 %x) {
40 ; CHECK-LABEL: @test_signed_too_large(
42 ; CHECK-NEXT: [[C_1:%.*]] = icmp sle i128 [[X:%.*]], 12345678901234123123123
43 ; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
45 ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i128 [[X]], -12345678901234123123123
46 ; CHECK-NEXT: call void @use(i1 [[C_2]])
47 ; CHECK-NEXT: [[C_3:%.*]] = icmp sge i128 [[X]], -12345678901234123123123
48 ; CHECK-NEXT: call void @use(i1 [[C_3]])
49 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i128 [[X]], -12345678901234123123123
50 ; CHECK-NEXT: call void @use(i1 [[C_4]])
51 ; CHECK-NEXT: ret void
53 ; CHECK-NEXT: ret void
56 %c.1 = icmp sle i128 %x, 12345678901234123123123
57 br i1 %c.1, label %bb1, label %bb2
60 %c.2 = icmp slt i128 %x, -12345678901234123123123
61 call void @use(i1 %c.2)
62 %c.3 = icmp sge i128 %x, -12345678901234123123123
63 call void @use(i1 %c.3)
64 %c.4 = icmp sge i128 %x, -12345678901234123123123
65 call void @use(i1 %c.4)
72 define i1 @add_decomp_i80(i80 %a) {
73 ; CHECK-LABEL: @add_decomp_i80(
75 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i80 [[A:%.*]], -1973801615886922022913
76 ; CHECK-NEXT: [[C:%.*]] = icmp ult i80 [[ADD]], 1346612317380797267967
77 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
79 ; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i80 [[A]], -1973801615886922022913
80 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i80 [[ADD_1]], 1346612317380797267967
81 ; CHECK-NEXT: ret i1 [[C_1]]
83 ; CHECK-NEXT: ret i1 false
86 %add = add nsw i80 %a, -1973801615886922022913
87 %c = icmp ult i80 %add, 1346612317380797267967
88 br i1 %c, label %then, label %else
91 %add.1 = add nsw i80 %a, -1973801615886922022913
92 %c.1 = icmp ult i80 %add.1, 1346612317380797267967
99 ; TODO: This could be folded.
100 define i1 @sub_decomp_i80(i80 %a) {
101 ; CHECK-LABEL: @sub_decomp_i80(
103 ; CHECK-NEXT: [[SUB:%.*]] = sub nuw i80 [[A:%.*]], 1973801615886922022913
104 ; CHECK-NEXT: [[C:%.*]] = icmp ult i80 [[SUB]], 1346612317380797267967
105 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
107 ; CHECK-NEXT: [[SUB_1:%.*]] = sub nuw i80 [[A]], 1973801615886922022913
108 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i80 [[SUB_1]], 1346612317380797267967
109 ; CHECK-NEXT: ret i1 [[C_1]]
111 ; CHECK-NEXT: ret i1 false
114 %sub = sub nuw i80 %a, 1973801615886922022913
115 %c = icmp ult i80 %sub, 1346612317380797267967
116 br i1 %c, label %then, label %else
119 %sub.1 = sub nuw i80 %a, 1973801615886922022913
120 %c.1 = icmp ult i80 %sub.1, 1346612317380797267967
127 define i1 @gep_decomp_i80(ptr %a) {
128 ; CHECK-LABEL: @gep_decomp_i80(
130 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 1973801615886922022913
131 ; CHECK-NEXT: br i1 false, label [[THEN:%.*]], label [[ELSE:%.*]]
133 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 1973801615886922022913
134 ; CHECK-NEXT: ret i1 true
136 ; CHECK-NEXT: ret i1 false
139 %gep = getelementptr inbounds i8, ptr %a, i80 1973801615886922022913
140 %c = icmp eq ptr %gep, null
141 br i1 %c, label %then, label %else
144 %gep.1 = getelementptr inbounds i8, ptr %a, i80 1973801615886922022913
145 %c.1 = icmp eq ptr %gep.1, null
152 define i1 @gep_zext_shl_decomp_i80(ptr %a, i80 %v) {
153 ; CHECK-LABEL: @gep_zext_shl_decomp_i80(
155 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i80 [[V:%.*]], 1973801615886922022913
156 ; CHECK-NEXT: [[EXT:%.*]] = zext i80 [[SHL]] to i128
157 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i128 [[EXT]]
158 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null
159 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
161 ; CHECK-NEXT: [[SHL_1:%.*]] = shl nuw i80 [[V]], 1973801615886922022913
162 ; CHECK-NEXT: [[EXT_1:%.*]] = zext i80 [[SHL_1]] to i128
163 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i128 [[EXT_1]]
164 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null
165 ; CHECK-NEXT: ret i1 [[C_1]]
167 ; CHECK-NEXT: ret i1 false
170 %shl = shl nuw i80 %v, 1973801615886922022913
171 %ext = zext i80 %shl to i128
172 %gep = getelementptr inbounds i8, ptr %a, i128 %ext
173 %c = icmp eq ptr %gep, null
174 br i1 %c, label %then, label %else
177 %shl.1 = shl nuw i80 %v, 1973801615886922022913
178 %ext.1 = zext i80 %shl.1 to i128
179 %gep.1 = getelementptr inbounds i8, ptr %a, i128 %ext.1
180 %c.1 = icmp eq ptr %gep.1, null
187 define i1 @gep_zext_add_decomp_i80(ptr %a, i80 %v) {
188 ; CHECK-LABEL: @gep_zext_add_decomp_i80(
190 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i80 [[V:%.*]], 1973801615886922022913
191 ; CHECK-NEXT: [[EXT:%.*]] = zext i80 [[ADD]] to i128
192 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i128 [[EXT]]
193 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null
194 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
196 ; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i80 [[V]], 1973801615886922022913
197 ; CHECK-NEXT: [[EXT_1:%.*]] = zext i80 [[ADD_1]] to i128
198 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i128 [[EXT_1]]
199 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null
200 ; CHECK-NEXT: ret i1 [[C_1]]
202 ; CHECK-NEXT: ret i1 false
205 %add = add nsw i80 %v, 1973801615886922022913
206 %ext = zext i80 %add to i128
207 %gep = getelementptr inbounds i8, ptr %a, i128 %ext
208 %c = icmp eq ptr %gep, null
209 br i1 %c, label %then, label %else
212 %add.1 = add nsw i80 %v, 1973801615886922022913
213 %ext.1 = zext i80 %add.1 to i128
214 %gep.1 = getelementptr inbounds i8, ptr %a, i128 %ext.1
215 %c.1 = icmp eq ptr %gep.1, null
222 define i1 @gep_shl_decomp_i80(ptr %a, i80 %v) {
223 ; CHECK-LABEL: @gep_shl_decomp_i80(
225 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i80 [[V:%.*]], 1973801615886922022913
226 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 [[SHL]]
227 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null
228 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
230 ; CHECK-NEXT: [[SHL_1:%.*]] = shl nuw i80 [[V]], 1973801615886922022913
231 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 [[SHL_1]]
232 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null
233 ; CHECK-NEXT: ret i1 [[C_1]]
235 ; CHECK-NEXT: ret i1 false
238 %shl = shl nuw i80 %v, 1973801615886922022913
239 %gep = getelementptr inbounds i8, ptr %a, i80 %shl
240 %c = icmp eq ptr %gep, null
241 br i1 %c, label %then, label %else
244 %shl.1 = shl nuw i80 %v, 1973801615886922022913
245 %gep.1 = getelementptr inbounds i8, ptr %a, i80 %shl.1
246 %c.1 = icmp eq ptr %gep.1, null
253 define i1 @gep_add_decomp_i80(ptr %a, i80 %v) {
254 ; CHECK-LABEL: @gep_add_decomp_i80(
256 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i80 [[V:%.*]], 1973801615886922022913
257 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 [[ADD]]
258 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null
259 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
261 ; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i80 [[V]], 1973801615886922022913
262 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 [[ADD_1]]
263 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null
264 ; CHECK-NEXT: ret i1 [[C_1]]
266 ; CHECK-NEXT: ret i1 false
269 %add = add nsw i80 %v, 1973801615886922022913
270 %gep = getelementptr inbounds i8, ptr %a, i80 %add
271 %c = icmp eq ptr %gep, null
272 br i1 %c, label %then, label %else
275 %add.1 = add nsw i80 %v, 1973801615886922022913
276 %gep.1 = getelementptr inbounds i8, ptr %a, i80 %add.1
277 %c.1 = icmp eq ptr %gep.1, null
284 define i1 @mul_nsw_decomp(i128 %x) {
285 ; CHECK-LABEL: @mul_nsw_decomp(
286 ; CHECK-NEXT: [[VAL:%.*]] = mul nsw i128 [[X:%.*]], 9223372036854775808
287 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X]], [[VAL]]
288 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
290 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i128 [[X]], 0
291 ; CHECK-NEXT: ret i1 [[CMP2]]
293 ; CHECK-NEXT: ret i1 false
295 %val = mul nsw i128 %x, 9223372036854775808
296 %cmp = icmp sgt i128 %x, %val
297 br i1 %cmp, label %then, label %else
300 %cmp2 = icmp sgt i128 %x, 0
307 define i1 @add_nuw_decomp_recursive() {
308 ; CHECK-LABEL: @add_nuw_decomp_recursive(
309 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 -9223372036854775808, 10
310 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], 10
311 ; CHECK-NEXT: ret i1 [[CMP]]
313 %add = add nuw nsw i64 -9223372036854775808, 10
314 %cmp = icmp uge i64 %add, 10
318 define i1 @add_minus_one_decomp_recursive() {
319 ; CHECK-LABEL: @add_minus_one_decomp_recursive(
320 ; CHECK-NEXT: [[ADD:%.*]] = add i64 -9223372036854775808, -1
321 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], 10
322 ; CHECK-NEXT: ret i1 [[CMP]]
324 %add = add i64 -9223372036854775808, -1
325 %cmp = icmp uge i64 %add, 10
329 define i1 @gep_decomp_large_index_31_bits(ptr %a) {
330 ; CHECK-LABEL: @gep_decomp_large_index_31_bits(
332 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 2147483646
333 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 2147483647
334 ; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]]
335 ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
336 ; CHECK-NEXT: [[CMP_ULE:%.*]] = icmp ule ptr [[GEP_1]], [[GEP_2]]
337 ; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]]
338 ; CHECK-NEXT: [[RES:%.*]] = xor i1 true, false
339 ; CHECK-NEXT: ret i1 [[RES]]
342 %gep.1 = getelementptr inbounds i64, ptr %a, i64 2147483646
343 %gep.2 = getelementptr inbounds i64, ptr %a, i64 2147483647
344 %ne = icmp ne ptr %gep.1, %gep.2
345 call void @llvm.assume(i1 %ne)
346 %cmp.ule = icmp ule ptr %gep.1, %gep.2
347 %cmp.uge = icmp uge ptr %gep.1, %gep.2
348 %res = xor i1 true, false
352 define i1 @gep_decomp_large_index_63_bits(ptr %a) {
353 ; CHECK-LABEL: @gep_decomp_large_index_63_bits(
355 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804
356 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 9223372036854775805
357 ; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]]
358 ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
359 ; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]]
360 ; CHECK-NEXT: [[RES:%.*]] = xor i1 true, true
361 ; CHECK-NEXT: ret i1 [[RES]]
364 %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804
365 %gep.2 = getelementptr inbounds i64, ptr %a, i64 9223372036854775805
366 %ne = icmp ne ptr %gep.1, %gep.2
367 call void @llvm.assume(i1 %ne)
368 %cmp.ule = icmp ule ptr %gep.1, %gep.2
369 %cmp.uge = icmp uge ptr %gep.1, %gep.2
370 %res = xor i1 %cmp.ule, %cmp.ule
374 define i1 @gep_decomp_large_index_63_bits_chained_overflow(ptr %a) {
375 ; CHECK-LABEL: @gep_decomp_large_index_63_bits_chained_overflow(
377 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804
378 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 1152921504606846976
379 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i64, ptr [[GEP_2]], i64 1152921504606846976
380 ; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_3]]
381 ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
382 ; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_3]]
383 ; CHECK-NEXT: [[RES:%.*]] = xor i1 true, true
384 ; CHECK-NEXT: ret i1 [[RES]]
387 %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804
388 %gep.2 = getelementptr inbounds ptr, ptr %a, i64 1152921504606846976
389 %gep.3 = getelementptr inbounds i64, ptr %gep.2, i64 1152921504606846976
390 %ne = icmp ne ptr %gep.1, %gep.3
391 call void @llvm.assume(i1 %ne)
392 %cmp.ule = icmp ule ptr %gep.1, %gep.3
393 %cmp.uge = icmp uge ptr %gep.1, %gep.3
394 %res = xor i1 %cmp.ule, %cmp.ule
398 %struct = type { [128 x i64], [2 x i32] }
400 define i1 @gep_decomp_large_index_63_bits_overflow_struct(ptr %a) {
401 ; CHECK-LABEL: @gep_decomp_large_index_63_bits_overflow_struct(
403 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804
404 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds [[STRUCT:%.*]], ptr [[A]], i64 8937376004704240, i32 1, i32 1
405 ; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]]
406 ; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
407 ; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]]
408 ; CHECK-NEXT: [[RES:%.*]] = xor i1 false, false
409 ; CHECK-NEXT: ret i1 [[RES]]
412 %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804
413 %gep.2 = getelementptr inbounds %struct, ptr %a, i64 8937376004704240, i32 1, i32 1
414 %ne = icmp ne ptr %gep.1, %gep.2
415 call void @llvm.assume(i1 %ne)
416 %cmp.ule = icmp ule ptr %gep.1, %gep.2
417 %cmp.uge = icmp uge ptr %gep.1, %gep.2
418 %res = xor i1 %cmp.ule, %cmp.ule
422 define i1 @pr68751(i128 %arg) {
423 ; CHECK-LABEL: @pr68751(
424 ; CHECK-NEXT: [[SHL1:%.*]] = shl nuw nsw i128 [[ARG:%.*]], 32
425 ; CHECK-NEXT: [[SHL2:%.*]] = shl nuw nsw i128 [[SHL1]], 32
426 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[SHL2]], 0
427 ; CHECK-NEXT: ret i1 [[CMP]]
429 %shl1 = shl nuw nsw i128 %arg, 32
430 %shl2 = shl nuw nsw i128 %shl1, 32
431 %cmp = icmp eq i128 %shl2, 0
435 declare void @llvm.assume(i1)