1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -S -passes=instsimplify < %s | FileCheck %s 3 4define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) { 5; CHECK-LABEL: define i64 @ptrtoint_gep_sub( 6; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) { 7; CHECK-NEXT: ret i64 [[END_ADDR]] 8; 9 %ptr.addr = ptrtoint ptr %ptr to i64 10 %size = sub i64 %end.addr, %ptr.addr 11 %end = getelementptr i8, ptr %ptr, i64 %size 12 %end.addr2 = ptrtoint ptr %end to i64 13 ret i64 %end.addr2 14} 15 16define <2 x i64> @ptrtoint_gep_sub_vector(<2 x ptr> %ptr, <2 x i64> %end.addr) { 17; CHECK-LABEL: define <2 x i64> @ptrtoint_gep_sub_vector( 18; CHECK-SAME: <2 x ptr> [[PTR:%.*]], <2 x i64> [[END_ADDR:%.*]]) { 19; CHECK-NEXT: ret <2 x i64> [[END_ADDR]] 20; 21 %ptr.addr = ptrtoint <2 x ptr> %ptr to <2 x i64> 22 %size = sub <2 x i64> %end.addr, %ptr.addr 23 %end = getelementptr i8, <2 x ptr> %ptr, <2 x i64> %size 24 %end.addr2 = ptrtoint <2 x ptr> %end to <2 x i64> 25 ret <2 x i64> %end.addr2 26} 27 28define i64 @ptrtoint_gep_sub_wrong_gep_type(ptr %ptr, i64 %end.addr) { 29; CHECK-LABEL: define i64 @ptrtoint_gep_sub_wrong_gep_type( 30; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) { 31; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i64 32; CHECK-NEXT: [[SIZE:%.*]] = sub i64 [[END_ADDR]], [[PTR_ADDR]] 33; CHECK-NEXT: [[END:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[SIZE]] 34; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i64 35; CHECK-NEXT: ret i64 [[END_ADDR2]] 36; 37 %ptr.addr = ptrtoint ptr %ptr to i64 38 %size = sub i64 %end.addr, %ptr.addr 39 %end = getelementptr i32, ptr %ptr, i64 %size 40 %end.addr2 = ptrtoint ptr %end to i64 41 ret i64 %end.addr2 42} 43 44define i64 @ptrtoint_gep_sub_wrong_ptrtoint_op(ptr %ptr, i64 %end.addr, ptr %ptr2) { 45; CHECK-LABEL: define i64 @ptrtoint_gep_sub_wrong_ptrtoint_op( 46; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]], ptr [[PTR2:%.*]]) { 47; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR2]] to i64 48; CHECK-NEXT: [[SIZE:%.*]] = sub i64 [[END_ADDR]], [[PTR_ADDR]] 49; CHECK-NEXT: [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]] 50; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i64 51; CHECK-NEXT: ret i64 [[END_ADDR2]] 52; 53 %ptr.addr = ptrtoint ptr %ptr2 to i64 54 %size = sub i64 %end.addr, %ptr.addr 55 %end = getelementptr i8, ptr %ptr, i64 %size 56 %end.addr2 = ptrtoint ptr %end to i64 57 ret i64 %end.addr2 58} 59 60define i64 @ptrtoint_gep_sub_wrong_operation(ptr %ptr, i64 %end.addr) { 61; CHECK-LABEL: define i64 @ptrtoint_gep_sub_wrong_operation( 62; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) { 63; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i64 64; CHECK-NEXT: [[SIZE:%.*]] = add i64 [[END_ADDR]], [[PTR_ADDR]] 65; CHECK-NEXT: [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]] 66; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i64 67; CHECK-NEXT: ret i64 [[END_ADDR2]] 68; 69 %ptr.addr = ptrtoint ptr %ptr to i64 70 %size = add i64 %end.addr, %ptr.addr 71 %end = getelementptr i8, ptr %ptr, i64 %size 72 %end.addr2 = ptrtoint ptr %end to i64 73 ret i64 %end.addr2 74} 75 76define i64 @ptrtoint_gep_sub_wrong_operand_order(ptr %ptr, i64 %end.addr) { 77; CHECK-LABEL: define i64 @ptrtoint_gep_sub_wrong_operand_order( 78; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) { 79; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i64 80; CHECK-NEXT: [[SIZE:%.*]] = sub i64 [[PTR_ADDR]], [[END_ADDR]] 81; CHECK-NEXT: [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]] 82; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i64 83; CHECK-NEXT: ret i64 [[END_ADDR2]] 84; 85 %ptr.addr = ptrtoint ptr %ptr to i64 86 %size = sub i64 %ptr.addr, %end.addr 87 %end = getelementptr i8, ptr %ptr, i64 %size 88 %end.addr2 = ptrtoint ptr %end to i64 89 ret i64 %end.addr2 90} 91 92define i32 @ptrtoint_gep_sub_wrong_type(ptr %ptr, i64 %end.addr) { 93; CHECK-LABEL: define i32 @ptrtoint_gep_sub_wrong_type( 94; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) { 95; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i64 96; CHECK-NEXT: [[SIZE:%.*]] = sub i64 [[END_ADDR]], [[PTR_ADDR]] 97; CHECK-NEXT: [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]] 98; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i32 99; CHECK-NEXT: ret i32 [[END_ADDR2]] 100; 101 %ptr.addr = ptrtoint ptr %ptr to i64 102 %size = sub i64 %end.addr, %ptr.addr 103 %end = getelementptr i8, ptr %ptr, i64 %size 104 %end.addr2 = ptrtoint ptr %end to i32 105 ret i32 %end.addr2 106} 107 108define i32 @ptrtoint_gep_sub_narrow_type(ptr %ptr, i32 %end.addr) { 109; CHECK-LABEL: define i32 @ptrtoint_gep_sub_narrow_type( 110; CHECK-SAME: ptr [[PTR:%.*]], i32 [[END_ADDR:%.*]]) { 111; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i32 112; CHECK-NEXT: [[SIZE:%.*]] = sub i32 [[END_ADDR]], [[PTR_ADDR]] 113; CHECK-NEXT: [[END:%.*]] = getelementptr i8, ptr [[PTR]], i32 [[SIZE]] 114; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i32 115; CHECK-NEXT: ret i32 [[END_ADDR2]] 116; 117 %ptr.addr = ptrtoint ptr %ptr to i32 118 %size = sub i32 %end.addr, %ptr.addr 119 %end = getelementptr i8, ptr %ptr, i32 %size 120 %end.addr2 = ptrtoint ptr %end to i32 121 ret i32 %end.addr2 122} 123 124define i128 @ptrtoint_gep_sub_wide_type(ptr %ptr, i128 %end.addr) { 125; CHECK-LABEL: define i128 @ptrtoint_gep_sub_wide_type( 126; CHECK-SAME: ptr [[PTR:%.*]], i128 [[END_ADDR:%.*]]) { 127; CHECK-NEXT: [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i128 128; CHECK-NEXT: [[SIZE:%.*]] = sub i128 [[END_ADDR]], [[PTR_ADDR]] 129; CHECK-NEXT: [[END:%.*]] = getelementptr i8, ptr [[PTR]], i128 [[SIZE]] 130; CHECK-NEXT: [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i128 131; CHECK-NEXT: ret i128 [[END_ADDR2]] 132; 133 %ptr.addr = ptrtoint ptr %ptr to i128 134 %size = sub i128 %end.addr, %ptr.addr 135 %end = getelementptr i8, ptr %ptr, i128 %size 136 %end.addr2 = ptrtoint ptr %end to i128 137 ret i128 %end.addr2 138} 139