xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/gep-chains.ll (revision 13ffde316a8541d77116bd18f73efada236617f3)
1dbe86a90SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2dbe86a90SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3dbe86a90SFlorian Hahn
4dbe86a90SFlorian Hahndeclare void @llvm.assume(i1 noundef) #0
5dbe86a90SFlorian Hahn
6dbe86a90SFlorian Hahndefine i1 @gep_add_1_uge_inbounds(ptr %dst, ptr %lower) {
7dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_uge_inbounds(
8dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
9dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
10dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
11dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1
12dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 1
13dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
14dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 3
15dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], true
16dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
17dbe86a90SFlorian Hahn;
18dbe86a90SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
19dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
20dbe86a90SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
21dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst, i64 1
22dbe86a90SFlorian Hahn  %cmp.add.1 = icmp uge ptr %dst.add.1, %lower
23dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr inbounds i8, ptr %dst.add.1, i64 1
24dbe86a90SFlorian Hahn  %cmp.add.3 = icmp uge ptr %dst.add.3, %lower
25dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.3
26dbe86a90SFlorian Hahn  %dst.add.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 3
27dbe86a90SFlorian Hahn  %cmp.add.4 = icmp uge ptr %dst.add.4, %lower
28dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.add.4
29dbe86a90SFlorian Hahn  ret i1 %res.2
30dbe86a90SFlorian Hahn}
31dbe86a90SFlorian Hahn
32dbe86a90SFlorian Hahndefine i1 @gep_add_1_uge_inbounds_scalable_vector(ptr %dst, ptr %lower) {
33dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_uge_inbounds_scalable_vector(
34dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
35dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
36dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST]], i64 3
37dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST]], i64 1
38dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_1:%.*]] = icmp uge ptr [[DST_ADD_1]], [[LOWER]]
39dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST_ADD_1]], i64 1
40dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_3:%.*]] = icmp uge ptr [[DST_ADD_3]], [[LOWER]]
41dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_3]]
42dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST_ADD_3]], i64 3
43dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
44dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
45dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
46dbe86a90SFlorian Hahn;
47dbe86a90SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
48dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
49dbe86a90SFlorian Hahn  %dst.add.3 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst, i64 3
50dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst, i64 1
51dbe86a90SFlorian Hahn  %cmp.add.1 = icmp uge ptr %dst.add.1, %lower
52dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst.add.1, i64 1
53dbe86a90SFlorian Hahn  %cmp.add.3 = icmp uge ptr %dst.add.3, %lower
54dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.3
55dbe86a90SFlorian Hahn  %dst.add.4 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst.add.3, i64 3
56dbe86a90SFlorian Hahn  %cmp.add.4 = icmp uge ptr %dst.add.4, %lower
57dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.add.4
58dbe86a90SFlorian Hahn  ret i1 %res.2
59dbe86a90SFlorian Hahn}
60dbe86a90SFlorian Hahn
61dbe86a90SFlorian Hahndefine i1 @gep_add_1_uge_only_inner_inbounds(ptr %dst, ptr %lower) {
62dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_uge_only_inner_inbounds(
63dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
64dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
65dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
66dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1
67dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr i8, ptr [[DST_ADD_1]], i64 1
68dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
69dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 3
70dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
71dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
72dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
73dbe86a90SFlorian Hahn;
74dbe86a90SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
75dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
76dbe86a90SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
77dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst, i64 1
78dbe86a90SFlorian Hahn  %cmp.add.1 = icmp uge ptr %dst.add.1, %lower
79dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr i8, ptr %dst.add.1, i64 1
80dbe86a90SFlorian Hahn  %cmp.add.3 = icmp uge ptr %dst.add.3, %lower
81dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.3
82dbe86a90SFlorian Hahn  %dst.add.4 = getelementptr i8, ptr %dst.add.3, i64 3
83dbe86a90SFlorian Hahn  %cmp.add.4 = icmp uge ptr %dst.add.4, %lower
84dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.add.4
85dbe86a90SFlorian Hahn  ret i1 %res.2
86dbe86a90SFlorian Hahn}
87dbe86a90SFlorian Hahn
88dbe86a90SFlorian Hahndefine i1 @gep_add_1_uge_only_outer_inbounds(ptr %dst, ptr %lower) {
89dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_uge_only_outer_inbounds(
90dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
91dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
92dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
93dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr i8, ptr [[DST]], i64 1
94dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_1:%.*]] = icmp uge ptr [[DST_ADD_1]], [[LOWER]]
95dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 1
96dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_3:%.*]] = icmp uge ptr [[DST_ADD_3]], [[LOWER]]
97dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_3]]
98dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 3
99dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
100dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
101dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
102dbe86a90SFlorian Hahn;
103dbe86a90SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
104dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
105dbe86a90SFlorian Hahn  %dst.add.3 = getelementptr i8, ptr %dst, i64 3
106dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr i8, ptr %dst, i64 1
107dbe86a90SFlorian Hahn  %cmp.add.1 = icmp uge ptr %dst.add.1, %lower
108dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr inbounds i8, ptr %dst.add.1, i64 1
109dbe86a90SFlorian Hahn  %cmp.add.3 = icmp uge ptr %dst.add.3, %lower
110dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.3
111dbe86a90SFlorian Hahn  %dst.add.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 3
112dbe86a90SFlorian Hahn  %cmp.add.4 = icmp uge ptr %dst.add.4, %lower
113dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.add.4
114dbe86a90SFlorian Hahn  ret i1 %res.2
115dbe86a90SFlorian Hahn}
116dbe86a90SFlorian Hahn
117dbe86a90SFlorian Hahndefine i1 @gep_add_1_uge_no_inbounds(ptr %dst, ptr %lower) {
118dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_uge_no_inbounds(
119dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
120dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
121dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
122dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr i8, ptr [[DST]], i64 1
123dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_1:%.*]] = icmp uge ptr [[DST_ADD_1]], [[LOWER]]
124dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr i8, ptr [[DST_ADD_1]], i64 1
125dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_3:%.*]] = icmp uge ptr [[DST_ADD_3]], [[LOWER]]
126dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_3]]
127dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 3
128dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
129dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
130dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
131dbe86a90SFlorian Hahn;
132dbe86a90SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
133dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
134dbe86a90SFlorian Hahn  %dst.add.3 = getelementptr i8, ptr %dst, i64 3
135dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr i8, ptr %dst, i64 1
136dbe86a90SFlorian Hahn  %cmp.add.1 = icmp uge ptr %dst.add.1, %lower
137dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr i8, ptr %dst.add.1, i64 1
138dbe86a90SFlorian Hahn  %cmp.add.3 = icmp uge ptr %dst.add.3, %lower
139dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.3
140dbe86a90SFlorian Hahn  %dst.add.4 = getelementptr i8, ptr %dst.add.3, i64 3
141dbe86a90SFlorian Hahn  %cmp.add.4 = icmp uge ptr %dst.add.4, %lower
142dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.add.4
143dbe86a90SFlorian Hahn  ret i1 %res.2
144dbe86a90SFlorian Hahn}
145dbe86a90SFlorian Hahn
146dbe86a90SFlorian Hahndefine i1 @gep_add_1_ult(ptr %dst, ptr %lower, ptr %upper) {
147dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_ult(
148dbe86a90SFlorian Hahn; CHECK-NEXT:    [[END:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
149dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp ult ptr [[END]], [[UPPER:%.*]]
150dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
151dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1
152dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 2
153dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 3
154dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
155dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 4
156dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_5:%.*]] = icmp ult ptr [[DST_ADD_5]], [[UPPER]]
157dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_5]]
158dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
159dbe86a90SFlorian Hahn;
160dbe86a90SFlorian Hahn  %end = getelementptr inbounds i8, ptr %dst, i64 4
161dbe86a90SFlorian Hahn  %pre = icmp ult ptr %end, %upper
162dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
163dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst, i64 1
164dbe86a90SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst.add.1, i64 2
165dbe86a90SFlorian Hahn  %cmp.add.3 = icmp ult ptr %dst.add.3, %upper
166dbe86a90SFlorian Hahn  %dst.add.4 = getelementptr inbounds i8, ptr %dst.add.1, i64 3
167dbe86a90SFlorian Hahn  %cmp.add.4 = icmp ult ptr %dst.add.4, %upper
168dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.3, %cmp.add.4
169dbe86a90SFlorian Hahn  %dst.add.5 = getelementptr inbounds i8, ptr %dst.add.1, i64 4
170dbe86a90SFlorian Hahn  %cmp.add.5 = icmp ult ptr %dst.add.5, %upper
171dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.add.5
172dbe86a90SFlorian Hahn  ret i1 %res.2
173dbe86a90SFlorian Hahn}
174dbe86a90SFlorian Hahn
175dbe86a90SFlorian Hahndefine i1 @gep_add_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {
176dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_ult_var_idx(
177dbe86a90SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[IDX:%.*]], 0
178dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
179dbe86a90SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
180dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
181dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
182dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
183dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 1
184dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
185dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_2:%.*]] = icmp ule ptr [[DST_ADD_2]], [[UPPER]]
186dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_ADD_2]]
187dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_1]]
188dbe86a90SFlorian Hahn;
189dbe86a90SFlorian Hahn  %not.zero = icmp ne i8 %idx, 0
190dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
191dbe86a90SFlorian Hahn  %idx.ext = zext i8 %idx to i16
192dbe86a90SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
193dbe86a90SFlorian Hahn  %pre = icmp ult ptr %dst.add.idx, %upper
194dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
195dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 1
196dbe86a90SFlorian Hahn  %cmp.add.1 = icmp ule ptr %dst.add.1, %upper
197dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 2
198dbe86a90SFlorian Hahn  %cmp.add.2 = icmp ule ptr %dst.add.2, %upper
199dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.2
200dbe86a90SFlorian Hahn  ret i1 %res.1
201dbe86a90SFlorian Hahn}
202dbe86a90SFlorian Hahn
203dbe86a90SFlorian Hahndefine i1 @gep_add_ult_var_idx_sgt_1(ptr %dst, ptr %upper, i8 %idx) {
204dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_ult_var_idx_sgt_1(
205dbe86a90SFlorian Hahn; CHECK-NEXT:    [[SGT_1:%.*]] = icmp sgt i8 [[IDX:%.*]], 1
206dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGT_1]])
207dbe86a90SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
208dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
209dbe86a90SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
210dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
211dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 1
212dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
213dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_2:%.*]] = icmp ule ptr [[DST_ADD_2]], [[UPPER]]
214dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_ADD_2]]
215dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_1]]
216dbe86a90SFlorian Hahn;
217dbe86a90SFlorian Hahn  %sgt.1 = icmp sgt i8 %idx, 1
218dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %sgt.1)
219dbe86a90SFlorian Hahn  %idx.ext = zext i8 %idx to i16
220dbe86a90SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
221dbe86a90SFlorian Hahn  %pre = icmp ult ptr %dst.add.idx, %upper
222dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %pre)
223dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 1
224dbe86a90SFlorian Hahn  %cmp.add.1 = icmp ule ptr %dst.add.1, %upper
225dbe86a90SFlorian Hahn  %dst.add.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 2
226dbe86a90SFlorian Hahn  %cmp.add.2 = icmp ule ptr %dst.add.2, %upper
227dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.add.1, %cmp.add.2
228dbe86a90SFlorian Hahn  ret i1 %res.1
229dbe86a90SFlorian Hahn}
230dbe86a90SFlorian Hahn
231dbe86a90SFlorian Hahndefine i1 @gep_add_1_ult_var_idx_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
232dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_ult_var_idx_inbounds(
233dbe86a90SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
234dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
235dbe86a90SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
236dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
237dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 1
238dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_1:%.*]] = icmp ult ptr [[DST_ADD_1]], [[UPPER:%.*]]
239dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_ADD_1]])
240dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
241dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
242dbe86a90SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
243dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
244dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 1
245dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
246dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
247dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 3
248dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
249dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
250dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
251dbe86a90SFlorian Hahn;
252dbe86a90SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
253dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
254dbe86a90SFlorian Hahn  %len.ext = zext i8 %len to i16
255dbe86a90SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
256dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 1
257dbe86a90SFlorian Hahn  %cmp.add.1 = icmp ult ptr %dst.add.1, %upper
258dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %cmp.add.1)
259dbe86a90SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
260dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
261dbe86a90SFlorian Hahn  %idx.ext = zext i8 %idx to i16
262dbe86a90SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
263dbe86a90SFlorian Hahn  %dst.add.idx.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 1
264dbe86a90SFlorian Hahn  %cmp.idx.1 = icmp ult ptr %dst.add.idx.1, %upper
265dbe86a90SFlorian Hahn  %dst.add.idx.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 2
266dbe86a90SFlorian Hahn  %cmp.idx.2 = icmp ult ptr %dst.add.idx.2, %upper
267dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.idx.1, %cmp.idx.2
268dbe86a90SFlorian Hahn  %dst.add.idx.3 = getelementptr inbounds i8, ptr %dst.add.idx, i64 3
269dbe86a90SFlorian Hahn  %cmp.idx.3 = icmp ult ptr %dst.add.idx.3, %upper
270dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.idx.3
271dbe86a90SFlorian Hahn  ret i1 %res.2
272dbe86a90SFlorian Hahn}
273dbe86a90SFlorian Hahn
274dbe86a90SFlorian Hahndefine i1 @gep_add_1_ult_var_idx_only_inner_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
275dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_ult_var_idx_only_inner_inbounds(
276dbe86a90SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
277dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
278dbe86a90SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
279dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
280dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 1
281dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_1:%.*]] = icmp ult ptr [[DST_ADD_1]], [[UPPER:%.*]]
282dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_ADD_1]])
283dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
284dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
285dbe86a90SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
286dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
287dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_1:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 1
288dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_1:%.*]] = icmp ult ptr [[DST_ADD_IDX_1]], [[UPPER]]
289dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_2:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 2
290dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_2:%.*]] = icmp ult ptr [[DST_ADD_IDX_2]], [[UPPER]]
291dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_IDX_1]], [[CMP_IDX_2]]
292dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_3:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 3
293dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
294dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
295dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
296dbe86a90SFlorian Hahn;
297dbe86a90SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
298dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
299dbe86a90SFlorian Hahn  %len.ext = zext i8 %len to i16
300dbe86a90SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
301dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 1
302dbe86a90SFlorian Hahn  %cmp.add.1 = icmp ult ptr %dst.add.1, %upper
303dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %cmp.add.1)
304dbe86a90SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
305dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
306dbe86a90SFlorian Hahn  %idx.ext = zext i8 %idx to i16
307dbe86a90SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
308dbe86a90SFlorian Hahn  %dst.add.idx.1 = getelementptr i8, ptr %dst.add.idx, i64 1
309dbe86a90SFlorian Hahn  %cmp.idx.1 = icmp ult ptr %dst.add.idx.1, %upper
310dbe86a90SFlorian Hahn  %dst.add.idx.2 = getelementptr i8, ptr %dst.add.idx, i64 2
311dbe86a90SFlorian Hahn  %cmp.idx.2 = icmp ult ptr %dst.add.idx.2, %upper
312dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.idx.1, %cmp.idx.2
313dbe86a90SFlorian Hahn  %dst.add.idx.3 = getelementptr i8, ptr %dst.add.idx, i64 3
314dbe86a90SFlorian Hahn  %cmp.idx.3 = icmp ult ptr %dst.add.idx.3, %upper
315dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.idx.3
316dbe86a90SFlorian Hahn  ret i1 %res.2
317dbe86a90SFlorian Hahn}
318dbe86a90SFlorian Hahn
319dbe86a90SFlorian Hahndefine i1 @gep_add_1_ult_var_idx_no_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
320dbe86a90SFlorian Hahn; CHECK-LABEL: @gep_add_1_ult_var_idx_no_inbounds(
321dbe86a90SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
322dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
323dbe86a90SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
324dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
325dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 1
326dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_ADD_1:%.*]] = icmp ult ptr [[DST_ADD_1]], [[UPPER:%.*]]
327dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_ADD_1]])
328dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
329dbe86a90SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
330dbe86a90SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
331dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr i8, ptr [[DST]], i16 [[IDX_EXT]]
332dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_1:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 1
333dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_1:%.*]] = icmp ult ptr [[DST_ADD_IDX_1]], [[UPPER]]
334dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_2:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 2
335dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_2:%.*]] = icmp ult ptr [[DST_ADD_IDX_2]], [[UPPER]]
336dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_IDX_1]], [[CMP_IDX_2]]
337dbe86a90SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX_3:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 3
338dbe86a90SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
339dbe86a90SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
340dbe86a90SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
341dbe86a90SFlorian Hahn;
342dbe86a90SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
343dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
344dbe86a90SFlorian Hahn  %len.ext = zext i8 %len to i16
345dbe86a90SFlorian Hahn  %dst.add.len = getelementptr i8, ptr %dst, i16 %len.ext
346dbe86a90SFlorian Hahn  %dst.add.1 = getelementptr i8, ptr %dst.add.len, i64 1
347dbe86a90SFlorian Hahn  %cmp.add.1 = icmp ult ptr %dst.add.1, %upper
348dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %cmp.add.1)
349dbe86a90SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
350dbe86a90SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
351dbe86a90SFlorian Hahn  %idx.ext = zext i8 %idx to i16
352dbe86a90SFlorian Hahn  %dst.add.idx = getelementptr i8, ptr %dst, i16 %idx.ext
353dbe86a90SFlorian Hahn  %dst.add.idx.1 = getelementptr i8, ptr %dst.add.idx, i64 1
354dbe86a90SFlorian Hahn  %cmp.idx.1 = icmp ult ptr %dst.add.idx.1, %upper
355dbe86a90SFlorian Hahn  %dst.add.idx.2 = getelementptr i8, ptr %dst.add.idx, i64 2
356dbe86a90SFlorian Hahn  %cmp.idx.2 = icmp ult ptr %dst.add.idx.2, %upper
357dbe86a90SFlorian Hahn  %res.1 = xor i1 %cmp.idx.1, %cmp.idx.2
358dbe86a90SFlorian Hahn  %dst.add.idx.3 = getelementptr i8, ptr %dst.add.idx, i64 3
359dbe86a90SFlorian Hahn  %cmp.idx.3 = icmp ult ptr %dst.add.idx.3, %upper
360dbe86a90SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.idx.3
361dbe86a90SFlorian Hahn  ret i1 %res.2
362dbe86a90SFlorian Hahn}
36321cc7400SFlorian Hahn
36421cc7400SFlorian Hahndefine i1 @test_chained_no_inbounds(ptr %A, ptr %B) {
365*bbe402b3SFlorian Hahn; CHECK-LABEL: @test_chained_no_inbounds(
366*bbe402b3SFlorian Hahn; CHECK-NEXT:  entry:
367*bbe402b3SFlorian Hahn; CHECK-NEXT:    [[B_1:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 1
368*bbe402b3SFlorian Hahn; CHECK-NEXT:    [[B_2:%.*]] = getelementptr i8, ptr [[B_1]], i64 1
369*bbe402b3SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt ptr [[A:%.*]], null
370*bbe402b3SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[B_1]], [[B_2]]
371*bbe402b3SFlorian Hahn; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[C_2]]
372*bbe402b3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
373*bbe402b3SFlorian Hahn; CHECK:       then:
374*bbe402b3SFlorian Hahn; CHECK-NEXT:    ret i1 true
375*bbe402b3SFlorian Hahn; CHECK:       else:
376*bbe402b3SFlorian Hahn; CHECK-NEXT:    ret i1 false
377*bbe402b3SFlorian Hahn;
37821cc7400SFlorian Hahnentry:
37921cc7400SFlorian Hahn  %B.1 = getelementptr i8, ptr %B, i64 1
38021cc7400SFlorian Hahn  %B.2 = getelementptr i8, ptr %B.1, i64 1
38121cc7400SFlorian Hahn  %c.1 = icmp ugt ptr %A, null
38221cc7400SFlorian Hahn  %c.2 = icmp ugt ptr %B.1, %B.2
38321cc7400SFlorian Hahn  %or = or i1 %c.1, %c.2
38421cc7400SFlorian Hahn  br i1 %or, label %then, label %else
38521cc7400SFlorian Hahn
38621cc7400SFlorian Hahnthen:
38721cc7400SFlorian Hahn  ret i1 true
38821cc7400SFlorian Hahn
38921cc7400SFlorian Hahnelse:
39021cc7400SFlorian Hahn  ret i1 false
39121cc7400SFlorian Hahn}
392