1267 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-p2:32:32-p3:32:32:32:16"5 6define i64 @test_inbounds(ptr %base, i64 %idx) {7; CHECK-LABEL: @test_inbounds(8; CHECK-NEXT: [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 29; CHECK-NEXT: ret i64 [[P2_IDX]]10;11 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx12 %i1 = ptrtoint ptr %base to i6413 %i2 = ptrtoint ptr %p2 to i6414 %d = sub i64 %i2, %i115 ret i64 %d16}17 18define i64 @test_partial_inbounds1(ptr %base, i64 %idx) {19; CHECK-LABEL: @test_partial_inbounds1(20; CHECK-NEXT: [[P2_IDX:%.*]] = shl i64 [[IDX:%.*]], 221; CHECK-NEXT: ret i64 [[P2_IDX]]22;23 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx24 %i1 = ptrtoint ptr %base to i6425 %i2 = ptrtoint ptr %p2 to i6426 %d = sub i64 %i2, %i127 ret i64 %d28}29 30define i64 @test_partial_inbounds2(ptr %base, i64 %idx) {31; CHECK-LABEL: @test_partial_inbounds2(32; CHECK-NEXT: [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 233; CHECK-NEXT: ret i64 [[P2_IDX]]34;35 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx36 %i1 = ptrtoint ptr %base to i6437 %i2 = ptrtoint ptr %p2 to i6438 %d = sub i64 %i2, %i139 ret i64 %d40}41 42define i64 @test_inbounds_nuw(ptr %base, i64 %idx) {43; CHECK-LABEL: @test_inbounds_nuw(44; CHECK-NEXT: [[P2_IDX:%.*]] = shl nuw nsw i64 [[IDX:%.*]], 245; CHECK-NEXT: ret i64 [[P2_IDX]]46;47 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx48 %i1 = ptrtoint ptr %base to i6449 %i2 = ptrtoint ptr %p2 to i6450 %d = sub nuw i64 %i2, %i151 ret i64 %d52}53 54define i64 @test_nuw(ptr %base, i64 %idx) {55; CHECK-LABEL: @test_nuw(56; CHECK-NEXT: [[P2_IDX:%.*]] = shl i64 [[IDX:%.*]], 257; CHECK-NEXT: ret i64 [[P2_IDX]]58;59 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx60 %i1 = ptrtoint ptr %base to i6461 %i2 = ptrtoint ptr %p2 to i6462 %d = sub nuw i64 %i2, %i163 ret i64 %d64}65 66define i32 @test_inbounds_nuw_trunc(ptr %base, i64 %idx) {67; CHECK-LABEL: @test_inbounds_nuw_trunc(68; CHECK-NEXT: [[IDX_TR:%.*]] = trunc i64 [[IDX:%.*]] to i3269; CHECK-NEXT: [[D:%.*]] = shl i32 [[IDX_TR]], 270; CHECK-NEXT: ret i32 [[D]]71;72 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx73 %i1 = ptrtoint ptr %base to i6474 %i2 = ptrtoint ptr %p2 to i6475 %t1 = trunc i64 %i1 to i3276 %t2 = trunc i64 %i2 to i3277 %d = sub nuw i32 %t2, %t178 ret i32 %d79}80 81define i64 @test_inbounds_nuw_swapped(ptr %base, i64 %idx) {82; CHECK-LABEL: @test_inbounds_nuw_swapped(83; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul nsw i64 [[IDX:%.*]], -484; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]85;86 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx87 %i1 = ptrtoint ptr %p2 to i6488 %i2 = ptrtoint ptr %base to i6489 %d = sub nuw i64 %i2, %i190 ret i64 %d91}92 93define i64 @test_inbounds1_nuw_swapped(ptr %base, i64 %idx) {94; CHECK-LABEL: @test_inbounds1_nuw_swapped(95; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -496; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]97;98 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx99 %i1 = ptrtoint ptr %p2 to i64100 %i2 = ptrtoint ptr %base to i64101 %d = sub nuw i64 %i2, %i1102 ret i64 %d103}104 105define i64 @test_inbounds2_nuw_swapped(ptr %base, i64 %idx) {106; CHECK-LABEL: @test_inbounds2_nuw_swapped(107; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul nsw i64 [[IDX:%.*]], -4108; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]109;110 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx111 %i1 = ptrtoint ptr %p2 to i64112 %i2 = ptrtoint ptr %base to i64113 %d = sub nuw i64 %i2, %i1114 ret i64 %d115}116 117define i64 @test_inbounds_two_gep(ptr %base, i64 %idx, i64 %idx2) {118; CHECK-LABEL: @test_inbounds_two_gep(119; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i64 [[IDX2:%.*]], [[IDX:%.*]]120; CHECK-NEXT: [[GEPDIFF:%.*]] = shl nsw i64 [[TMP1]], 2121; CHECK-NEXT: ret i64 [[GEPDIFF]]122;123 %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx124 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2125 %i1 = ptrtoint ptr %p1 to i64126 %i2 = ptrtoint ptr %p2 to i64127 %d = sub i64 %i2, %i1128 ret i64 %d129}130 131define i64 @test_inbounds_nsw_two_gep(ptr %base, i64 %idx, i64 %idx2) {132; CHECK-LABEL: @test_inbounds_nsw_two_gep(133; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i64 [[IDX2:%.*]], [[IDX:%.*]]134; CHECK-NEXT: [[GEPDIFF:%.*]] = shl nsw i64 [[TMP1]], 2135; CHECK-NEXT: ret i64 [[GEPDIFF]]136;137 %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx138 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2139 %i1 = ptrtoint ptr %p1 to i64140 %i2 = ptrtoint ptr %p2 to i64141 %d = sub nsw i64 %i2, %i1142 ret i64 %d143}144 145define i64 @test_inbounds_nuw_two_gep(ptr %base, i64 %idx, i64 %idx2) {146; CHECK-LABEL: @test_inbounds_nuw_two_gep(147; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i64 [[IDX2:%.*]], [[IDX:%.*]]148; CHECK-NEXT: [[GEPDIFF:%.*]] = shl nsw i64 [[TMP1]], 2149; CHECK-NEXT: ret i64 [[GEPDIFF]]150;151 %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx152 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2153 %i1 = ptrtoint ptr %p1 to i64154 %i2 = ptrtoint ptr %p2 to i64155 %d = sub nuw i64 %i2, %i1156 ret i64 %d157}158 159define i64 @test_nusw_two_gep(ptr %base, i64 %idx, i64 %idx2) {160; CHECK-LABEL: @test_nusw_two_gep(161; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[IDX2:%.*]], [[IDX:%.*]]162; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2163; CHECK-NEXT: ret i64 [[GEPDIFF]]164;165 %p1 = getelementptr nusw [0 x i32], ptr %base, i64 0, i64 %idx166 %p2 = getelementptr nusw [0 x i32], ptr %base, i64 0, i64 %idx2167 %i1 = ptrtoint ptr %p1 to i64168 %i2 = ptrtoint ptr %p2 to i64169 %d = sub i64 %i2, %i1170 ret i64 %d171}172 173define i64 @test_nuw_two_gep(ptr %base, i64 %idx, i64 %idx2) {174; CHECK-LABEL: @test_nuw_two_gep(175; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i64 [[IDX2:%.*]], [[IDX:%.*]]176; CHECK-NEXT: [[GEPDIFF:%.*]] = shl nuw i64 [[TMP1]], 2177; CHECK-NEXT: ret i64 [[GEPDIFF]]178;179 %p1 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx180 %p2 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx2181 %i1 = ptrtoint ptr %p1 to i64182 %i2 = ptrtoint ptr %p2 to i64183 %d = sub nuw i64 %i2, %i1184 ret i64 %d185}186 187define i64 @test_nuw_two_gep_missing_nuw_on_sub(ptr %base, i64 %idx, i64 %idx2) {188; CHECK-LABEL: @test_nuw_two_gep_missing_nuw_on_sub(189; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[IDX2:%.*]], [[IDX:%.*]]190; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2191; CHECK-NEXT: ret i64 [[GEPDIFF]]192;193 %p1 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx194 %p2 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx2195 %i1 = ptrtoint ptr %p1 to i64196 %i2 = ptrtoint ptr %p2 to i64197 %d = sub i64 %i2, %i1198 ret i64 %d199}200 201define i64 @test_nuw_two_gep_missing_nuw_on_one_gep(ptr %base, i64 %idx, i64 %idx2) {202; CHECK-LABEL: @test_nuw_two_gep_missing_nuw_on_one_gep(203; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[IDX2:%.*]], [[IDX:%.*]]204; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2205; CHECK-NEXT: ret i64 [[GEPDIFF]]206;207 %p1 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx208 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx2209 %i1 = ptrtoint ptr %p1 to i64210 %i2 = ptrtoint ptr %p2 to i64211 %d = sub nuw i64 %i2, %i1212 ret i64 %d213}214 215define i64 @test_inbounds_nuw_multi_index(ptr %base, i64 %idx, i64 %idx2) {216; CHECK-LABEL: @test_inbounds_nuw_multi_index(217; CHECK-NEXT: [[P2_SPLIT_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 3218; CHECK-NEXT: [[P2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 2219; CHECK-NEXT: [[D:%.*]] = add nsw i64 [[P2_SPLIT_IDX]], [[P2_IDX]]220; CHECK-NEXT: ret i64 [[D]]221;222 %p2 = getelementptr inbounds [0 x [2 x i32]], ptr %base, i64 0, i64 %idx, i64 %idx2223 %i1 = ptrtoint ptr %base to i64224 %i2 = ptrtoint ptr %p2 to i64225 %d = sub nuw i64 %i2, %i1226 ret i64 %d227}228 229; rdar://7362831230define i32 @test23(ptr %P, i64 %A){231; CHECK-LABEL: @test23(232; CHECK-NEXT: [[G:%.*]] = trunc i64 [[A:%.*]] to i32233; CHECK-NEXT: ret i32 [[G]]234;235 %B = getelementptr inbounds i8, ptr %P, i64 %A236 %C = ptrtoint ptr %B to i64237 %D = trunc i64 %C to i32238 %E = ptrtoint ptr %P to i64239 %F = trunc i64 %E to i32240 %G = sub i32 %D, %F241 ret i32 %G242}243 244define i8 @test23_as1(ptr addrspace(1) %P, i16 %A) {245; CHECK-LABEL: @test23_as1(246; CHECK-NEXT: [[G:%.*]] = trunc i16 [[A:%.*]] to i8247; CHECK-NEXT: ret i8 [[G]]248;249 %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A250 %C = ptrtoint ptr addrspace(1) %B to i16251 %D = trunc i16 %C to i8252 %E = ptrtoint ptr addrspace(1) %P to i16253 %F = trunc i16 %E to i8254 %G = sub i8 %D, %F255 ret i8 %G256}257 258define i64 @test24(ptr %P, i64 %A){259; CHECK-LABEL: @test24(260; CHECK-NEXT: ret i64 [[A:%.*]]261;262 %B = getelementptr inbounds i8, ptr %P, i64 %A263 %C = ptrtoint ptr %B to i64264 %E = ptrtoint ptr %P to i64265 %G = sub i64 %C, %E266 ret i64 %G267}268 269define i16 @test24_as1(ptr addrspace(1) %P, i16 %A) {270; CHECK-LABEL: @test24_as1(271; CHECK-NEXT: ret i16 [[A:%.*]]272;273 %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A274 %C = ptrtoint ptr addrspace(1) %B to i16275 %E = ptrtoint ptr addrspace(1) %P to i16276 %G = sub i16 %C, %E277 ret i16 %G278}279 280define i64 @test24a(ptr %P, i64 %A){281; CHECK-LABEL: @test24a(282; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 0, [[A:%.*]]283; CHECK-NEXT: ret i64 [[GEPDIFF]]284;285 %B = getelementptr inbounds i8, ptr %P, i64 %A286 %C = ptrtoint ptr %B to i64287 %E = ptrtoint ptr %P to i64288 %G = sub i64 %E, %C289 ret i64 %G290}291 292define i16 @test24a_as1(ptr addrspace(1) %P, i16 %A) {293; CHECK-LABEL: @test24a_as1(294; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i16 0, [[A:%.*]]295; CHECK-NEXT: ret i16 [[GEPDIFF]]296;297 %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A298 %C = ptrtoint ptr addrspace(1) %B to i16299 %E = ptrtoint ptr addrspace(1) %P to i16300 %G = sub i16 %E, %C301 ret i16 %G302}303 304@Arr = external global [42 x i16]305 306define i64 @test24b(ptr %P, i64 %A){307; CHECK-LABEL: @test24b(308; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1309; CHECK-NEXT: ret i64 [[B_IDX]]310;311 %B = getelementptr inbounds [42 x i16], ptr @Arr, i64 0, i64 %A312 %C = ptrtoint ptr %B to i64313 %G = sub i64 %C, ptrtoint (ptr @Arr to i64)314 ret i64 %G315}316 317define i64 @test25(ptr %P, i64 %A){318; CHECK-LABEL: @test25(319; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1320; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i64 [[B_IDX]], -84321; CHECK-NEXT: ret i64 [[GEPDIFF]]322;323 %B = getelementptr inbounds [42 x i16], ptr @Arr, i64 0, i64 %A324 %C = ptrtoint ptr %B to i64325 %G = sub i64 %C, ptrtoint (ptr getelementptr ([42 x i16], ptr @Arr, i64 1, i64 0) to i64)326 ret i64 %G327}328 329define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) {330; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint(331; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64332; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]333; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64334; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 4294967294335; CHECK-NEXT: [[D:%.*]] = sub i64 [[C]], ptrtoint (ptr @Arr to i64)336; CHECK-NEXT: ret i64 [[D]]337;338 %A = getelementptr bfloat, ptr @Arr, i32 %offset339 %B = ptrtoint ptr %A to i32340 %C = zext i32 %B to i64341 %D = sub i64 %C, ptrtoint (ptr @Arr to i64)342 ret i64 %D343}344 345define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) {346; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint(347; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64348; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]349; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64350; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 4294967294351; CHECK-NEXT: [[D:%.*]] = sub i64 ptrtoint (ptr @Arr to i64), [[C]]352; CHECK-NEXT: ret i64 [[D]]353;354 %A = getelementptr bfloat, ptr @Arr, i32 %offset355 %B = ptrtoint ptr %A to i32356 %C = zext i32 %B to i64357 %D = sub i64 ptrtoint (ptr @Arr to i64), %C358 ret i64 %D359}360 361define i64 @negative_zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) {362; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint(363; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64364; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]365; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64366; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 65534367; CHECK-NEXT: [[D:%.*]] = sub i64 [[C]], ptrtoint (ptr @Arr to i64)368; CHECK-NEXT: ret i64 [[D]]369;370 %A = getelementptr bfloat, ptr @Arr, i32 %offset371 %B = ptrtoint ptr %A to i16372 %C = zext i16 %B to i64373 %D = sub i64 %C, ptrtoint (ptr @Arr to i64)374 ret i64 %D375}376 377define i64 @negative_ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) {378; CHECK-LABEL: @negative_ptrtoint_sub_zext_ptrtoint(379; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64380; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]381; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64382; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 65534383; CHECK-NEXT: [[D:%.*]] = sub i64 ptrtoint (ptr @Arr to i64), [[C]]384; CHECK-NEXT: ret i64 [[D]]385;386 %A = getelementptr bfloat, ptr @Arr, i32 %offset387 %B = ptrtoint ptr %A to i16388 %C = zext i16 %B to i64389 %D = sub i64 ptrtoint (ptr @Arr to i64), %C390 ret i64 %D391}392 393@Arr_as1 = external addrspace(1) global [42 x i16]394 395define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) {396; CHECK-LABEL: @test25_as1(397; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[A:%.*]] to i16398; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i16 [[TMP1]], 1399; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i16 [[B_IDX]], -84400; CHECK-NEXT: ret i16 [[GEPDIFF]]401;402 %B = getelementptr inbounds [42 x i16], ptr addrspace(1) @Arr_as1, i64 0, i64 %A403 %C = ptrtoint ptr addrspace(1) %B to i16404 %G = sub i16 %C, ptrtoint (ptr addrspace(1) getelementptr ([42 x i16], ptr addrspace(1) @Arr_as1, i64 1, i64 0) to i16)405 ret i16 %G406}407 408@Arr_as2 = external addrspace(2) global [42 x i16]409 410define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds(i32 %offset) {411; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds(412; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]]413; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32414; CHECK-NEXT: [[C:%.*]] = zext i32 [[B]] to i64415; CHECK-NEXT: [[D:%.*]] = sub nsw i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), [[C]]416; CHECK-NEXT: ret i64 [[D]]417;418 %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset419 %B = ptrtoint ptr addrspace(2) %A to i32420 %C = zext i32 %B to i64421 %D = sub i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C422 ret i64 %D423}424 425define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw(i32 %offset) {426; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw(427; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1428; CHECK-NEXT: [[D:%.*]] = sext i32 [[A_IDX]] to i64429; CHECK-NEXT: ret i64 [[D]]430;431 %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset432 %B = ptrtoint ptr addrspace(2) %A to i32433 %C = zext i32 %B to i64434 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)435 ret i64 %D436}437 438define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) {439; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw(440; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1441; CHECK-NEXT: [[D:%.*]] = zext i32 [[A_IDX]] to i64442; CHECK-NEXT: ret i64 [[D]]443;444 %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset445 %B = ptrtoint ptr addrspace(2) %A to i32446 %C = zext i32 %B to i64447 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)448 ret i64 %D449}450 451define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(i32 %offset) {452; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(453; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1454; CHECK-NEXT: [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64455; CHECK-NEXT: ret i64 [[D]]456;457 %A = getelementptr nusw nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset458 %B = ptrtoint ptr addrspace(2) %A to i32459 %C = zext i32 %B to i64460 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)461 ret i64 %D462}463 464define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw(i32 %offset) {465; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw(466; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1467; CHECK-NEXT: [[E:%.*]] = sext i32 [[A_IDX]] to i64468; CHECK-NEXT: ret i64 [[E]]469;470 %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset471 %B = ptrtoint ptr addrspace(2) %A to i32472 %C = zext i32 %B to i64473 %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64474 %E = sub i64 %C, %D475 ret i64 %E476}477 478define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(i32 %offset) {479; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(480; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1481; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64482; CHECK-NEXT: ret i64 [[E]]483;484 %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset485 %B = ptrtoint ptr addrspace(2) %A to i32486 %C = zext i32 %B to i64487 %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64488 %E = sub i64 %C, %D489 ret i64 %E490}491 492define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) {493; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(494; CHECK-NEXT: [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]]495; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32496; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[TMP1]], 65534497; CHECK-NEXT: [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64498; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[C]], ptrtoint (ptr addrspace(2) @Arr_as2 to i64)499; CHECK-NEXT: ret i64 [[D]]500;501 %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset502 %B = ptrtoint ptr addrspace(2) %A to i16503 %C = zext i16 %B to i64504 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)505 ret i64 %D506}507 508define i64 @negative_zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_truncating(i32 %offset) {509; CHECK-LABEL: @negative_zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_truncating(510; CHECK-NEXT: [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]]511; CHECK-NEXT: [[A_IDX:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32512; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64513; CHECK-NEXT: [[D:%.*]] = zext i16 ptrtoint (ptr addrspace(2) @Arr_as2 to i16) to i64514; CHECK-NEXT: [[E1:%.*]] = sub nsw i64 [[E]], [[D]]515; CHECK-NEXT: ret i64 [[E1]]516;517 %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset518 %B = ptrtoint ptr addrspace(2) %A to i32519 %C = zext i32 %B to i64520 %D = zext i16 ptrtoint (ptr addrspace(2) @Arr_as2 to i16) to i64521 %E = sub i64 %C, %D522 ret i64 %E523}524 525define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local(ptr addrspace(2) %p, i32 %offset) {526; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local(527; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]]528; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32529; CHECK-NEXT: [[C:%.*]] = zext i32 [[B]] to i64530; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32531; CHECK-NEXT: [[CC:%.*]] = zext i32 [[TMP1]] to i64532; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[CC]], [[C]]533; CHECK-NEXT: ret i64 [[D]]534;535 %A = getelementptr inbounds bfloat, ptr addrspace(2) %p, i32 %offset536 %B = ptrtoint ptr addrspace(2) %A to i32537 %C = zext i32 %B to i64538 %CC = ptrtoint ptr addrspace(2) %p to i64539 %D = sub i64 %CC, %C540 ret i64 %D541}542 543define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) {544; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_local(545; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1546; CHECK-NEXT: [[D:%.*]] = sext i32 [[A_IDX]] to i64547; CHECK-NEXT: ret i64 [[D]]548;549 %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset550 %B = ptrtoint ptr addrspace(2) %A to i32551 %C = zext i32 %B to i64552 %CC = ptrtoint ptr addrspace(2) %p to i64553 %D = sub i64 %C, %CC554 ret i64 %D555}556 557define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) {558; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw_local(559; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1560; CHECK-NEXT: [[D:%.*]] = zext i32 [[A_IDX]] to i64561; CHECK-NEXT: ret i64 [[D]]562;563 %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset564 %B = ptrtoint ptr addrspace(2) %A to i32565 %C = zext i32 %B to i64566 %CC = ptrtoint ptr addrspace(2) %p to i64567 %D = sub i64 %C, %CC568 ret i64 %D569}570 571define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local(ptr addrspace(2) %p, i32 %offset) {572; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local(573; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1574; CHECK-NEXT: [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64575; CHECK-NEXT: ret i64 [[D]]576;577 %A = getelementptr nusw nuw bfloat, ptr addrspace(2) %p, i32 %offset578 %B = ptrtoint ptr addrspace(2) %A to i32579 %C = zext i32 %B to i64580 %CC = ptrtoint ptr addrspace(2) %p to i64581 %D = sub i64 %C, %CC582 ret i64 %D583}584 585define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) {586; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local(587; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1588; CHECK-NEXT: [[E:%.*]] = sext i32 [[A_IDX]] to i64589; CHECK-NEXT: ret i64 [[E]]590;591 %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset592 %B = ptrtoint ptr addrspace(2) %A to i32593 %C = zext i32 %B to i64594 %CC = ptrtoint ptr addrspace(2) %p to i32595 %D = zext i32 %CC to i64596 %E = sub i64 %C, %D597 ret i64 %E598}599 600define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) {601; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local(602; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1603; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64604; CHECK-NEXT: ret i64 [[E]]605;606 %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset607 %B = ptrtoint ptr addrspace(2) %A to i32608 %C = zext i32 %B to i64609 %CC = ptrtoint ptr addrspace(2) %p to i32610 %D = zext i32 %CC to i64611 %E = sub i64 %C, %D612 ret i64 %E613}614 615define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) {616; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local(617; CHECK-NEXT: [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]]618; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32619; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[TMP1]], 65535620; CHECK-NEXT: [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64621; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32622; CHECK-NEXT: [[CC:%.*]] = zext i32 [[TMP2]] to i64623; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[C]], [[CC]]624; CHECK-NEXT: ret i64 [[D]]625;626 %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset627 %B = ptrtoint ptr addrspace(2) %A to i16628 %C = zext i16 %B to i64629 %CC = ptrtoint ptr addrspace(2) %p to i64630 %D = sub i64 %C, %CC631 ret i64 %D632}633 634define i64 @zext_ptrtoint_sub_ptrtoint_as3_nuw_local(ptr addrspace(3) %p, i16 %offset) {635; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as3_nuw_local(636; CHECK-NEXT: [[SUB:%.*]] = zext i16 [[GEP_IDX:%.*]] to i64637; CHECK-NEXT: ret i64 [[SUB]]638;639 %gep = getelementptr nuw i8, ptr addrspace(3) %p, i16 %offset640 %gep.int = ptrtoint ptr addrspace(3) %gep to i32641 %p.int = ptrtoint ptr addrspace(3) %p to i32642 %gep.int.ext = zext i32 %gep.int to i64643 %p.int.ext = zext i32 %p.int to i64644 %sub = sub i64 %gep.int.ext, %p.int.ext645 ret i64 %sub646}647 648define i64 @test30(ptr %foo, i64 %i, i64 %j) {649; CHECK-LABEL: @test30(650; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2651; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[GEP1_IDX]], [[J:%.*]]652; CHECK-NEXT: ret i64 [[GEPDIFF]]653;654 %gep1 = getelementptr inbounds i32, ptr %foo, i64 %i655 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j656 %cast1 = ptrtoint ptr %gep1 to i64657 %cast2 = ptrtoint ptr %gep2 to i64658 %sub = sub i64 %cast1, %cast2659 ret i64 %sub660}661 662define i16 @test30_as1(ptr addrspace(1) %foo, i16 %i, i16 %j) {663; CHECK-LABEL: @test30_as1(664; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2665; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i16 [[GEP1_IDX]], [[J:%.*]]666; CHECK-NEXT: ret i16 [[GEPDIFF]]667;668 %gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i16 %i669 %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i16 %j670 %cast1 = ptrtoint ptr addrspace(1) %gep1 to i16671 %cast2 = ptrtoint ptr addrspace(1) %gep2 to i16672 %sub = sub i16 %cast1, %cast2673 ret i16 %sub674}675 676; Inbounds translates to 'nsw' on sub677 678define i64 @gep_diff_both_inbounds(ptr %foo, i64 %i, i64 %j) {679; CHECK-LABEL: @gep_diff_both_inbounds(680; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[I:%.*]], [[J:%.*]]681; CHECK-NEXT: ret i64 [[GEPDIFF]]682;683 %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i684 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j685 %cast1 = ptrtoint ptr %gep1 to i64686 %cast2 = ptrtoint ptr %gep2 to i64687 %sub = sub i64 %cast1, %cast2688 ret i64 %sub689}690 691; Negative test for 'nsw' - both geps must be inbounds692 693define i64 @gep_diff_first_inbounds(ptr %foo, i64 %i, i64 %j) {694; CHECK-LABEL: @gep_diff_first_inbounds(695; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]696; CHECK-NEXT: ret i64 [[GEPDIFF]]697;698 %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i699 %gep2 = getelementptr i8, ptr %foo, i64 %j700 %cast1 = ptrtoint ptr %gep1 to i64701 %cast2 = ptrtoint ptr %gep2 to i64702 %sub = sub i64 %cast1, %cast2703 ret i64 %sub704}705 706; Negative test for 'nsw' - both geps must be inbounds707 708define i64 @gep_diff_second_inbounds(ptr %foo, i64 %i, i64 %j) {709; CHECK-LABEL: @gep_diff_second_inbounds(710; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]711; CHECK-NEXT: ret i64 [[GEPDIFF]]712;713 %gep1 = getelementptr i8, ptr %foo, i64 %i714 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j715 %cast1 = ptrtoint ptr %gep1 to i64716 %cast2 = ptrtoint ptr %gep2 to i64717 %sub = sub i64 %cast1, %cast2718 ret i64 %sub719}720 721define i64 @gep_diff_with_bitcast(ptr %p, i64 %idx) {722; CHECK-LABEL: @gep_diff_with_bitcast(723; CHECK-NEXT: ret i64 [[IDX:%.*]]724;725 %i1 = getelementptr inbounds [4 x i64], ptr %p, i64 %idx726 %i3 = ptrtoint ptr %i1 to i64727 %i4 = ptrtoint ptr %p to i64728 %i5 = sub nuw i64 %i3, %i4729 %i6 = lshr i64 %i5, 5730 ret i64 %i6731}732 733define i64 @sub_scalable(ptr noundef %val1) {734; CHECK-LABEL: @sub_scalable(735; CHECK-NEXT: entry:736; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()737; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 4738; CHECK-NEXT: ret i64 [[TMP1]]739;740entry:741 %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1742 %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64743 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64744 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i745 ret i64 %sub.ptr.sub.i746}747 748define i64 @sub_scalable2(ptr noundef %val1) {749; CHECK-LABEL: @sub_scalable2(750; CHECK-NEXT: entry:751; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()752; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 4753; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64()754; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[TMP2]], 5755; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[TMP1]], [[GEP2_IDX]]756; CHECK-NEXT: ret i64 [[GEPDIFF]]757;758entry:759 %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1760 %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64761 %gep2 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 2762 %sub.ptr.rhs.cast.i = ptrtoint ptr %gep2 to i64763 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i764 ret i64 %sub.ptr.sub.i765}766 767define i64 @nullptrtoint_scalable_c() {768; CHECK-LABEL: @nullptrtoint_scalable_c(769; CHECK-NEXT: entry:770; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()771; CHECK-NEXT: [[PTR_IDX:%.*]] = shl i64 [[TMP0]], 7772; CHECK-NEXT: ret i64 [[PTR_IDX]]773;774entry:775 %ptr = getelementptr nusw <vscale x 4 x i32>, ptr null, i64 8776 %ret = ptrtoint ptr %ptr to i64777 ret i64 %ret778}779 780define i64 @nullptrtoint_scalable_x(i64 %x) {781; CHECK-LABEL: @nullptrtoint_scalable_x(782; CHECK-NEXT: entry:783; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()784; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 4785; CHECK-NEXT: [[PTR_IDX:%.*]] = mul nsw i64 [[X:%.*]], [[TMP1]]786; CHECK-NEXT: ret i64 [[PTR_IDX]]787;788entry:789 %ptr = getelementptr nusw <vscale x 4 x i32>, ptr null, i64 %x790 %ret = ptrtoint ptr %ptr to i64791 ret i64 %ret792}793 794define i1 @_gep_phi1(ptr %str1) {795; CHECK-LABEL: @_gep_phi1(796; CHECK-NEXT: entry:797; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null798; CHECK-NEXT: br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]]799; CHECK: lor.lhs.false.i:800; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1801; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0802; CHECK-NEXT: br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]]803; CHECK: while.cond.i:804; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ]805; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1806; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1807; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0808; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]809; CHECK: while.end.i:810; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]]811; CHECK: _Z3fooPKc.exit:812; CHECK-NEXT: [[TOBOOL:%.*]] = phi i1 [ true, [[WHILE_END_I]] ], [ false, [[LOR_LHS_FALSE_I]] ], [ false, [[ENTRY:%.*]] ]813; CHECK-NEXT: ret i1 [[TOBOOL]]814;815entry:816 %cmp.i = icmp eq ptr %str1, null817 br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i818 819lor.lhs.false.i:820 %0 = load i8, ptr %str1, align 1821 %cmp1.i = icmp eq i8 %0, 0822 br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i823 824while.cond.i:825 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ]826 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1827 %1 = load i8, ptr %test.0.i, align 1828 %cmp3.not.i = icmp eq i8 %1, 0829 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i830 831while.end.i:832 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64833 %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64834 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i835 br label %_Z3fooPKc.exit836 837_Z3fooPKc.exit:838 %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ]839 %tobool = icmp ne i64 %retval.0.i, 0840 ret i1 %tobool841}842 843define i1 @_gep_phi2(ptr %str1, i64 %val2) {844; CHECK-LABEL: @_gep_phi2(845; CHECK-NEXT: entry:846; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null847; CHECK-NEXT: br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]]848; CHECK: lor.lhs.false.i:849; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1850; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0851; CHECK-NEXT: br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]]852; CHECK: while.cond.i:853; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ]854; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1855; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1856; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0857; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]858; CHECK: while.end.i:859; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]]860; CHECK: _Z3fooPKc.exit:861; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ 1, [[WHILE_END_I]] ], [ [[VAL2:%.*]], [[LOR_LHS_FALSE_I]] ], [ [[VAL2]], [[ENTRY:%.*]] ]862; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[TMP2]], 0863; CHECK-NEXT: ret i1 [[TOBOOL]]864;865entry:866 %cmp.i = icmp eq ptr %str1, null867 br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i868 869lor.lhs.false.i:870 %0 = load i8, ptr %str1, align 1871 %cmp1.i = icmp eq i8 %0, 0872 br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i873 874while.cond.i:875 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ]876 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1877 %1 = load i8, ptr %test.0.i, align 1878 %cmp3.not.i = icmp eq i8 %1, 0879 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i880 881while.end.i:882 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64883 %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64884 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i885 br label %_Z3fooPKc.exit886 887_Z3fooPKc.exit:888 %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ]889 %2 = or i64 %retval.0.i, %val2890 %tobool = icmp eq i64 %2, 0891 ret i1 %tobool892}893 894define i64 @multiple_geps_one_chain(ptr %base, i64 %idx, i64 %idx2) {895; CHECK-LABEL: @multiple_geps_one_chain(896; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]897; CHECK-NEXT: [[D:%.*]] = shl i64 [[P2_IDX1]], 2898; CHECK-NEXT: ret i64 [[D]]899;900 %p2 = getelementptr inbounds i32, ptr %base, i64 %idx901 %p3 = getelementptr inbounds i32, ptr %p2, i64 %idx2902 %i1 = ptrtoint ptr %base to i64903 %i2 = ptrtoint ptr %p3 to i64904 %d = sub i64 %i2, %i1905 ret i64 %d906}907 908define i64 @multiple_geps_one_chain_commuted(ptr %base, i64 %idx, i64 %idx2) {909; CHECK-LABEL: @multiple_geps_one_chain_commuted(910; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]911; CHECK-NEXT: [[DOTNEG:%.*]] = mul i64 [[P2_IDX1]], -4912; CHECK-NEXT: ret i64 [[DOTNEG]]913;914 %p2 = getelementptr inbounds i32, ptr %base, i64 %idx915 %p3 = getelementptr inbounds i32, ptr %p2, i64 %idx2916 %i1 = ptrtoint ptr %base to i64917 %i2 = ptrtoint ptr %p3 to i64918 %d = sub i64 %i1, %i2919 ret i64 %d920}921 922define i64 @multiple_geps_two_chains(ptr %base, i64 %idx, i64 %idx2, i64 %idx3) {923; CHECK-LABEL: @multiple_geps_two_chains(924; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]925; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[P2_IDX1]], [[IDX3:%.*]]926; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2927; CHECK-NEXT: ret i64 [[GEPDIFF]]928;929 %p2 = getelementptr inbounds i32, ptr %base, i64 %idx930 %p3 = getelementptr inbounds i32, ptr %p2, i64 %idx2931 %p4 = getelementptr inbounds i32, ptr %base, i64 %idx3932 %i1 = ptrtoint ptr %p4 to i64933 %i2 = ptrtoint ptr %p3 to i64934 %d = sub i64 %i2, %i1935 ret i64 %d936}937 938define i64 @multiple_geps_two_chains_commuted(ptr %base, i64 %idx, i64 %idx2, i64 %idx3) {939; CHECK-LABEL: @multiple_geps_two_chains_commuted(940; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]941; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[IDX3:%.*]], [[P2_IDX1]]942; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2943; CHECK-NEXT: ret i64 [[GEPDIFF]]944;945 %p2 = getelementptr inbounds i32, ptr %base, i64 %idx946 %p3 = getelementptr inbounds i32, ptr %p2, i64 %idx2947 %p4 = getelementptr inbounds i32, ptr %base, i64 %idx3948 %i1 = ptrtoint ptr %p4 to i64949 %i2 = ptrtoint ptr %p3 to i64950 %d = sub i64 %i1, %i2951 ret i64 %d952}953 954declare void @use(ptr)955 956define i64 @multiple_geps_two_chains_gep_base(ptr %base, i64 %base.idx, i64 %idx, i64 %idx2, i64 %idx3) {957; CHECK-LABEL: @multiple_geps_two_chains_gep_base(958; CHECK-NEXT: [[GEP_BASE:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[BASE_IDX:%.*]]959; CHECK-NEXT: call void @use(ptr [[GEP_BASE]])960; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]961; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[P2_IDX1]], [[IDX3:%.*]]962; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2963; CHECK-NEXT: ret i64 [[GEPDIFF]]964;965 %gep.base = getelementptr inbounds i32, ptr %base, i64 %base.idx966 call void @use(ptr %gep.base)967 %p2 = getelementptr inbounds i32, ptr %gep.base, i64 %idx968 %p3 = getelementptr inbounds i32, ptr %p2, i64 %idx2969 %p4 = getelementptr inbounds i32, ptr %gep.base, i64 %idx3970 %i1 = ptrtoint ptr %p4 to i64971 %i2 = ptrtoint ptr %p3 to i64972 %d = sub i64 %i2, %i1973 ret i64 %d974}975 976define i64 @multiple_geps_two_chains_multi_use(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {977; CHECK-LABEL: @multiple_geps_two_chains_multi_use(978; CHECK-NEXT: [[P1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]979; CHECK-NEXT: [[P4_IDX:%.*]] = shl i64 [[P1_IDX1]], 2980; CHECK-NEXT: [[P5:%.*]] = getelementptr inbounds i8, ptr [[P2:%.*]], i64 [[P4_IDX]]981; CHECK-NEXT: [[P3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]982; CHECK-NEXT: [[P4_IDX1:%.*]] = shl i64 [[P3_IDX2]], 2983; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[P4_IDX1]]984; CHECK-NEXT: call void @use(ptr [[P5]])985; CHECK-NEXT: call void @use(ptr [[P4]])986; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[P4_IDX]], [[P4_IDX1]]987; CHECK-NEXT: ret i64 [[GEPDIFF]]988;989 %p1 = getelementptr inbounds i32, ptr %base, i64 %idx1990 %p2 = getelementptr inbounds i32, ptr %p1, i64 %idx2991 %p3 = getelementptr inbounds i32, ptr %base, i64 %idx3992 %p4 = getelementptr inbounds i32, ptr %p3, i64 %idx4993 call void @use(ptr %p2)994 call void @use(ptr %p4)995 %i1 = ptrtoint ptr %p4 to i64996 %i2 = ptrtoint ptr %p2 to i64997 %d = sub i64 %i2, %i1998 ret i64 %d999}1000 1001define i64 @multiple_geps_two_chains_partial_multi_use(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4, i64 %idx5, i64 %idx6) {1002; CHECK-LABEL: @multiple_geps_two_chains_partial_multi_use(1003; CHECK-NEXT: [[P1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]1004; CHECK-NEXT: [[P4_IDX:%.*]] = shl i64 [[P1_IDX1]], 21005; CHECK-NEXT: [[P3:%.*]] = getelementptr inbounds i8, ptr [[P2:%.*]], i64 [[P4_IDX]]1006; CHECK-NEXT: [[P4_IDX2:%.*]] = add i64 [[IDX4:%.*]], [[IDX5:%.*]]1007; CHECK-NEXT: [[P5_IDX:%.*]] = shl i64 [[P4_IDX2]], 21008; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[P5_IDX]]1009; CHECK-NEXT: call void @use(ptr [[P3]])1010; CHECK-NEXT: call void @use(ptr [[P4]])1011; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[P1_IDX1]], [[IDX3:%.*]]1012; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[P4_IDX2]], [[IDX6:%.*]]1013; CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[TMP3]], [[TMP4]]1014; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP5]], 21015; CHECK-NEXT: ret i64 [[GEPDIFF]]1016;1017 %p1 = getelementptr inbounds i32, ptr %base, i64 %idx11018 %p2 = getelementptr inbounds i32, ptr %p1, i64 %idx21019 %p3 = getelementptr inbounds i32, ptr %p2, i64 %idx31020 %p4 = getelementptr inbounds i32, ptr %base, i64 %idx41021 %p5 = getelementptr inbounds i32, ptr %p4, i64 %idx51022 %p6 = getelementptr inbounds i32, ptr %p5, i64 %idx61023 call void @use(ptr %p2)1024 call void @use(ptr %p5)1025 %i1 = ptrtoint ptr %p6 to i641026 %i2 = ptrtoint ptr %p3 to i641027 %d = sub i64 %i2, %i11028 ret i64 %d1029}1030 1031define i64 @multiple_geps_two_chains_partial_multi_use_insert_point(ptr %p, i64 %idx1, i64 %idx2, i64 %idx3) {1032; CHECK-LABEL: @multiple_geps_two_chains_partial_multi_use_insert_point(1033; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 81034; CHECK-NEXT: call void @use(ptr [[GEP2]])1035; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[IDX2:%.*]], [[IDX3:%.*]]1036; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[TMP1]]1037; CHECK-NEXT: call void @use(ptr [[GEP4]])1038; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 81039; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[IDX1:%.*]], [[TMP2]]1040; CHECK-NEXT: ret i64 [[GEPDIFF]]1041;1042 %gep1 = getelementptr i8, ptr %p, i64 %idx11043 %gep2 = getelementptr i8, ptr %p, i64 81044 call void @use(ptr %gep2)1045 %gep3 = getelementptr i8, ptr %gep2, i64 %idx21046 %gep4 = getelementptr i8, ptr %gep3, i64 %idx31047 call void @use(ptr %gep4)1048 %gep1.int = ptrtoint ptr %gep1 to i641049 %gep4.int = ptrtoint ptr %gep4 to i641050 %sub = sub i64 %gep1.int, %gep4.int1051 ret i64 %sub1052}1053 1054define i64 @multiple_geps_inbounds(ptr %base, i64 %idx, i64 %idx2) {1055; CHECK-LABEL: @multiple_geps_inbounds(1056; CHECK-NEXT: [[D:%.*]] = add nsw i64 [[IDX:%.*]], [[IDX2:%.*]]1057; CHECK-NEXT: ret i64 [[D]]1058;1059 %p2 = getelementptr inbounds i8, ptr %base, i64 %idx1060 %p3 = getelementptr inbounds i8, ptr %p2, i64 %idx21061 %i1 = ptrtoint ptr %base to i641062 %i2 = ptrtoint ptr %p3 to i641063 %d = sub i64 %i2, %i11064 ret i64 %d1065}1066 1067define i64 @multiple_geps_nusw(ptr %base, i64 %idx, i64 %idx2) {1068; CHECK-LABEL: @multiple_geps_nusw(1069; CHECK-NEXT: [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]1070; CHECK-NEXT: ret i64 [[D]]1071;1072 %p2 = getelementptr nusw i8, ptr %base, i64 %idx1073 %p3 = getelementptr nusw i8, ptr %p2, i64 %idx21074 %i1 = ptrtoint ptr %base to i641075 %i2 = ptrtoint ptr %p3 to i641076 %d = sub i64 %i2, %i11077 ret i64 %d1078}1079 1080define i64 @multiple_geps_nuw(ptr %base, i64 %idx, i64 %idx2) {1081; CHECK-LABEL: @multiple_geps_nuw(1082; CHECK-NEXT: [[D:%.*]] = add nuw i64 [[IDX:%.*]], [[IDX2:%.*]]1083; CHECK-NEXT: ret i64 [[D]]1084;1085 %p2 = getelementptr nuw i8, ptr %base, i64 %idx1086 %p3 = getelementptr nuw i8, ptr %p2, i64 %idx21087 %i1 = ptrtoint ptr %base to i641088 %i2 = ptrtoint ptr %p3 to i641089 %d = sub i64 %i2, %i11090 ret i64 %d1091}1092 1093 1094define i64 @multiple_geps_inbounds_nuw(ptr %base, i64 %idx, i64 %idx2) {1095; CHECK-LABEL: @multiple_geps_inbounds_nuw(1096; CHECK-NEXT: [[D:%.*]] = add nuw nsw i64 [[IDX:%.*]], [[IDX2:%.*]]1097; CHECK-NEXT: ret i64 [[D]]1098;1099 %p2 = getelementptr inbounds nuw i8, ptr %base, i64 %idx1100 %p3 = getelementptr inbounds nuw i8, ptr %p2, i64 %idx21101 %i1 = ptrtoint ptr %base to i641102 %i2 = ptrtoint ptr %p3 to i641103 %d = sub i64 %i2, %i11104 ret i64 %d1105}1106 1107define <2 x i64> @splat_geps(ptr %base, <2 x i64> %idx1, <2 x i64> %idx2) {1108; CHECK-LABEL: @splat_geps(1109; CHECK-NEXT: [[D:%.*]] = sub nsw <2 x i64> [[IDX2:%.*]], [[IDX1:%.*]]1110; CHECK-NEXT: ret <2 x i64> [[D]]1111;1112 %gep1 = getelementptr inbounds i8, ptr %base, <2 x i64> %idx11113 %gep2 = getelementptr inbounds i8, ptr %base, <2 x i64> %idx21114 %gep1.int = ptrtoint <2 x ptr> %gep1 to <2 x i64>1115 %gep2.int = ptrtoint <2 x ptr> %gep2 to <2 x i64>1116 %d = sub <2 x i64> %gep2.int, %gep1.int1117 ret <2 x i64> %d1118}1119 1120define <2 x i64> @splat_geps_multiple(ptr %base, i64 %idx0, <2 x i64> %idx1, <2 x i64> %idx2) {1121; CHECK-LABEL: @splat_geps_multiple(1122; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX0:%.*]], i64 01123; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer1124; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[DOTSPLAT]], [[IDX1:%.*]]1125; CHECK-NEXT: [[D:%.*]] = sub nsw <2 x i64> [[IDX2:%.*]], [[TMP1]]1126; CHECK-NEXT: ret <2 x i64> [[D]]1127;1128 %gep0 = getelementptr inbounds i8, ptr %base, i64 %idx01129 %gep1 = getelementptr inbounds i8, ptr %gep0, <2 x i64> %idx11130 %gep2 = getelementptr inbounds i8, ptr %base, <2 x i64> %idx21131 %gep1.int = ptrtoint <2 x ptr> %gep1 to <2 x i64>1132 %gep2.int = ptrtoint <2 x ptr> %gep2 to <2 x i64>1133 %d = sub <2 x i64> %gep2.int, %gep1.int1134 ret <2 x i64> %d1135}1136 1137define i64 @nuw_ptrdiff_shl_nsw(ptr %base, i64 %idx) {1138; CHECK-LABEL: @nuw_ptrdiff_shl_nsw(1139; CHECK-NEXT: [[OFFSET:%.*]] = shl nuw nsw i64 [[IDX:%.*]], 31140; CHECK-NEXT: ret i64 [[OFFSET]]1141;1142 %offset = shl nsw i64 %idx, 31143 %gep = getelementptr inbounds i8, ptr %base, i64 %offset1144 %lhs = ptrtoint ptr %gep to i641145 %rhs = ptrtoint ptr %base to i641146 %diff = sub nuw i64 %lhs, %rhs1147 ret i64 %diff1148}1149 1150define i64 @nuw_ptrdiff_shl_nonsw(ptr %base, i64 %idx) {1151; CHECK-LABEL: @nuw_ptrdiff_shl_nonsw(1152; CHECK-NEXT: [[OFFSET:%.*]] = shl i64 [[IDX:%.*]], 31153; CHECK-NEXT: ret i64 [[OFFSET]]1154;1155 %offset = shl i64 %idx, 31156 %gep = getelementptr inbounds i8, ptr %base, i64 %offset1157 %lhs = ptrtoint ptr %gep to i641158 %rhs = ptrtoint ptr %base to i641159 %diff = sub nuw i64 %lhs, %rhs1160 ret i64 %diff1161}1162 1163define i64 @nuw_ptrdiff_mul_nsw_nneg_scale(ptr %base, i64 %idx) {1164; CHECK-LABEL: @nuw_ptrdiff_mul_nsw_nneg_scale(1165; CHECK-NEXT: [[OFFSET:%.*]] = mul nuw nsw i64 [[IDX:%.*]], 31166; CHECK-NEXT: ret i64 [[OFFSET]]1167;1168 %offset = mul nsw i64 %idx, 31169 %gep = getelementptr inbounds i8, ptr %base, i64 %offset1170 %lhs = ptrtoint ptr %gep to i641171 %rhs = ptrtoint ptr %base to i641172 %diff = sub nuw i64 %lhs, %rhs1173 ret i64 %diff1174}1175 1176define i64 @nuw_ptrdiff_mul_nsw_unknown_scale(ptr %base, i64 %idx, i64 %scale) {1177; CHECK-LABEL: @nuw_ptrdiff_mul_nsw_unknown_scale(1178; CHECK-NEXT: [[OFFSET:%.*]] = mul nsw i64 [[IDX:%.*]], [[SCALE:%.*]]1179; CHECK-NEXT: ret i64 [[OFFSET]]1180;1181 %offset = mul nsw i64 %idx, %scale1182 %gep = getelementptr inbounds i8, ptr %base, i64 %offset1183 %lhs = ptrtoint ptr %gep to i641184 %rhs = ptrtoint ptr %base to i641185 %diff = sub nuw i64 %lhs, %rhs1186 ret i64 %diff1187}1188 1189declare void @usei64(i64)1190 1191define i64 @nuw_ptrdiff_mul_nsw_nneg_scale_multiuse(ptr %base, i64 %idx) {1192; CHECK-LABEL: @nuw_ptrdiff_mul_nsw_nneg_scale_multiuse(1193; CHECK-NEXT: [[OFFSET:%.*]] = mul nsw i64 [[IDX:%.*]], 31194; CHECK-NEXT: call void @usei64(i64 [[OFFSET]])1195; CHECK-NEXT: ret i64 [[OFFSET]]1196;1197 %offset = mul nsw i64 %idx, 31198 call void @usei64(i64 %offset)1199 %gep = getelementptr inbounds i8, ptr %base, i64 %offset1200 %lhs = ptrtoint ptr %gep to i641201 %rhs = ptrtoint ptr %base to i641202 %diff = sub nuw i64 %lhs, %rhs1203 ret i64 %diff1204}1205 1206define i64 @multiple_geps_multi_use_below_limit(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {1207; CHECK-LABEL: @multiple_geps_multi_use_below_limit(1208; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds nuw i8, ptr [[P1:%.*]], i64 [[IDX2:%.*]]1209; CHECK-NEXT: call void @use(ptr [[P2]])1210; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds nuw i8, ptr [[P2]], i64 [[IDX5:%.*]]1211; CHECK-NEXT: call void @use(ptr [[P4]])1212; CHECK-NEXT: [[P3:%.*]] = getelementptr inbounds nuw i8, ptr [[P1]], i64 [[IDX3:%.*]]1213; CHECK-NEXT: call void @use(ptr [[P3]])1214; CHECK-NEXT: [[P5:%.*]] = getelementptr inbounds nuw i8, ptr [[P3]], i64 [[IDX4:%.*]]1215; CHECK-NEXT: call void @use(ptr [[P5]])1216; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[IDX2]], [[IDX5]]1217; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[IDX3]], [[IDX4]]1218; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[TMP1]], [[TMP2]]1219; CHECK-NEXT: ret i64 [[GEPDIFF]]1220;1221 %p1 = getelementptr inbounds nuw i8, ptr %base, i64 %idx11222 call void @use(ptr %p1)1223 %p2 = getelementptr inbounds nuw i8, ptr %p1, i64 %idx21224 call void @use(ptr %p2)1225 %p3 = getelementptr inbounds nuw i8, ptr %base, i64 %idx31226 call void @use(ptr %p3)1227 %p4 = getelementptr inbounds nuw i8, ptr %p3, i64 %idx41228 call void @use(ptr %p4)1229 %i1 = ptrtoint ptr %p4 to i641230 %i2 = ptrtoint ptr %p2 to i641231 %d = sub i64 %i2, %i11232 ret i64 %d1233}1234 1235define i64 @multiple_geps_multi_use_above_limit(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4, i64 %idx5) {1236; CHECK-LABEL: @multiple_geps_multi_use_above_limit(1237; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds nuw i8, ptr [[P1:%.*]], i64 [[IDX2:%.*]]1238; CHECK-NEXT: call void @use(ptr [[P2]])1239; CHECK-NEXT: [[P3:%.*]] = getelementptr inbounds nuw i8, ptr [[P2]], i64 [[IDX6:%.*]]1240; CHECK-NEXT: call void @use(ptr [[P3]])1241; CHECK-NEXT: [[P5:%.*]] = getelementptr inbounds nuw i8, ptr [[P1]], i64 [[TMP3:%.*]]1242; CHECK-NEXT: call void @use(ptr [[P5]])1243; CHECK-NEXT: [[P6:%.*]] = getelementptr inbounds nuw i8, ptr [[P5]], i64 [[IDX7:%.*]]1244; CHECK-NEXT: call void @use(ptr [[P6]])1245; CHECK-NEXT: [[P7:%.*]] = getelementptr inbounds nuw i8, ptr [[P6]], i64 [[IDX5:%.*]]1246; CHECK-NEXT: call void @use(ptr [[P7]])1247; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P7]] to i641248; CHECK-NEXT: [[I2:%.*]] = ptrtoint ptr [[P3]] to i641249; CHECK-NEXT: [[D:%.*]] = sub i64 [[I2]], [[I1]]1250; CHECK-NEXT: ret i64 [[D]]1251;1252 %p1 = getelementptr inbounds nuw i8, ptr %base, i64 %idx11253 call void @use(ptr %p1)1254 %p2 = getelementptr inbounds nuw i8, ptr %p1, i64 %idx21255 call void @use(ptr %p2)1256 %p3 = getelementptr inbounds nuw i8, ptr %base, i64 %idx31257 call void @use(ptr %p3)1258 %p4 = getelementptr inbounds nuw i8, ptr %p3, i64 %idx41259 call void @use(ptr %p4)1260 %p5 = getelementptr inbounds nuw i8, ptr %p4, i64 %idx51261 call void @use(ptr %p5)1262 %i1 = ptrtoint ptr %p5 to i641263 %i2 = ptrtoint ptr %p2 to i641264 %d = sub i64 %i2, %i11265 ret i64 %d1266}1267