1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 declare void @llvm.assume(i1 noundef)
6 define i1 @gep_sub_1_uge_inbounds(ptr %dst, ptr %lower) {
7 ; CHECK-LABEL: @gep_sub_1_uge_inbounds(
8 ; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
9 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
10 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
11 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1
12 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
13 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
14 ; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -4
15 ; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
16 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
17 ; CHECK-NEXT: ret i1 [[RES_2]]
19 %pre = icmp uge ptr %dst, %lower
20 call void @llvm.assume(i1 %pre)
21 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
22 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1
23 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
24 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3
25 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
26 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
27 %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -4
28 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
29 %res.2 = xor i1 %res.1, %cmp.sub.4
33 define i1 @gep_sub_1_uge_only_inner_inbounds(ptr %dst, ptr %lower) {
34 ; CHECK-LABEL: @gep_sub_1_uge_only_inner_inbounds(
35 ; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
36 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
37 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
38 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -1
39 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
40 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -3
41 ; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
42 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
43 ; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -4
44 ; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
45 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
46 ; CHECK-NEXT: ret i1 [[RES_2]]
48 %pre = icmp uge ptr %dst, %lower
49 call void @llvm.assume(i1 %pre)
50 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
51 %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1
52 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
53 %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3
54 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
55 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
56 %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4
57 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
58 %res.2 = xor i1 %res.1, %cmp.sub.4
62 define i1 @gep_sub_1_uge_only_outer_inbounds(ptr %dst, ptr %lower) {
63 ; CHECK-LABEL: @gep_sub_1_uge_only_outer_inbounds(
64 ; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
65 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
66 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
67 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1
68 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
69 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
70 ; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
71 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
72 ; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -4
73 ; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
74 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
75 ; CHECK-NEXT: ret i1 [[RES_2]]
77 %pre = icmp uge ptr %dst, %lower
78 call void @llvm.assume(i1 %pre)
79 %dst.add.3 = getelementptr i8, ptr %dst, i64 3
80 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1
81 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
82 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3
83 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
84 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
85 %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -4
86 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
87 %res.2 = xor i1 %res.1, %cmp.sub.4
91 define i1 @gep_sub_1_uge_no_inbounds(ptr %dst, ptr %lower) {
92 ; CHECK-LABEL: @gep_sub_1_uge_no_inbounds(
93 ; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
94 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
95 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
96 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -1
97 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
98 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -3
99 ; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
100 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
101 ; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -4
102 ; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
103 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
104 ; CHECK-NEXT: ret i1 [[RES_2]]
106 %pre = icmp uge ptr %dst, %lower
107 call void @llvm.assume(i1 %pre)
108 %dst.add.3 = getelementptr i8, ptr %dst, i64 3
109 %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1
110 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
111 %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3
112 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
113 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
114 %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4
115 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
116 %res.2 = xor i1 %res.1, %cmp.sub.4
120 define i1 @gep_sub_1_ult(ptr %dst, ptr %upper) {
121 ; CHECK-LABEL: @gep_sub_1_ult(
122 ; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
123 ; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_4]], [[UPPER:%.*]]
124 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
125 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
126 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1
127 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
128 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
129 ; CHECK-NEXT: ret i1 [[RES_1]]
131 %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
132 %pre = icmp ult ptr %dst.add.4, %upper
133 call void @llvm.assume(i1 %pre)
134 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
135 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1
136 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
137 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3
138 %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper
139 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
143 define i1 @gep_sub_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {
144 ; CHECK-LABEL: @gep_sub_ult_var_idx(
145 ; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[IDX:%.*]], 0
146 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
147 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
148 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
149 ; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
150 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
151 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -1
152 ; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2
153 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
154 ; CHECK-NEXT: [[DST_SUB_1_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_SUB_1]], i64 -1
155 ; CHECK-NEXT: [[CMP_SUB_1_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1_SUB_1]], [[UPPER]]
156 ; CHECK-NEXT: [[CMP_SUB_1_SUB_1_EQ:%.*]] = icmp eq ptr [[DST_SUB_1_SUB_1]], [[DST_SUB_2]]
157 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_1_SUB_1]]
158 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_SUB_1_SUB_1_EQ]]
159 ; CHECK-NEXT: ret i1 [[RES_3]]
161 %not.zero = icmp ne i8 %idx, 0
162 call void @llvm.assume(i1 %not.zero)
163 %idx.ext = zext i8 %idx to i16
164 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
165 %pre = icmp ult ptr %dst.add.idx, %upper
166 call void @llvm.assume(i1 %pre)
167 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1
168 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
169 %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2
170 %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper
171 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
172 %dst.sub.1.sub.1 = getelementptr inbounds i8, ptr %dst.sub.1, i64 -1
173 %cmp.sub.1.sub.1 = icmp ult ptr %dst.sub.1.sub.1, %upper
174 %cmp.sub.1.sub.1.eq = icmp eq ptr %dst.sub.1.sub.1, %dst.sub.2
175 %res.2 = xor i1 %res.1, %cmp.sub.1.sub.1
176 %res.3 = xor i1 %res.2, %cmp.sub.1.sub.1.eq
180 define i1 @gep_sub_ult_var_idx_sgt_1(ptr %dst, ptr %upper, i8 %idx) {
181 ; CHECK-LABEL: @gep_sub_ult_var_idx_sgt_1(
182 ; CHECK-NEXT: [[SGT_1:%.*]] = icmp sgt i8 [[IDX:%.*]], 1
183 ; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]])
184 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
185 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
186 ; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
187 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
188 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -1
189 ; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2
190 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
191 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -3
192 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
193 ; CHECK-NEXT: ret i1 [[RES_2]]
195 %sgt.1 = icmp sgt i8 %idx, 1
196 call void @llvm.assume(i1 %sgt.1)
197 %idx.ext = zext i8 %idx to i16
198 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
199 %pre = icmp ult ptr %dst.add.idx, %upper
200 call void @llvm.assume(i1 %pre)
201 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1
202 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
203 %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2
204 %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper
205 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
206 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -3
207 %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper
208 %res.2 = xor i1 %res.1, %cmp.sub.3
212 define i1 @gep_sub_1_ult_var_idx_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
213 ; CHECK-LABEL: @gep_sub_1_ult_var_idx_inbounds(
214 ; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
215 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
216 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
217 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
218 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1
219 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
220 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
221 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
222 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
223 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
224 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
225 ; CHECK-NEXT: ret i1 true
227 %not.zero = icmp ne i8 %len, 0
228 call void @llvm.assume(i1 %not.zero)
229 %len.ext = zext i8 %len to i16
230 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
231 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1
232 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
233 call void @llvm.assume(i1 %cmp.sub.1)
234 %cmp.idx.ult.len = icmp ult i8 %idx, %len
235 call void @llvm.assume(i1 %cmp.idx.ult.len)
236 %idx.ext = zext i8 %idx to i16
237 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
238 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
242 define i1 @gep_sub_1_ult_var_idx_only_inner_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
243 ; CHECK-LABEL: @gep_sub_1_ult_var_idx_only_inner_inbounds(
244 ; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
245 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
246 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
247 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
248 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 -1
249 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
250 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
251 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
252 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
253 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
254 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
255 ; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
256 ; CHECK-NEXT: ret i1 [[CMP_IDX]]
258 %not.zero = icmp ne i8 %len, 0
259 call void @llvm.assume(i1 %not.zero)
260 %len.ext = zext i8 %len to i16
261 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
262 %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1
263 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
264 call void @llvm.assume(i1 %cmp.sub.1)
265 %cmp.idx.ult.len = icmp ult i8 %idx, %len
266 call void @llvm.assume(i1 %cmp.idx.ult.len)
267 %idx.ext = zext i8 %idx to i16
268 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
269 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
273 define i1 @gep_sub_1_ult_var_idx_no_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
274 ; CHECK-LABEL: @gep_sub_1_ult_var_idx_no_inbounds(
275 ; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
276 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
277 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
278 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
279 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 -1
280 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
281 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
282 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
283 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
284 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
285 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr i8, ptr [[DST]], i16 [[IDX_EXT]]
286 ; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
287 ; CHECK-NEXT: ret i1 [[CMP_IDX]]
289 %not.zero = icmp ne i8 %len, 0
290 call void @llvm.assume(i1 %not.zero)
291 %len.ext = zext i8 %len to i16
292 %dst.add.len = getelementptr i8, ptr %dst, i16 %len.ext
293 %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1
294 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
295 call void @llvm.assume(i1 %cmp.sub.1)
296 %cmp.idx.ult.len = icmp ult i8 %idx, %len
297 call void @llvm.assume(i1 %cmp.idx.ult.len)
298 %idx.ext = zext i8 %idx to i16
299 %dst.add.idx = getelementptr i8, ptr %dst, i16 %idx.ext
300 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
304 define i1 @gep_sub_2_ult_var_idx(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
305 ; CHECK-LABEL: @gep_sub_2_ult_var_idx(
306 ; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
307 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
308 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
309 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
310 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -2
311 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
312 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
313 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
314 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
315 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
316 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
317 ; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
318 ; CHECK-NEXT: ret i1 [[CMP_IDX]]
320 %not.zero = icmp ne i8 %len, 0
321 call void @llvm.assume(i1 %not.zero)
322 %len.ext = zext i8 %len to i16
323 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
324 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2
325 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
326 call void @llvm.assume(i1 %cmp.sub.1)
327 %cmp.idx.ult.len = icmp ult i8 %idx, %len
328 call void @llvm.assume(i1 %cmp.idx.ult.len)
329 %idx.ext = zext i8 %idx to i16
330 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
331 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
335 define i1 @gep_sub_2_ult_var_idx_inbounds_len_sge_2(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
336 ; CHECK-LABEL: @gep_sub_2_ult_var_idx_inbounds_len_sge_2(
337 ; CHECK-NEXT: [[SGE_2:%.*]] = icmp sge i8 [[LEN:%.*]], 2
338 ; CHECK-NEXT: call void @llvm.assume(i1 [[SGE_2]])
339 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
340 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
341 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1
342 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
343 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
344 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
345 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
346 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
347 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
348 ; CHECK-NEXT: ret i1 true
350 %sge.2 = icmp sge i8 %len, 2
351 call void @llvm.assume(i1 %sge.2)
352 %len.ext = zext i8 %len to i16
353 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
354 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1
355 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
356 call void @llvm.assume(i1 %cmp.sub.1)
357 %cmp.idx.ult.len = icmp ult i8 %idx, %len
358 call void @llvm.assume(i1 %cmp.idx.ult.len)
359 %idx.ext = zext i8 %idx to i16
360 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
361 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
365 define i1 @gep_sub_2_ult_var_idx_inbounds_len_uge_2(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
366 ; CHECK-LABEL: @gep_sub_2_ult_var_idx_inbounds_len_uge_2(
367 ; CHECK-NEXT: [[UGE_2:%.*]] = icmp uge i8 [[LEN:%.*]], 2
368 ; CHECK-NEXT: call void @llvm.assume(i1 [[UGE_2]])
369 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
370 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
371 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1
372 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
373 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
374 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
375 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
376 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
377 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
378 ; CHECK-NEXT: ret i1 true
380 %uge.2 = icmp uge i8 %len, 2
381 call void @llvm.assume(i1 %uge.2)
382 %len.ext = zext i8 %len to i16
383 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
384 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1
385 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
386 call void @llvm.assume(i1 %cmp.sub.1)
387 %cmp.idx.ult.len = icmp ult i8 %idx, %len
388 call void @llvm.assume(i1 %cmp.idx.ult.len)
389 %idx.ext = zext i8 %idx to i16
390 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
391 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
395 define i1 @gep_sub_ult_var_idx_len_sgt_1(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
396 ; CHECK-LABEL: @gep_sub_ult_var_idx_len_sgt_1(
397 ; CHECK-NEXT: [[SGT_1:%.*]] = icmp sgt i8 [[LEN:%.*]], 1
398 ; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]])
399 ; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
400 ; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
401 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -2
402 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
403 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])
404 ; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
405 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
406 ; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
407 ; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
408 ; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
409 ; CHECK-NEXT: ret i1 [[CMP_IDX]]
411 %sgt.1 = icmp sgt i8 %len, 1
412 call void @llvm.assume(i1 %sgt.1)
413 %len.ext = zext i8 %len to i16
414 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
415 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2
416 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
417 call void @llvm.assume(i1 %cmp.sub.1)
418 %cmp.idx.ult.len = icmp ult i8 %idx, %len
419 call void @llvm.assume(i1 %cmp.idx.ult.len)
420 %idx.ext = zext i8 %idx to i16
421 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
422 %cmp.idx = icmp ult ptr %dst.add.idx, %upper
426 define i1 @gep_sub_1_ult_var_idx_lower_bound(ptr %lower, ptr %src, i8 %len) {
427 ; CHECK-LABEL: @gep_sub_1_ult_var_idx_lower_bound(
429 ; CHECK-NEXT: [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]
430 ; CHECK-NEXT: call void @llvm.assume(i1 [[SRC_UGE_LOWER]])
431 ; CHECK-NEXT: [[LEN_POS:%.*]] = icmp sge i8 [[LEN:%.*]], 0
432 ; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_POS]])
433 ; CHECK-NEXT: [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]
434 ; CHECK-NEXT: [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -1
435 ; CHECK-NEXT: [[RES:%.*]] = icmp ult ptr [[GEP_SUB_1]], [[LOWER]]
436 ; CHECK-NEXT: ret i1 [[RES]]
439 %src.uge.lower = icmp uge ptr %src, %lower
440 call void @llvm.assume(i1 %src.uge.lower)
442 %len.pos = icmp sge i8 %len, 0
443 call void @llvm.assume(i1 %len.pos)
445 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len
446 %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1
447 %res = icmp ult ptr %gep.sub.1, %lower
451 define i1 @gep_sub_1_ult_var_idx_lower_bound_len_ne_0(ptr %lower, ptr %src, i8 %len) {
452 ; CHECK-LABEL: @gep_sub_1_ult_var_idx_lower_bound_len_ne_0(
454 ; CHECK-NEXT: [[LEN_NE_0:%.*]] = icmp ne i8 [[LEN:%.*]], 0
455 ; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NE_0]])
456 ; CHECK-NEXT: [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]
457 ; CHECK-NEXT: call void @llvm.assume(i1 [[SRC_UGE_LOWER]])
458 ; CHECK-NEXT: [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0
459 ; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_POS]])
460 ; CHECK-NEXT: [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]
461 ; CHECK-NEXT: [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -1
462 ; CHECK-NEXT: ret i1 false
465 %len.ne.0 = icmp ne i8 %len, 0
466 call void @llvm.assume(i1 %len.ne.0)
468 %src.uge.lower = icmp uge ptr %src, %lower
469 call void @llvm.assume(i1 %src.uge.lower)
471 %len.pos = icmp sge i8 %len, 0
472 call void @llvm.assume(i1 %len.pos)
474 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len
475 %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1
476 %res = icmp ult ptr %gep.sub.1, %lower
480 define i1 @gep_sub_2_ult_var_idx_lower_bound_len_ne_0(ptr %lower, ptr %src, i8 %len) {
481 ; CHECK-LABEL: @gep_sub_2_ult_var_idx_lower_bound_len_ne_0(
483 ; CHECK-NEXT: [[LEN_NE_0:%.*]] = icmp ne i8 [[LEN:%.*]], 0
484 ; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NE_0]])
485 ; CHECK-NEXT: [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]
486 ; CHECK-NEXT: call void @llvm.assume(i1 [[SRC_UGE_LOWER]])
487 ; CHECK-NEXT: [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0
488 ; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_POS]])
489 ; CHECK-NEXT: [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]
490 ; CHECK-NEXT: [[GEP_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -2
491 ; CHECK-NEXT: [[RES:%.*]] = icmp ult ptr [[GEP_SUB_2]], [[LOWER]]
492 ; CHECK-NEXT: ret i1 [[RES]]
495 %len.ne.0 = icmp ne i8 %len, 0
496 call void @llvm.assume(i1 %len.ne.0)
498 %src.uge.lower = icmp uge ptr %src, %lower
499 call void @llvm.assume(i1 %src.uge.lower)
501 %len.pos = icmp sge i8 %len, 0
502 call void @llvm.assume(i1 %len.pos)
504 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len
505 %gep.sub.2 = getelementptr inbounds i8, ptr %gep.len, i8 -2
506 %res = icmp ult ptr %gep.sub.2, %lower
510 define i1 @gep_i16_sub_1_uge_inbounds(ptr %dst, ptr %lower) {
511 ; CHECK-LABEL: @gep_i16_sub_1_uge_inbounds(
512 ; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
513 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
514 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
515 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -1
516 ; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2
517 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, true
518 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3
519 ; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[LOWER]]
520 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]
521 ; CHECK-NEXT: ret i1 [[RES_2]]
523 %pre = icmp uge ptr %dst, %lower
524 call void @llvm.assume(i1 %pre)
525 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
526 %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i64 -1
527 %cmp.sub.1 = icmp ule ptr %dst.sub.1, %lower
528 %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2
529 %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst
530 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
531 %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3
532 %cmp.sub.3 = icmp ule ptr %dst.sub.3, %lower
533 %res.2 = xor i1 %res.1, %cmp.sub.3
537 define i1 @gep_i16_sub_1_uge_inbounds_var_idx(ptr %dst, i64 %off) {
538 ; CHECK-LABEL: @gep_i16_sub_1_uge_inbounds_var_idx(
539 ; CHECK-NEXT: [[OFF_UGE:%.*]] = icmp sge i64 [[OFF:%.*]], 1
540 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_UGE]])
541 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[OFF]]
542 ; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i32 -1
543 ; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ule ptr [[DST_SUB_1]], [[DST]]
544 ; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2
545 ; CHECK-NEXT: [[CMP_SUB_2:%.*]] = icmp ule ptr [[DST_SUB_2]], [[DST]]
546 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_2]]
547 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3
548 ; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[DST]]
549 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]
550 ; CHECK-NEXT: ret i1 [[RES_2]]
552 %off.uge = icmp sge i64 %off, 1
553 call void @llvm.assume(i1 %off.uge)
554 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 %off
555 %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i32 -1
556 %cmp.sub.1 = icmp ule ptr %dst.sub.1, %dst
557 %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2
558 %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst
559 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
560 %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3
561 %cmp.sub.3 = icmp ule ptr %dst.sub.3, %dst
562 %res.2 = xor i1 %res.1, %cmp.sub.3
566 define i1 @gep_i32_two_indices_known_lt_and_positive(ptr %a, i8 %idx.1, i8 %idx.2) {
567 ; CHECK-LABEL: @gep_i32_two_indices_known_lt_and_positive(
568 ; CHECK-NEXT: [[LT:%.*]] = icmp ult i8 [[IDX_1:%.*]], [[IDX_2:%.*]]
569 ; CHECK-NEXT: call void @llvm.assume(i1 [[LT]])
570 ; CHECK-NEXT: [[IDX_1_POS:%.*]] = icmp sge i8 [[IDX_1]], 0
571 ; CHECK-NEXT: [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2]], 0
572 ; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_1_POS]])
573 ; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_2_POS]])
574 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]
575 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3
576 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]
577 ; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3
578 ; CHECK-NEXT: ret i1 true
580 %lt = icmp ult i8 %idx.1, %idx.2
581 call void @llvm.assume(i1 %lt)
582 %idx.1.pos = icmp sge i8 %idx.1, 0
583 %idx.2.pos = icmp sge i8 %idx.2, 0
584 call void @llvm.assume(i1 %idx.1.pos)
585 call void @llvm.assume(i1 %idx.2.pos)
586 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1
587 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3
588 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2
589 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3
590 %c = icmp ult ptr %gep.2, %gep.4
594 define i1 @gep_i32_two_indices_known_lt_and_not_known_positive(ptr %a, i8 %idx.1, i8 %idx.2) {
595 ; CHECK-LABEL: @gep_i32_two_indices_known_lt_and_not_known_positive(
596 ; CHECK-NEXT: [[LT:%.*]] = icmp ult i8 [[IDX_1:%.*]], [[IDX_2:%.*]]
597 ; CHECK-NEXT: call void @llvm.assume(i1 [[LT]])
598 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]
599 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3
600 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]
601 ; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3
602 ; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_2]], [[GEP_4]]
603 ; CHECK-NEXT: ret i1 [[C]]
605 %lt = icmp ult i8 %idx.1, %idx.2
606 call void @llvm.assume(i1 %lt)
607 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1
608 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3
609 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2
610 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3
611 %c = icmp ult ptr %gep.2, %gep.4
615 define i1 @gep_i32_two_indices_known_positive_but_not_lt(ptr %a, i8 %idx.1, i8 %idx.2) {
616 ; CHECK-LABEL: @gep_i32_two_indices_known_positive_but_not_lt(
617 ; CHECK-NEXT: [[IDX_1_POS:%.*]] = icmp sge i8 [[IDX_1:%.*]], 0
618 ; CHECK-NEXT: [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2:%.*]], 0
619 ; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_1_POS]])
620 ; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_2_POS]])
621 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]
622 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3
623 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]
624 ; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3
625 ; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_2]], [[GEP_4]]
626 ; CHECK-NEXT: ret i1 [[C]]
628 %idx.1.pos = icmp sge i8 %idx.1, 0
629 %idx.2.pos = icmp sge i8 %idx.2, 0
630 call void @llvm.assume(i1 %idx.1.pos)
631 call void @llvm.assume(i1 %idx.2.pos)
632 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1
633 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3
634 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2
635 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3
636 %c = icmp ult ptr %gep.2, %gep.4