1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 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" 5 6define i64 @test_inbounds(ptr %base, i64 %idx) { 7; CHECK-LABEL: @test_inbounds( 8; CHECK-NEXT: [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 2 9; CHECK-NEXT: ret i64 [[P2_IDX]] 10; 11 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 12 %i1 = ptrtoint ptr %base to i64 13 %i2 = ptrtoint ptr %p2 to i64 14 %d = sub i64 %i2, %i1 15 ret i64 %d 16} 17 18define i64 @test_partial_inbounds1(ptr %base, i64 %idx) { 19; CHECK-LABEL: @test_partial_inbounds1( 20; CHECK-NEXT: [[P2_IDX:%.*]] = shl i64 [[IDX:%.*]], 2 21; CHECK-NEXT: ret i64 [[P2_IDX]] 22; 23 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx 24 %i1 = ptrtoint ptr %base to i64 25 %i2 = ptrtoint ptr %p2 to i64 26 %d = sub i64 %i2, %i1 27 ret i64 %d 28} 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:%.*]], 2 33; CHECK-NEXT: ret i64 [[P2_IDX]] 34; 35 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 36 %i1 = ptrtoint ptr %base to i64 37 %i2 = ptrtoint ptr %p2 to i64 38 %d = sub i64 %i2, %i1 39 ret i64 %d 40} 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:%.*]], 2 45; CHECK-NEXT: ret i64 [[P2_IDX]] 46; 47 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 48 %i1 = ptrtoint ptr %base to i64 49 %i2 = ptrtoint ptr %p2 to i64 50 %d = sub nuw i64 %i2, %i1 51 ret i64 %d 52} 53 54define i64 @test_nuw(ptr %base, i64 %idx) { 55; CHECK-LABEL: @test_nuw( 56; CHECK-NEXT: [[P2_IDX:%.*]] = shl i64 [[IDX:%.*]], 2 57; CHECK-NEXT: ret i64 [[P2_IDX]] 58; 59 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx 60 %i1 = ptrtoint ptr %base to i64 61 %i2 = ptrtoint ptr %p2 to i64 62 %d = sub nuw i64 %i2, %i1 63 ret i64 %d 64} 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 i32 69; CHECK-NEXT: [[D:%.*]] = shl i32 [[IDX_TR]], 2 70; CHECK-NEXT: ret i32 [[D]] 71; 72 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 73 %i1 = ptrtoint ptr %base to i64 74 %i2 = ptrtoint ptr %p2 to i64 75 %t1 = trunc i64 %i1 to i32 76 %t2 = trunc i64 %i2 to i32 77 %d = sub nuw i32 %t2, %t1 78 ret i32 %d 79} 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 i64 [[IDX:%.*]], -4 84; CHECK-NEXT: ret i64 [[P2_IDX_NEG]] 85; 86 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 87 %i1 = ptrtoint ptr %p2 to i64 88 %i2 = ptrtoint ptr %base to i64 89 %d = sub nuw i64 %i2, %i1 90 ret i64 %d 91} 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:%.*]], -4 96; CHECK-NEXT: ret i64 [[P2_IDX_NEG]] 97; 98 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx 99 %i1 = ptrtoint ptr %p2 to i64 100 %i2 = ptrtoint ptr %base to i64 101 %d = sub nuw i64 %i2, %i1 102 ret i64 %d 103} 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 i64 [[IDX:%.*]], -4 108; CHECK-NEXT: ret i64 [[P2_IDX_NEG]] 109; 110 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 111 %i1 = ptrtoint ptr %p2 to i64 112 %i2 = ptrtoint ptr %base to i64 113 %d = sub nuw i64 %i2, %i1 114 ret i64 %d 115} 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]], 2 121; CHECK-NEXT: ret i64 [[GEPDIFF]] 122; 123 %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 124 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2 125 %i1 = ptrtoint ptr %p1 to i64 126 %i2 = ptrtoint ptr %p2 to i64 127 %d = sub i64 %i2, %i1 128 ret i64 %d 129} 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]], 2 135; CHECK-NEXT: ret i64 [[GEPDIFF]] 136; 137 %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 138 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2 139 %i1 = ptrtoint ptr %p1 to i64 140 %i2 = ptrtoint ptr %p2 to i64 141 %d = sub nsw i64 %i2, %i1 142 ret i64 %d 143} 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]], 2 149; CHECK-NEXT: ret i64 [[GEPDIFF]] 150; 151 %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx 152 %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2 153 %i1 = ptrtoint ptr %p1 to i64 154 %i2 = ptrtoint ptr %p2 to i64 155 %d = sub nuw i64 %i2, %i1 156 ret i64 %d 157} 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]], 2 163; CHECK-NEXT: ret i64 [[GEPDIFF]] 164; 165 %p1 = getelementptr nusw [0 x i32], ptr %base, i64 0, i64 %idx 166 %p2 = getelementptr nusw [0 x i32], ptr %base, i64 0, i64 %idx2 167 %i1 = ptrtoint ptr %p1 to i64 168 %i2 = ptrtoint ptr %p2 to i64 169 %d = sub i64 %i2, %i1 170 ret i64 %d 171} 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]], 2 177; CHECK-NEXT: ret i64 [[GEPDIFF]] 178; 179 %p1 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx 180 %p2 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx2 181 %i1 = ptrtoint ptr %p1 to i64 182 %i2 = ptrtoint ptr %p2 to i64 183 %d = sub nuw i64 %i2, %i1 184 ret i64 %d 185} 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]], 2 191; CHECK-NEXT: ret i64 [[GEPDIFF]] 192; 193 %p1 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx 194 %p2 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx2 195 %i1 = ptrtoint ptr %p1 to i64 196 %i2 = ptrtoint ptr %p2 to i64 197 %d = sub i64 %i2, %i1 198 ret i64 %d 199} 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]], 2 205; CHECK-NEXT: ret i64 [[GEPDIFF]] 206; 207 %p1 = getelementptr nuw [0 x i32], ptr %base, i64 0, i64 %idx 208 %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx2 209 %i1 = ptrtoint ptr %p1 to i64 210 %i2 = ptrtoint ptr %p2 to i64 211 %d = sub nuw i64 %i2, %i1 212 ret i64 %d 213} 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_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 3 218; CHECK-NEXT: [[P2_IDX1:%.*]] = shl nsw i64 [[IDX2:%.*]], 2 219; CHECK-NEXT: [[P2_OFFS:%.*]] = add nsw i64 [[P2_IDX]], [[P2_IDX1]] 220; CHECK-NEXT: ret i64 [[P2_OFFS]] 221; 222 %p2 = getelementptr inbounds [0 x [2 x i32]], ptr %base, i64 0, i64 %idx, i64 %idx2 223 %i1 = ptrtoint ptr %base to i64 224 %i2 = ptrtoint ptr %p2 to i64 225 %d = sub nuw i64 %i2, %i1 226 ret i64 %d 227} 228 229; rdar://7362831 230define i32 @test23(ptr %P, i64 %A){ 231; CHECK-LABEL: @test23( 232; CHECK-NEXT: [[G:%.*]] = trunc i64 [[A:%.*]] to i32 233; CHECK-NEXT: ret i32 [[G]] 234; 235 %B = getelementptr inbounds i8, ptr %P, i64 %A 236 %C = ptrtoint ptr %B to i64 237 %D = trunc i64 %C to i32 238 %E = ptrtoint ptr %P to i64 239 %F = trunc i64 %E to i32 240 %G = sub i32 %D, %F 241 ret i32 %G 242} 243 244define i8 @test23_as1(ptr addrspace(1) %P, i16 %A) { 245; CHECK-LABEL: @test23_as1( 246; CHECK-NEXT: [[G:%.*]] = trunc i16 [[A:%.*]] to i8 247; CHECK-NEXT: ret i8 [[G]] 248; 249 %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A 250 %C = ptrtoint ptr addrspace(1) %B to i16 251 %D = trunc i16 %C to i8 252 %E = ptrtoint ptr addrspace(1) %P to i16 253 %F = trunc i16 %E to i8 254 %G = sub i8 %D, %F 255 ret i8 %G 256} 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 %A 263 %C = ptrtoint ptr %B to i64 264 %E = ptrtoint ptr %P to i64 265 %G = sub i64 %C, %E 266 ret i64 %G 267} 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 %A 274 %C = ptrtoint ptr addrspace(1) %B to i16 275 %E = ptrtoint ptr addrspace(1) %P to i16 276 %G = sub i16 %C, %E 277 ret i16 %G 278} 279 280define i64 @test24a(ptr %P, i64 %A){ 281; CHECK-LABEL: @test24a( 282; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, [[A:%.*]] 283; CHECK-NEXT: ret i64 [[DIFF_NEG]] 284; 285 %B = getelementptr inbounds i8, ptr %P, i64 %A 286 %C = ptrtoint ptr %B to i64 287 %E = ptrtoint ptr %P to i64 288 %G = sub i64 %E, %C 289 ret i64 %G 290} 291 292define i16 @test24a_as1(ptr addrspace(1) %P, i16 %A) { 293; CHECK-LABEL: @test24a_as1( 294; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i16 0, [[A:%.*]] 295; CHECK-NEXT: ret i16 [[DIFF_NEG]] 296; 297 %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A 298 %C = ptrtoint ptr addrspace(1) %B to i16 299 %E = ptrtoint ptr addrspace(1) %P to i16 300 %G = sub i16 %E, %C 301 ret i16 %G 302} 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:%.*]], 1 309; CHECK-NEXT: ret i64 [[B_IDX]] 310; 311 %B = getelementptr inbounds [42 x i16], ptr @Arr, i64 0, i64 %A 312 %C = ptrtoint ptr %B to i64 313 %G = sub i64 %C, ptrtoint (ptr @Arr to i64) 314 ret i64 %G 315} 316 317define i64 @test25(ptr %P, i64 %A){ 318; CHECK-LABEL: @test25( 319; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1 320; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i64 [[B_IDX]], -84 321; CHECK-NEXT: ret i64 [[GEPDIFF]] 322; 323 %B = getelementptr inbounds [42 x i16], ptr @Arr, i64 0, i64 %A 324 %C = ptrtoint ptr %B to i64 325 %G = sub i64 %C, ptrtoint (ptr getelementptr ([42 x i16], ptr @Arr, i64 1, i64 0) to i64) 326 ret i64 %G 327} 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 i64 332; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] 333; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 334; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 4294967294 335; 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 %offset 339 %B = ptrtoint ptr %A to i32 340 %C = zext i32 %B to i64 341 %D = sub i64 %C, ptrtoint (ptr @Arr to i64) 342 ret i64 %D 343} 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 i64 348; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] 349; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 350; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 4294967294 351; 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 %offset 355 %B = ptrtoint ptr %A to i32 356 %C = zext i32 %B to i64 357 %D = sub i64 ptrtoint (ptr @Arr to i64), %C 358 ret i64 %D 359} 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 i64 364; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] 365; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 366; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 65534 367; 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 %offset 371 %B = ptrtoint ptr %A to i16 372 %C = zext i16 %B to i64 373 %D = sub i64 %C, ptrtoint (ptr @Arr to i64) 374 ret i64 %D 375} 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 i64 380; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] 381; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 382; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 65534 383; 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 %offset 387 %B = ptrtoint ptr %A to i16 388 %C = zext i16 %B to i64 389 %D = sub i64 ptrtoint (ptr @Arr to i64), %C 390 ret i64 %D 391} 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 i64 [[A:%.*]] to i16 398; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i16 [[TMP1]], 1 399; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i16 [[B_IDX]], -84 400; CHECK-NEXT: ret i16 [[GEPDIFF]] 401; 402 %B = getelementptr inbounds [42 x i16], ptr addrspace(1) @Arr_as1, i64 0, i64 %A 403 %C = ptrtoint ptr addrspace(1) %B to i16 404 %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 %G 406} 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 i32 414; CHECK-NEXT: [[C:%.*]] = zext i32 [[B]] to i64 415; 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 %offset 419 %B = ptrtoint ptr addrspace(2) %A to i32 420 %C = zext i32 %B to i64 421 %D = sub i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C 422 ret i64 %D 423} 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:%.*]], 1 428; CHECK-NEXT: [[D:%.*]] = sext i32 [[A_IDX]] to i64 429; CHECK-NEXT: ret i64 [[D]] 430; 431 %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset 432 %B = ptrtoint ptr addrspace(2) %A to i32 433 %C = zext i32 %B to i64 434 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) 435 ret i64 %D 436} 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:%.*]], 1 441; CHECK-NEXT: [[D:%.*]] = zext i32 [[A_IDX]] to i64 442; CHECK-NEXT: ret i64 [[D]] 443; 444 %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset 445 %B = ptrtoint ptr addrspace(2) %A to i32 446 %C = zext i32 %B to i64 447 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) 448 ret i64 %D 449} 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:%.*]], 1 454; CHECK-NEXT: [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64 455; CHECK-NEXT: ret i64 [[D]] 456; 457 %A = getelementptr nusw nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset 458 %B = ptrtoint ptr addrspace(2) %A to i32 459 %C = zext i32 %B to i64 460 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) 461 ret i64 %D 462} 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:%.*]], 1 467; CHECK-NEXT: [[E:%.*]] = sext i32 [[A_IDX]] to i64 468; CHECK-NEXT: ret i64 [[E]] 469; 470 %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset 471 %B = ptrtoint ptr addrspace(2) %A to i32 472 %C = zext i32 %B to i64 473 %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64 474 %E = sub i64 %C, %D 475 ret i64 %E 476} 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:%.*]], 1 481; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64 482; CHECK-NEXT: ret i64 [[E]] 483; 484 %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset 485 %B = ptrtoint ptr addrspace(2) %A to i32 486 %C = zext i32 %B to i64 487 %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64 488 %E = sub i64 %C, %D 489 ret i64 %E 490} 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 i32 496; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[TMP1]], 65534 497; CHECK-NEXT: [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64 498; 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 %offset 502 %B = ptrtoint ptr addrspace(2) %A to i16 503 %C = zext i16 %B to i64 504 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) 505 ret i64 %D 506} 507 508define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local(ptr addrspace(2) %p, i32 %offset) { 509; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local( 510; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]] 511; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32 512; CHECK-NEXT: [[C:%.*]] = zext i32 [[B]] to i64 513; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32 514; CHECK-NEXT: [[CC:%.*]] = zext i32 [[TMP1]] to i64 515; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[CC]], [[C]] 516; CHECK-NEXT: ret i64 [[D]] 517; 518 %A = getelementptr inbounds bfloat, ptr addrspace(2) %p, i32 %offset 519 %B = ptrtoint ptr addrspace(2) %A to i32 520 %C = zext i32 %B to i64 521 %CC = ptrtoint ptr addrspace(2) %p to i64 522 %D = sub i64 %CC, %C 523 ret i64 %D 524} 525 526define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) { 527; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_local( 528; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1 529; CHECK-NEXT: [[D:%.*]] = sext i32 [[A_IDX]] to i64 530; CHECK-NEXT: ret i64 [[D]] 531; 532 %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset 533 %B = ptrtoint ptr addrspace(2) %A to i32 534 %C = zext i32 %B to i64 535 %CC = ptrtoint ptr addrspace(2) %p to i64 536 %D = sub i64 %C, %CC 537 ret i64 %D 538} 539 540define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) { 541; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw_local( 542; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1 543; CHECK-NEXT: [[D:%.*]] = zext i32 [[A_IDX]] to i64 544; CHECK-NEXT: ret i64 [[D]] 545; 546 %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset 547 %B = ptrtoint ptr addrspace(2) %A to i32 548 %C = zext i32 %B to i64 549 %CC = ptrtoint ptr addrspace(2) %p to i64 550 %D = sub i64 %C, %CC 551 ret i64 %D 552} 553 554define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local(ptr addrspace(2) %p, i32 %offset) { 555; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local( 556; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1 557; CHECK-NEXT: [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64 558; CHECK-NEXT: ret i64 [[D]] 559; 560 %A = getelementptr nusw nuw bfloat, ptr addrspace(2) %p, i32 %offset 561 %B = ptrtoint ptr addrspace(2) %A to i32 562 %C = zext i32 %B to i64 563 %CC = ptrtoint ptr addrspace(2) %p to i64 564 %D = sub i64 %C, %CC 565 ret i64 %D 566} 567 568define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) { 569; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local( 570; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1 571; CHECK-NEXT: [[E:%.*]] = sext i32 [[A_IDX]] to i64 572; CHECK-NEXT: ret i64 [[E]] 573; 574 %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset 575 %B = ptrtoint ptr addrspace(2) %A to i32 576 %C = zext i32 %B to i64 577 %CC = ptrtoint ptr addrspace(2) %p to i32 578 %D = zext i32 %CC to i64 579 %E = sub i64 %C, %D 580 ret i64 %E 581} 582 583define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) { 584; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local( 585; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1 586; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64 587; CHECK-NEXT: ret i64 [[E]] 588; 589 %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset 590 %B = ptrtoint ptr addrspace(2) %A to i32 591 %C = zext i32 %B to i64 592 %CC = ptrtoint ptr addrspace(2) %p to i32 593 %D = zext i32 %CC to i64 594 %E = sub i64 %C, %D 595 ret i64 %E 596} 597 598define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) { 599; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local( 600; CHECK-NEXT: [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]] 601; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32 602; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[TMP1]], 65535 603; CHECK-NEXT: [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64 604; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32 605; CHECK-NEXT: [[CC:%.*]] = zext i32 [[TMP2]] to i64 606; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[C]], [[CC]] 607; CHECK-NEXT: ret i64 [[D]] 608; 609 %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset 610 %B = ptrtoint ptr addrspace(2) %A to i16 611 %C = zext i16 %B to i64 612 %CC = ptrtoint ptr addrspace(2) %p to i64 613 %D = sub i64 %C, %CC 614 ret i64 %D 615} 616 617define i64 @test30(ptr %foo, i64 %i, i64 %j) { 618; CHECK-LABEL: @test30( 619; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2 620; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[GEP1_IDX]], [[J:%.*]] 621; CHECK-NEXT: ret i64 [[GEPDIFF]] 622; 623 %gep1 = getelementptr inbounds i32, ptr %foo, i64 %i 624 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j 625 %cast1 = ptrtoint ptr %gep1 to i64 626 %cast2 = ptrtoint ptr %gep2 to i64 627 %sub = sub i64 %cast1, %cast2 628 ret i64 %sub 629} 630 631define i16 @test30_as1(ptr addrspace(1) %foo, i16 %i, i16 %j) { 632; CHECK-LABEL: @test30_as1( 633; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2 634; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i16 [[GEP1_IDX]], [[J:%.*]] 635; CHECK-NEXT: ret i16 [[GEPDIFF]] 636; 637 %gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i16 %i 638 %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i16 %j 639 %cast1 = ptrtoint ptr addrspace(1) %gep1 to i16 640 %cast2 = ptrtoint ptr addrspace(1) %gep2 to i16 641 %sub = sub i16 %cast1, %cast2 642 ret i16 %sub 643} 644 645; Inbounds translates to 'nsw' on sub 646 647define i64 @gep_diff_both_inbounds(ptr %foo, i64 %i, i64 %j) { 648; CHECK-LABEL: @gep_diff_both_inbounds( 649; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[I:%.*]], [[J:%.*]] 650; CHECK-NEXT: ret i64 [[GEPDIFF]] 651; 652 %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i 653 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j 654 %cast1 = ptrtoint ptr %gep1 to i64 655 %cast2 = ptrtoint ptr %gep2 to i64 656 %sub = sub i64 %cast1, %cast2 657 ret i64 %sub 658} 659 660; Negative test for 'nsw' - both geps must be inbounds 661 662define i64 @gep_diff_first_inbounds(ptr %foo, i64 %i, i64 %j) { 663; CHECK-LABEL: @gep_diff_first_inbounds( 664; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]] 665; CHECK-NEXT: ret i64 [[GEPDIFF]] 666; 667 %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i 668 %gep2 = getelementptr i8, ptr %foo, i64 %j 669 %cast1 = ptrtoint ptr %gep1 to i64 670 %cast2 = ptrtoint ptr %gep2 to i64 671 %sub = sub i64 %cast1, %cast2 672 ret i64 %sub 673} 674 675; Negative test for 'nsw' - both geps must be inbounds 676 677define i64 @gep_diff_second_inbounds(ptr %foo, i64 %i, i64 %j) { 678; CHECK-LABEL: @gep_diff_second_inbounds( 679; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]] 680; CHECK-NEXT: ret i64 [[GEPDIFF]] 681; 682 %gep1 = getelementptr i8, ptr %foo, i64 %i 683 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j 684 %cast1 = ptrtoint ptr %gep1 to i64 685 %cast2 = ptrtoint ptr %gep2 to i64 686 %sub = sub i64 %cast1, %cast2 687 ret i64 %sub 688} 689 690define i64 @gep_diff_with_bitcast(ptr %p, i64 %idx) { 691; CHECK-LABEL: @gep_diff_with_bitcast( 692; CHECK-NEXT: ret i64 [[IDX:%.*]] 693; 694 %i1 = getelementptr inbounds [4 x i64], ptr %p, i64 %idx 695 %i3 = ptrtoint ptr %i1 to i64 696 %i4 = ptrtoint ptr %p to i64 697 %i5 = sub nuw i64 %i3, %i4 698 %i6 = lshr i64 %i5, 5 699 ret i64 %i6 700} 701 702define i64 @sub_scalable(ptr noundef %val1) { 703; CHECK-LABEL: @sub_scalable( 704; CHECK-NEXT: entry: 705; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 706; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 707; CHECK-NEXT: ret i64 [[TMP1]] 708; 709entry: 710 %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1 711 %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64 712 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 713 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 714 ret i64 %sub.ptr.sub.i 715} 716 717define i64 @sub_scalable2(ptr noundef %val1) { 718; CHECK-LABEL: @sub_scalable2( 719; CHECK-NEXT: entry: 720; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 721; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 722; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64() 723; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[TMP2]], 5 724; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[TMP1]], [[GEP2_IDX]] 725; CHECK-NEXT: ret i64 [[GEPDIFF]] 726; 727entry: 728 %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1 729 %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64 730 %gep2 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 2 731 %sub.ptr.rhs.cast.i = ptrtoint ptr %gep2 to i64 732 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 733 ret i64 %sub.ptr.sub.i 734} 735 736define i64 @nullptrtoint_scalable_c() { 737; CHECK-LABEL: @nullptrtoint_scalable_c( 738; CHECK-NEXT: entry: 739; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 740; CHECK-NEXT: [[PTR_IDX:%.*]] = shl i64 [[TMP0]], 7 741; CHECK-NEXT: ret i64 [[PTR_IDX]] 742; 743entry: 744 %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 8 745 %ret = ptrtoint ptr %ptr to i64 746 ret i64 %ret 747} 748 749define i64 @nullptrtoint_scalable_x(i64 %x) { 750; CHECK-LABEL: @nullptrtoint_scalable_x( 751; CHECK-NEXT: entry: 752; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 753; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 754; CHECK-NEXT: [[PTR_IDX:%.*]] = mul nsw i64 [[X:%.*]], [[TMP1]] 755; CHECK-NEXT: ret i64 [[PTR_IDX]] 756; 757entry: 758 %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 %x 759 %ret = ptrtoint ptr %ptr to i64 760 ret i64 %ret 761} 762 763define i1 @_gep_phi1(ptr %str1) { 764; CHECK-LABEL: @_gep_phi1( 765; CHECK-NEXT: entry: 766; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null 767; CHECK-NEXT: br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]] 768; CHECK: lor.lhs.false.i: 769; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1 770; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0 771; CHECK-NEXT: br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]] 772; CHECK: while.cond.i: 773; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ] 774; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 775; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1 776; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0 777; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 778; CHECK: while.end.i: 779; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]] 780; CHECK: _Z3fooPKc.exit: 781; CHECK-NEXT: [[TOBOOL:%.*]] = phi i1 [ true, [[WHILE_END_I]] ], [ false, [[LOR_LHS_FALSE_I]] ], [ false, [[ENTRY:%.*]] ] 782; CHECK-NEXT: ret i1 [[TOBOOL]] 783; 784entry: 785 %cmp.i = icmp eq ptr %str1, null 786 br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i 787 788lor.lhs.false.i: 789 %0 = load i8, ptr %str1, align 1 790 %cmp1.i = icmp eq i8 %0, 0 791 br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i 792 793while.cond.i: 794 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ] 795 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 796 %1 = load i8, ptr %test.0.i, align 1 797 %cmp3.not.i = icmp eq i8 %1, 0 798 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 799 800while.end.i: 801 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 802 %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64 803 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 804 br label %_Z3fooPKc.exit 805 806_Z3fooPKc.exit: 807 %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ] 808 %tobool = icmp ne i64 %retval.0.i, 0 809 ret i1 %tobool 810} 811 812define i1 @_gep_phi2(ptr %str1, i64 %val2) { 813; CHECK-LABEL: @_gep_phi2( 814; CHECK-NEXT: entry: 815; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null 816; CHECK-NEXT: br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]] 817; CHECK: lor.lhs.false.i: 818; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1 819; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0 820; CHECK-NEXT: br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]] 821; CHECK: while.cond.i: 822; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ] 823; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 824; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1 825; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0 826; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 827; CHECK: while.end.i: 828; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]] 829; CHECK: _Z3fooPKc.exit: 830; CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ 1, [[WHILE_END_I]] ], [ 0, [[LOR_LHS_FALSE_I]] ], [ 0, [[ENTRY:%.*]] ] 831; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[RETVAL_0_I]], [[VAL2:%.*]] 832; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[TMP2]], 0 833; CHECK-NEXT: ret i1 [[TOBOOL]] 834; 835entry: 836 %cmp.i = icmp eq ptr %str1, null 837 br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i 838 839lor.lhs.false.i: 840 %0 = load i8, ptr %str1, align 1 841 %cmp1.i = icmp eq i8 %0, 0 842 br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i 843 844while.cond.i: 845 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ] 846 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 847 %1 = load i8, ptr %test.0.i, align 1 848 %cmp3.not.i = icmp eq i8 %1, 0 849 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 850 851while.end.i: 852 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 853 %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64 854 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 855 br label %_Z3fooPKc.exit 856 857_Z3fooPKc.exit: 858 %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ] 859 %2 = or i64 %retval.0.i, %val2 860 %tobool = icmp eq i64 %2, 0 861 ret i1 %tobool 862} 863