xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll (revision fbcf8a8cbb2461730bfd0603b396842925a88ef2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @use(i1)
5
6define void @test_unsigned_too_large(i128 %x) {
7; CHECK-LABEL: @test_unsigned_too_large(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i128 [[X:%.*]], 12345678901234123123123
10; CHECK-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
11; CHECK:       bb1:
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
19; CHECK:       bb2:
20; CHECK-NEXT:    ret void
21;
22entry:
23  %c.1 = icmp ule i128 %x, 12345678901234123123123
24  br i1 %c.1, label %bb1, label %bb2
25
26bb1:
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)
33  ret void
34
35bb2:
36  ret void
37}
38
39define void @test_signed_too_large(i128 %x) {
40; CHECK-LABEL: @test_signed_too_large(
41; CHECK-NEXT:  entry:
42; CHECK-NEXT:    [[C_1:%.*]] = icmp sle i128 [[X:%.*]], 12345678901234123123123
43; CHECK-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
44; CHECK:       bb1:
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
52; CHECK:       bb2:
53; CHECK-NEXT:    ret void
54;
55entry:
56  %c.1 = icmp sle i128 %x, 12345678901234123123123
57  br i1 %c.1, label %bb1, label %bb2
58
59bb1:
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)
66  ret void
67
68bb2:
69  ret void
70}
71
72define i1 @add_decomp_i80(i80 %a) {
73; CHECK-LABEL: @add_decomp_i80(
74; CHECK-NEXT:  entry:
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:%.*]]
78; CHECK:       then:
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]]
82; CHECK:       else:
83; CHECK-NEXT:    ret i1 false
84;
85entry:
86  %add = add nsw i80 %a, -1973801615886922022913
87  %c = icmp ult i80 %add, 1346612317380797267967
88  br i1 %c, label %then, label %else
89
90then:
91  %add.1 = add nsw i80 %a, -1973801615886922022913
92  %c.1 = icmp ult i80 %add.1, 1346612317380797267967
93  ret i1 %c.1
94
95else:
96  ret i1 false
97}
98
99; TODO: This could be folded.
100define i1 @sub_decomp_i80(i80 %a) {
101; CHECK-LABEL: @sub_decomp_i80(
102; CHECK-NEXT:  entry:
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:%.*]]
106; CHECK:       then:
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]]
110; CHECK:       else:
111; CHECK-NEXT:    ret i1 false
112;
113entry:
114  %sub = sub nuw i80 %a, 1973801615886922022913
115  %c = icmp ult i80 %sub, 1346612317380797267967
116  br i1 %c, label %then, label %else
117
118then:
119  %sub.1 = sub nuw i80 %a, 1973801615886922022913
120  %c.1 = icmp ult i80 %sub.1, 1346612317380797267967
121  ret i1 %c.1
122
123else:
124  ret i1 false
125}
126
127define i1 @gep_decomp_i80(ptr %a) {
128; CHECK-LABEL: @gep_decomp_i80(
129; CHECK-NEXT:  entry:
130; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 1973801615886922022913
131; CHECK-NEXT:    br i1 false, label [[THEN:%.*]], label [[ELSE:%.*]]
132; CHECK:       then:
133; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 1973801615886922022913
134; CHECK-NEXT:    ret i1 true
135; CHECK:       else:
136; CHECK-NEXT:    ret i1 false
137;
138entry:
139  %gep = getelementptr inbounds i8, ptr %a, i80 1973801615886922022913
140  %c = icmp eq ptr %gep, null
141  br i1 %c, label %then, label %else
142
143then:
144  %gep.1 = getelementptr inbounds i8, ptr %a, i80 1973801615886922022913
145  %c.1 = icmp eq ptr %gep.1, null
146  ret i1 %c.1
147
148else:
149  ret i1 false
150}
151
152define i1 @gep_zext_shl_decomp_i80(ptr %a, i80 %v) {
153; CHECK-LABEL: @gep_zext_shl_decomp_i80(
154; CHECK-NEXT:  entry:
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:%.*]]
160; CHECK:       then:
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]]
166; CHECK:       else:
167; CHECK-NEXT:    ret i1 false
168;
169entry:
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
175
176then:
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
181  ret i1 %c.1
182
183else:
184  ret i1 false
185}
186
187define i1 @gep_zext_add_decomp_i80(ptr %a, i80 %v) {
188; CHECK-LABEL: @gep_zext_add_decomp_i80(
189; CHECK-NEXT:  entry:
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:%.*]]
195; CHECK:       then:
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]]
201; CHECK:       else:
202; CHECK-NEXT:    ret i1 false
203;
204entry:
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
210
211then:
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
216  ret i1 %c.1
217
218else:
219  ret i1 false
220}
221
222define i1 @gep_shl_decomp_i80(ptr %a, i80 %v) {
223; CHECK-LABEL: @gep_shl_decomp_i80(
224; CHECK-NEXT:  entry:
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:%.*]]
229; CHECK:       then:
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]]
234; CHECK:       else:
235; CHECK-NEXT:    ret i1 false
236;
237entry:
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
242
243then:
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
247  ret i1 %c.1
248
249else:
250  ret i1 false
251}
252
253define i1 @gep_add_decomp_i80(ptr %a, i80 %v) {
254; CHECK-LABEL: @gep_add_decomp_i80(
255; CHECK-NEXT:  entry:
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:%.*]]
260; CHECK:       then:
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]]
265; CHECK:       else:
266; CHECK-NEXT:    ret i1 false
267;
268entry:
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
273
274then:
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
278  ret i1 %c.1
279
280else:
281  ret i1 false
282}
283
284define 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:%.*]]
289; CHECK:       then:
290; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i128 [[X]], 0
291; CHECK-NEXT:    ret i1 [[CMP2]]
292; CHECK:       else:
293; CHECK-NEXT:    ret i1 false
294;
295  %val = mul nsw i128 %x, 9223372036854775808
296  %cmp = icmp sgt i128 %x, %val
297  br i1 %cmp, label %then, label %else
298
299then:
300  %cmp2 = icmp sgt i128 %x, 0
301  ret i1 %cmp2
302
303else:
304  ret i1 false
305}
306
307define 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]]
312;
313  %add = add nuw nsw i64 -9223372036854775808, 10
314  %cmp = icmp uge i64 %add, 10
315  ret i1 %cmp
316}
317
318define 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]]
323;
324  %add = add i64 -9223372036854775808, -1
325  %cmp = icmp uge i64 %add, 10
326  ret i1 %cmp
327}
328
329define i1 @gep_decomp_large_index_31_bits(ptr %a) {
330; CHECK-LABEL: @gep_decomp_large_index_31_bits(
331; CHECK-NEXT:  entry:
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]]
340;
341entry:
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
349  ret i1 %res
350}
351
352define i1 @gep_decomp_large_index_63_bits(ptr %a) {
353; CHECK-LABEL: @gep_decomp_large_index_63_bits(
354; CHECK-NEXT:  entry:
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]]
362;
363entry:
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
371  ret i1 %res
372}
373
374define i1 @gep_decomp_large_index_63_bits_chained_overflow(ptr %a) {
375; CHECK-LABEL: @gep_decomp_large_index_63_bits_chained_overflow(
376; CHECK-NEXT:  entry:
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]]
385;
386entry:
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
395  ret i1 %res
396}
397
398%struct = type { [128 x i64], [2 x i32] }
399
400define i1 @gep_decomp_large_index_63_bits_overflow_struct(ptr %a) {
401; CHECK-LABEL: @gep_decomp_large_index_63_bits_overflow_struct(
402; CHECK-NEXT:  entry:
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]]
410;
411entry:
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
419  ret i1 %res
420}
421
422define 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]]
428;
429  %shl1 = shl nuw nsw i128 %arg, 32
430  %shl2 = shl nuw nsw i128 %shl1, 32
431  %cmp = icmp eq i128 %shl2, 0
432  ret i1 %cmp
433}
434
435declare void @llvm.assume(i1)
436