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