[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / gep-sub.ll
blob6bc2a342eae828b17ce949a735fb2f9cbe527a60
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
30   ret i1 %res.2
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
59   ret i1 %res.2
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
88   ret i1 %res.2
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
117   ret i1 %res.2
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
140   ret i1 %res.1
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
177   ret i1 %res.3
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
209   ret i1 %res.2
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
239   ret i1 %cmp.idx
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
270   ret i1 %cmp.idx
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
301   ret i1 %cmp.idx
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
332   ret i1 %cmp.idx
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
362   ret i1 %cmp.idx
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
392   ret i1 %cmp.idx
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
423   ret i1 %cmp.idx
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(
428 ; CHECK-NEXT:  entry:
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]]
438 entry:
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
448   ret i1 %res
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(
453 ; CHECK-NEXT:  entry:
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
464 entry:
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
477   ret i1 %res
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(
482 ; CHECK-NEXT:  entry:
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]]
494 entry:
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
507   ret i1 %res
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
534   ret i1 %res.2
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
563   ret i1 %res.2
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
591   ret i1 %c
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
612   ret i1 %c
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
637   ret i1 %c