brintos

brintos / llvm-project-archived public Read only

0
0
Text · 47.0 KiB · 01da63f Raw
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