[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / and-implied-by-operands.ll
blob6bbc73c9c996c8b428ddcd09fed0d37277aa872e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 define i1 @test_second_and_condition_implied_by_first(i8 %x) {
5 ; CHECK-LABEL: @test_second_and_condition_implied_by_first(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
8 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
9 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], true
10 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
11 ; CHECK:       then:
12 ; CHECK-NEXT:    ret i1 false
13 ; CHECK:       else:
14 ; CHECK-NEXT:    ret i1 true
16 entry:
17   %c.1 = icmp ugt i8 %x, 10
18   %t.1 = icmp ugt i8 %x, 5
19   %and = and i1 %c.1, %t.1
20   br i1 %and, label %then, label %else
22 then:
23   ret i1 0
25 else:
26   ret i1 1
29 define i1 @test_first_and_condition_implied_by_second_ops(i8 %x) {
30 ; CHECK-LABEL: @test_first_and_condition_implied_by_second_ops(
31 ; CHECK-NEXT:  entry:
32 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
33 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
34 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_1]]
35 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
36 ; CHECK:       then:
37 ; CHECK-NEXT:    ret i1 false
38 ; CHECK:       else:
39 ; CHECK-NEXT:    ret i1 true
41 entry:
42   %c.1 = icmp ugt i8 %x, 10
43   %t.1 = icmp ugt i8 %x, 5
44   %and = and i1 %t.1, %c.1
45   br i1 %and, label %then, label %else
47 then:
48   ret i1 0
50 else:
51   ret i1 1
54 define i1 @test_second_and_condition_implied_by_first_select_form(i8 %x) {
55 ; CHECK-LABEL: @test_second_and_condition_implied_by_first_select_form(
56 ; CHECK-NEXT:  entry:
57 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
58 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
59 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 true, i1 false
60 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
61 ; CHECK:       then:
62 ; CHECK-NEXT:    ret i1 false
63 ; CHECK:       else:
64 ; CHECK-NEXT:    ret i1 true
66 entry:
67   %c.1 = icmp ugt i8 %x, 10
68   %t.1 = icmp ugt i8 %x, 5
69   %and = select i1 %c.1, i1 %t.1, i1 false
70   br i1 %and, label %then, label %else
72 then:
73   ret i1 0
75 else:
76   ret i1 1
79 define i1 @test_first_and_condition_implied_by_second_select_form(i8 %x) {
80 ; CHECK-LABEL: @test_first_and_condition_implied_by_second_select_form(
81 ; CHECK-NEXT:  entry:
82 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
83 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
84 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[T_1]], i1 [[C_1]], i1 false
85 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
86 ; CHECK:       then:
87 ; CHECK-NEXT:    ret i1 false
88 ; CHECK:       else:
89 ; CHECK-NEXT:    ret i1 true
91 entry:
92   %c.1 = icmp ugt i8 %x, 10
93   %t.1 = icmp ugt i8 %x, 5
94   %and = select i1 %t.1, i1 %c.1, i1 false
95   br i1 %and, label %then, label %else
97 then:
98   ret i1 0
100 else:
101   ret i1 1
104 define i1 @test_same_cond_for_and(i8 %x) {
105 ; CHECK-LABEL: @test_same_cond_for_and(
106 ; CHECK-NEXT:  entry:
107 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
108 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_1]]
109 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
110 ; CHECK:       then:
111 ; CHECK-NEXT:    ret i1 false
112 ; CHECK:       else:
113 ; CHECK-NEXT:    ret i1 true
115 entry:
116   %c.1 = icmp ugt i8 %x, 10
117   %and = and i1 %c.1, %c.1
118   br i1 %and, label %then, label %else
120 then:
121   ret i1 0
123 else:
124   ret i1 1
127 define i1 @test_same_cond_for_and_select_form(i8 %x) {
128 ; CHECK-LABEL: @test_same_cond_for_and_select_form(
129 ; CHECK-NEXT:  entry:
130 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
131 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false
132 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
133 ; CHECK:       then:
134 ; CHECK-NEXT:    ret i1 false
135 ; CHECK:       else:
136 ; CHECK-NEXT:    ret i1 true
138 entry:
139   %c.1 = icmp ugt i8 %x, 10
140   %and = select i1 %c.1, i1 %c.1, i1 false
141   br i1 %and, label %then, label %else
143 then:
144   ret i1 0
146 else:
147   ret i1 1
150 define i1 @test_second_and_condition_not_implied_by_first(i8 %x) {
151 ; CHECK-LABEL: @test_second_and_condition_not_implied_by_first(
152 ; CHECK-NEXT:  entry:
153 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
154 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 5
155 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_1]]
156 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
157 ; CHECK:       then:
158 ; CHECK-NEXT:    ret i1 false
159 ; CHECK:       else:
160 ; CHECK-NEXT:    ret i1 true
162 entry:
163   %c.1 = icmp ugt i8 %x, 10
164   %c.2 = icmp ugt i8 %x, 5
165   %and = and i1 %c.2, %c.1
166   br i1 %and, label %then, label %else
168 then:
169   ret i1 0
171 else:
172   ret i1 1
175 define i1 @test_remove_variables(i1 %c, ptr %A, i64 %B, ptr %C) {
176 ; CHECK-LABEL: @test_remove_variables(
177 ; CHECK-NEXT:  entry:
178 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN_1:%.*]], label [[EXIT:%.*]]
179 ; CHECK:       then.1:
180 ; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C:%.*]], align 8
181 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[TMP0]], [[A:%.*]]
182 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN_2:%.*]], label [[ELSE_2:%.*]]
183 ; CHECK:       then.2:
184 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sgt i64 [[B:%.*]], 0
185 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_3]]
186 ; CHECK-NEXT:    ret i1 [[AND]]
187 ; CHECK:       else.2:
188 ; CHECK-NEXT:    ret i1 false
189 ; CHECK:       exit:
190 ; CHECK-NEXT:    ret i1 true
192 entry:
193   br i1 %c, label %then.1, label %exit
195 then.1:
196   %0 = load ptr, ptr %C, align 8
197   %c.1 = icmp ult ptr %0, %A
198   br i1 %c.1, label %then.2, label %else.2
200 then.2:
201   %c.2 = icmp ne ptr %A, null
202   %c.3 = icmp sgt i64 %B, 0
203   %and = and i1 %c.2, %c.3
204   ret i1 %and
206 else.2:
207   ret i1 0
209 exit:
210   %t = icmp eq ptr null, null
211   ret i1 %t
214 define i1 @test_and_op_0_simplified(i32 %v) {
215 ; CHECK-LABEL: @test_and_op_0_simplified(
216 ; CHECK-NEXT:  entry:
217 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0
218 ; CHECK-NEXT:    [[AND:%.*]] = and i1 false, [[C_1]]
219 ; CHECK-NEXT:    ret i1 [[AND]]
221 entry:
222   %c.1 = icmp sgt i32 %v, 0
223   %t.1 = icmp sgt i32 0, 0
224   %and = and i1 %t.1, %c.1
225   ret i1 %and
228 define i1 @test_and_op_1_simplified(i32 %v) {
229 ; CHECK-LABEL: @test_and_op_1_simplified(
230 ; CHECK-NEXT:  entry:
231 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0
232 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], false
233 ; CHECK-NEXT:    ret i1 [[AND]]
235 entry:
236   %c.1 = icmp sgt i32 %v, 0
237   %t.1 = icmp sgt i32 0, 0
238   %and = and i1 %c.1, %t.1
239   ret i1 %and
242 define i1 @and_select_not_used_for_branch(i32 %x, i32 %y,i32 %z) {
243 ; CHECK-LABEL: @and_select_not_used_for_branch(
244 ; CHECK-NEXT:  entry:
245 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0
246 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0
247 ; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i32 [[X]], 16
248 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_3]]
249 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]]
250 ; CHECK:       then:
251 ; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0
252 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false
253 ; CHECK-NEXT:    br label [[EXIT]]
254 ; CHECK:       exit:
255 ; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ]
256 ; CHECK-NEXT:    ret i1 [[RES]]
258 entry:
259   %c.1 = icmp ne i32 %x, 0
260   %c.2 = icmp ne i32 %y, 0
261   %c.3 = icmp eq i32 %x, 16
262   %and = and i1 %c.2, %c.3
263   br i1 %and, label %then, label %exit
265 then:
266   %c.4 = icmp eq i32 %z, 0
267   %sel = select i1 %c.4, i1 %c.1, i1 false
268   br label %exit
270 exit:
271   %res = phi i1 [ %c.1, %entry ], [ %sel, %then ]
272   ret i1 %res
275 define i1 @and_select_scope_limited(i32 %x, i32 %y, i32 %z) {
276 ; CHECK-LABEL: @and_select_scope_limited(
277 ; CHECK-NEXT:  entry:
278 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0
279 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0
280 ; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i32 [[X]], 16
281 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_3]]
282 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]]
283 ; CHECK:       then:
284 ; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0
285 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false
286 ; CHECK-NEXT:    br i1 [[SEL]], label [[T_1:%.*]], label [[EXIT]]
287 ; CHECK:       t.1:
288 ; CHECK-NEXT:    ret i1 true
289 ; CHECK:       exit:
290 ; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ]
291 ; CHECK-NEXT:    ret i1 [[RES]]
293 entry:
294   %c.1 = icmp ne i32 %x, 0
295   %c.2 = icmp ne i32 %y, 0
296   %c.3 = icmp eq i32 %x, 16
297   %and = and i1 %c.2, %c.3
298   br i1 %and, label %then, label %exit
300 then:
301   %c.4 = icmp eq i32 %z, 0
302   %sel = select i1 %c.4, i1 %c.1, i1 false
303   br i1 %sel, label %t.1, label %exit
305 t.1:
306   ret i1 %c.1
308 exit:
309   %res = phi i1 [ %c.1, %entry ], [ %sel, %then ]
310   ret i1 %res
313 declare void @use(ptr)
315 define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start, i16 %len) {
316 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge(
317 ; CHECK-NEXT:  entry:
318 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
319 ; CHECK-NEXT:    br label [[LOOP_PH:%.*]]
320 ; CHECK:       loop.ph:
321 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
322 ; CHECK:       loop.header:
323 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
324 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp sgt i16 [[LEN]], 0
325 ; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]
326 ; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[LEN_NEG]], [[C]]
327 ; CHECK-NEXT:    br i1 [[AND_0]], label [[FOR_BODY:%.*]], label [[EXIT:%.*]]
328 ; CHECK:       for.body:
329 ; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
330 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
331 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
332 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
333 ; CHECK:       loop.latch:
334 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
335 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
336 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
337 ; CHECK:       exit:
338 ; CHECK-NEXT:    ret void
340 entry:
341   %upper = getelementptr inbounds i32, ptr %start, i16 %len
342   br label %loop.ph
344 loop.ph:
345   br label %loop.header
347 loop.header:
348   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
349   %len.neg = icmp sgt i16 %len, 0
350   %c = icmp ne ptr %ptr.iv, %upper
351   %and.0 = and i1 %len.neg, %c
352   br i1 %and.0, label %for.body, label %exit
354 for.body:
355   %t.1 = icmp uge ptr %ptr.iv, %start
356   %t.2 = icmp ult ptr %ptr.iv, %upper
357   %and = and i1 %t.1, %t.2
358   br i1 %and, label %loop.latch, label %exit
360 loop.latch:
361   call void @use(ptr %ptr.iv)
362   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
363   br label %loop.header
365 exit:
366   ret void
369 define i1 @test_and_used_in_false_branch(i8 %x) {
370 ; CHECK-LABEL: @test_and_used_in_false_branch(
371 ; CHECK-NEXT:  entry:
372 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
373 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
374 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], true
375 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
376 ; CHECK:       then:
377 ; CHECK-NEXT:    ret i1 true
378 ; CHECK:       else:
379 ; CHECK-NEXT:    ret i1 [[T_1]]
382 entry:
383   %c.1 = icmp ugt i8 %x, 10
384   %t.1 = icmp ugt i8 %x, 5
385   %and = and i1 %c.1, %t.1
386   br i1 %and, label %then, label %else
388 then:
389   ret i1 %t.1
391 else:
392   ret i1 %t.1
395 define i1 @test_or_used_in_false_branch(i8 %x) {
396 ; CHECK-LABEL: @test_or_used_in_false_branch(
397 ; CHECK-NEXT:  entry:
398 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
399 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[X]], 5
400 ; CHECK-NEXT:    [[AND:%.*]] = or i1 [[C_1]], false
401 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
402 ; CHECK:       then:
403 ; CHECK-NEXT:    ret i1 [[T_1]]
404 ; CHECK:       else:
405 ; CHECK-NEXT:    ret i1 false
408 entry:
409   %c.1 = icmp ule i8 %x, 10
410   %t.1 = icmp ule i8 %x, 5
411   %and = or i1 %c.1, %t.1
412   br i1 %and, label %then, label %else
414 then:
415   ret i1 %t.1
417 else:
418   ret i1 %t.1
421 define i1 @test_or_used_in_false_branch2(i8 %x) {
422 ; CHECK-LABEL: @test_or_used_in_false_branch2(
423 ; CHECK-NEXT:  entry:
424 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
425 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
426 ; CHECK-NEXT:    [[AND:%.*]] = or i1 false, [[T_1]]
427 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
428 ; CHECK:       then:
429 ; CHECK-NEXT:    ret i1 [[T_1]]
430 ; CHECK:       else:
431 ; CHECK-NEXT:    ret i1 false
434 entry:
435   %c.1 = icmp ugt i8 %x, 10
436   %t.1 = icmp ugt i8 %x, 5
437   %and = or i1 %c.1, %t.1
438   br i1 %and, label %then, label %else
440 then:
441   ret i1 %t.1
443 else:
444   ret i1 %t.1
447 define i1 @and_select_first_implies_second_may_be_poison(ptr noundef %A, ptr noundef %B) {
448 ; CHECK-LABEL: @and_select_first_implies_second_may_be_poison(
449 ; CHECK-NEXT:  entry:
450 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
451 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
452 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
453 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_2]], i1 true, i1 false
454 ; CHECK-NEXT:    ret i1 [[AND]]
456 entry:
457   %c.1 = icmp ne ptr %A, %B
458   %gep = getelementptr inbounds ptr, ptr %B, i64 -1
459   %c.2 = icmp ugt ptr %gep, %A
460   %and = select i1 %c.2, i1 %c.1, i1 false
461   ret i1 %and
464 define i1 @and_select_second_implies_first_may_be_poison(ptr noundef %A, ptr noundef %B) {
465 ; CHECK-LABEL: @and_select_second_implies_first_may_be_poison(
466 ; CHECK-NEXT:  entry:
467 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
468 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
469 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
470 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false
471 ; CHECK-NEXT:    ret i1 [[AND]]
473 entry:
474   %c.1 = icmp ne ptr %A, %B
475   %gep = getelementptr inbounds ptr, ptr %B, i64 -1
476   %c.2 = icmp ugt ptr %gep, %A
477   %and = select i1 %c.1, i1 %c.2, i1 false
478   ret i1 %and
481 define i1 @and_select_second_implies_first_guaranteed_not_poison(ptr noundef %A, ptr noundef %B) {
482 ; CHECK-LABEL: @and_select_second_implies_first_guaranteed_not_poison(
483 ; CHECK-NEXT:  entry:
484 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
485 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
486 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
487 ; CHECK-NEXT:    call void @no_noundef(i1 [[C_2]])
488 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false
489 ; CHECK-NEXT:    ret i1 [[AND]]
491 entry:
492   %c.1 = icmp ne ptr %A, %B
493   %gep = getelementptr inbounds ptr, ptr %B, i64 -1
494   %c.2 = icmp ugt ptr %gep, %A
495   call void @no_noundef(i1 %c.2)
496   %and = select i1 %c.1, i1 %c.2, i1 false
497   ret i1 %and
500 declare void @no_noundef(i1 noundef)