164965430SRoman Lebedev; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2b280ee1dSBjorn Pettersson; RUN: opt %s -passes=instsimplify -S | FileCheck %s
364965430SRoman Lebedev
464965430SRoman Lebedev; Here we have add some offset to a non-null pointer,
564965430SRoman Lebedev; and check that the result does not overflow and is not a null pointer.
664965430SRoman Lebedev; But since the base pointer is already non-null, and we check for overflow,
764965430SRoman Lebedev; that will already catch the get null pointer,
864965430SRoman Lebedev; so the separate null check is redundant and can be dropped.
964965430SRoman Lebedev
10*04b944e2SNikita Popovdefine i1 @t0(ptr nonnull %base, i64 %offset) {
1164965430SRoman Lebedev; CHECK-LABEL: @t0(
12*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
1364965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
1464965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp uge i64 [[ADJUSTED]], [[BASE_INT]]
156e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
1664965430SRoman Lebedev;
17*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
1864965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
1964965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
2064965430SRoman Lebedev  %no_overflow_during_adjustment = icmp uge i64 %adjusted, %base_int
2164965430SRoman Lebedev  %res = and i1 %non_null_after_adjustment, %no_overflow_during_adjustment
2264965430SRoman Lebedev  ret i1 %res
2364965430SRoman Lebedev}
24*04b944e2SNikita Popovdefine i1 @t1(ptr nonnull %base, i64 %offset) {
2564965430SRoman Lebedev; CHECK-LABEL: @t1(
26*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
2764965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
2864965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp ule i64 [[BASE_INT]], [[ADJUSTED]]
296e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
3064965430SRoman Lebedev;
31*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
3264965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
3364965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
3464965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ule i64 %base_int, %adjusted ; swapped
3564965430SRoman Lebedev  %res = and i1 %non_null_after_adjustment, %no_overflow_during_adjustment
3664965430SRoman Lebedev  ret i1 %res
3764965430SRoman Lebedev}
38*04b944e2SNikita Popovdefine i1 @t2(ptr nonnull %base, i64 %offset) {
3964965430SRoman Lebedev; CHECK-LABEL: @t2(
40*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
4164965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
4264965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp uge i64 [[ADJUSTED]], [[BASE_INT]]
436e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
4464965430SRoman Lebedev;
45*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
4664965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
4764965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
4864965430SRoman Lebedev  %no_overflow_during_adjustment = icmp uge i64 %adjusted, %base_int
4964965430SRoman Lebedev  %res = and i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
5064965430SRoman Lebedev  ret i1 %res
5164965430SRoman Lebedev}
52*04b944e2SNikita Popovdefine i1 @t3(ptr nonnull %base, i64 %offset) {
5364965430SRoman Lebedev; CHECK-LABEL: @t3(
54*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
5564965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
5664965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp ule i64 [[BASE_INT]], [[ADJUSTED]]
576e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
5864965430SRoman Lebedev;
59*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
6064965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
6164965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
6264965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ule i64 %base_int, %adjusted ; swapped
6364965430SRoman Lebedev  %res = and i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
6464965430SRoman Lebedev  ret i1 %res
6564965430SRoman Lebedev}
6664965430SRoman Lebedev
676e2c5c87SRoman Lebedev; If the joining operator was 'or', i.e. we check that either we produced non-null
6864965430SRoman Lebedev; pointer, or no overflow happened, then the overflow check itself is redundant.
6964965430SRoman Lebedev
70*04b944e2SNikita Popovdefine i1 @t4(ptr nonnull %base, i64 %offset) {
7164965430SRoman Lebedev; CHECK-LABEL: @t4(
72*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
7364965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
7464965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp ne i64 [[ADJUSTED]], 0
756e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
7664965430SRoman Lebedev;
77*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
7864965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
7964965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
8064965430SRoman Lebedev  %no_overflow_during_adjustment = icmp uge i64 %adjusted, %base_int
8164965430SRoman Lebedev  %res = or i1 %non_null_after_adjustment, %no_overflow_during_adjustment
8264965430SRoman Lebedev  ret i1 %res
8364965430SRoman Lebedev}
84*04b944e2SNikita Popovdefine i1 @t5(ptr nonnull %base, i64 %offset) {
8564965430SRoman Lebedev; CHECK-LABEL: @t5(
86*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
8764965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
8864965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp ne i64 [[ADJUSTED]], 0
896e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
9064965430SRoman Lebedev;
91*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
9264965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
9364965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
9464965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ule i64 %base_int, %adjusted ; swapped
9564965430SRoman Lebedev  %res = or i1 %non_null_after_adjustment, %no_overflow_during_adjustment
9664965430SRoman Lebedev  ret i1 %res
9764965430SRoman Lebedev}
98*04b944e2SNikita Popovdefine i1 @t6(ptr nonnull %base, i64 %offset) {
9964965430SRoman Lebedev; CHECK-LABEL: @t6(
100*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
10164965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
10264965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp ne i64 [[ADJUSTED]], 0
1036e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
10464965430SRoman Lebedev;
105*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
10664965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
10764965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
10864965430SRoman Lebedev  %no_overflow_during_adjustment = icmp uge i64 %adjusted, %base_int
10964965430SRoman Lebedev  %res = or i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
11064965430SRoman Lebedev  ret i1 %res
11164965430SRoman Lebedev}
112*04b944e2SNikita Popovdefine i1 @t7(ptr nonnull %base, i64 %offset) {
11364965430SRoman Lebedev; CHECK-LABEL: @t7(
114*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
11564965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
11664965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp ne i64 [[ADJUSTED]], 0
1176e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
11864965430SRoman Lebedev;
119*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
12064965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
12164965430SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
12264965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ule i64 %base_int, %adjusted ; swapped
12364965430SRoman Lebedev  %res = or i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
12464965430SRoman Lebedev  ret i1 %res
12564965430SRoman Lebedev}
12664965430SRoman Lebedev
12764965430SRoman Lebedev; Or, we could be checking the reverse condition, that we either get null pointer,
12864965430SRoman Lebedev; or overflow happens, then again, the standalone null check is redundant and
12964965430SRoman Lebedev; can be dropped.
13064965430SRoman Lebedev
131*04b944e2SNikita Popovdefine i1 @t8(ptr nonnull %base, i64 %offset) {
13264965430SRoman Lebedev; CHECK-LABEL: @t8(
133*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
13464965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
13564965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp ult i64 [[ADJUSTED]], [[BASE_INT]]
1366e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
13764965430SRoman Lebedev;
138*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
13964965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
14064965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
14164965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ult i64 %adjusted, %base_int
14264965430SRoman Lebedev  %res = or i1 %non_null_after_adjustment, %no_overflow_during_adjustment
14364965430SRoman Lebedev  ret i1 %res
14464965430SRoman Lebedev}
145*04b944e2SNikita Popovdefine i1 @t9(ptr nonnull %base, i64 %offset) {
14664965430SRoman Lebedev; CHECK-LABEL: @t9(
147*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
14864965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
14964965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp ugt i64 [[BASE_INT]], [[ADJUSTED]]
1506e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
15164965430SRoman Lebedev;
152*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
15364965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
15464965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
15564965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ugt i64 %base_int, %adjusted ; swapped
15664965430SRoman Lebedev  %res = or i1 %non_null_after_adjustment, %no_overflow_during_adjustment
15764965430SRoman Lebedev  ret i1 %res
15864965430SRoman Lebedev}
159*04b944e2SNikita Popovdefine i1 @t10(ptr nonnull %base, i64 %offset) {
16064965430SRoman Lebedev; CHECK-LABEL: @t10(
161*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
16264965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
16364965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp ult i64 [[ADJUSTED]], [[BASE_INT]]
1646e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
16564965430SRoman Lebedev;
166*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
16764965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
16864965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
16964965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ult i64 %adjusted, %base_int
17064965430SRoman Lebedev  %res = or i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
17164965430SRoman Lebedev  ret i1 %res
17264965430SRoman Lebedev}
173*04b944e2SNikita Popovdefine i1 @t11(ptr nonnull %base, i64 %offset) {
17464965430SRoman Lebedev; CHECK-LABEL: @t11(
175*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
17664965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
17764965430SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp ugt i64 [[BASE_INT]], [[ADJUSTED]]
1786e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
17964965430SRoman Lebedev;
180*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
18164965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
18264965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
18364965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ugt i64 %base_int, %adjusted ; swapped
18464965430SRoman Lebedev  %res = or i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
18564965430SRoman Lebedev  ret i1 %res
18664965430SRoman Lebedev}
18764965430SRoman Lebedev
18864965430SRoman Lebedev; If the joining operator was 'and', i.e. we check that we both get null pointer
18964965430SRoman Lebedev; AND overflow happens, then the overflow check is redundant.
19064965430SRoman Lebedev
191*04b944e2SNikita Popovdefine i1 @t12(ptr nonnull %base, i64 %offset) {
19264965430SRoman Lebedev; CHECK-LABEL: @t12(
193*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
19464965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
19564965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp eq i64 [[ADJUSTED]], 0
1966e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
19764965430SRoman Lebedev;
198*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
19964965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
20064965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
20164965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ult i64 %adjusted, %base_int
20264965430SRoman Lebedev  %res = and i1 %non_null_after_adjustment, %no_overflow_during_adjustment
20364965430SRoman Lebedev  ret i1 %res
20464965430SRoman Lebedev}
205*04b944e2SNikita Popovdefine i1 @t13(ptr nonnull %base, i64 %offset) {
20664965430SRoman Lebedev; CHECK-LABEL: @t13(
207*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
20864965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
20964965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp eq i64 [[ADJUSTED]], 0
2106e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
21164965430SRoman Lebedev;
212*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
21364965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
21464965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
21564965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ugt i64 %base_int, %adjusted ; swapped
21664965430SRoman Lebedev  %res = and i1 %non_null_after_adjustment, %no_overflow_during_adjustment
21764965430SRoman Lebedev  ret i1 %res
21864965430SRoman Lebedev}
219*04b944e2SNikita Popovdefine i1 @t14(ptr nonnull %base, i64 %offset) {
22064965430SRoman Lebedev; CHECK-LABEL: @t14(
221*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
22264965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
22364965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp eq i64 [[ADJUSTED]], 0
2246e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
22564965430SRoman Lebedev;
226*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
22764965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
22864965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
22964965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ult i64 %adjusted, %base_int
23064965430SRoman Lebedev  %res = and i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
23164965430SRoman Lebedev  ret i1 %res
23264965430SRoman Lebedev}
233*04b944e2SNikita Popovdefine i1 @t15(ptr nonnull %base, i64 %offset) {
23464965430SRoman Lebedev; CHECK-LABEL: @t15(
235*04b944e2SNikita Popov; CHECK-NEXT:    [[BASE_INT:%.*]] = ptrtoint ptr [[BASE:%.*]] to i64
23664965430SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE_INT]], [[OFFSET:%.*]]
23764965430SRoman Lebedev; CHECK-NEXT:    [[NON_NULL_AFTER_ADJUSTMENT:%.*]] = icmp eq i64 [[ADJUSTED]], 0
2386e2c5c87SRoman Lebedev; CHECK-NEXT:    ret i1 [[NON_NULL_AFTER_ADJUSTMENT]]
23964965430SRoman Lebedev;
240*04b944e2SNikita Popov  %base_int = ptrtoint ptr %base to i64
24164965430SRoman Lebedev  %adjusted = add i64 %base_int, %offset
24264965430SRoman Lebedev  %non_null_after_adjustment = icmp eq i64 %adjusted, 0
24364965430SRoman Lebedev  %no_overflow_during_adjustment = icmp ugt i64 %base_int, %adjusted ; swapped
24464965430SRoman Lebedev  %res = and i1 %no_overflow_during_adjustment, %non_null_after_adjustment ; swapped
24564965430SRoman Lebedev  ret i1 %res
24664965430SRoman Lebedev}
2478aeb7bb0SRoman Lebedev
2488aeb7bb0SRoman Lebedevdeclare void @llvm.assume(i1)
2498aeb7bb0SRoman Lebedevdefine i1 @t16(i64 %base, i64 %offset) {
2508aeb7bb0SRoman Lebedev; CHECK-LABEL: @t16(
2518aeb7bb0SRoman Lebedev; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[BASE:%.*]], 0
2528aeb7bb0SRoman Lebedev; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
2538aeb7bb0SRoman Lebedev; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i64 [[BASE]], [[OFFSET:%.*]]
2548aeb7bb0SRoman Lebedev; CHECK-NEXT:    [[NO_OVERFLOW_DURING_ADJUSTMENT:%.*]] = icmp uge i64 [[ADJUSTED]], [[BASE]]
25500c1ee48SRoman Lebedev; CHECK-NEXT:    ret i1 [[NO_OVERFLOW_DURING_ADJUSTMENT]]
2568aeb7bb0SRoman Lebedev;
2578aeb7bb0SRoman Lebedev  %cmp = icmp slt i64 %base, 0
2588aeb7bb0SRoman Lebedev  call void @llvm.assume(i1 %cmp)
2598aeb7bb0SRoman Lebedev
2608aeb7bb0SRoman Lebedev  %adjusted = add i64 %base, %offset
2618aeb7bb0SRoman Lebedev  %non_null_after_adjustment = icmp ne i64 %adjusted, 0
2628aeb7bb0SRoman Lebedev  %no_overflow_during_adjustment = icmp uge i64 %adjusted, %base
2638aeb7bb0SRoman Lebedev  %res = and i1 %non_null_after_adjustment, %no_overflow_during_adjustment
2648aeb7bb0SRoman Lebedev  ret i1 %res
2658aeb7bb0SRoman Lebedev}
266