1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='instcombine<no-verify-fixpoint>' -S < %s | FileCheck %s 3 4; In many of these tests nuw can be inferred on the sunk GEP in the exit 5; block. However, the condition is only converted into the necessary form 6; after it has been sunk and revisited already. 7 8target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64" 9 10define ptr@test1(ptr %A, i32 %Offset) { 11; CHECK-LABEL: @test1( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2 14; CHECK-NEXT: br label [[BB:%.*]] 15; CHECK: bb: 16; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 17; CHECK-NEXT: [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4 18; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400 19; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 20; CHECK: bb2: 21; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i32 [[RHS_IDX]] 22; CHECK-NEXT: ret ptr [[RHS_PTR]] 23; 24entry: 25 %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset 26 br label %bb 27 28bb: 29 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 30 %LHS = getelementptr inbounds i32, ptr %A, i32 100 31 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 32 %cond = icmp ult ptr %LHS, %RHS 33 br i1 %cond, label %bb2, label %bb 34 35bb2: 36 ret ptr %RHS 37} 38 39define ptr @test1_nuw(ptr %A, i32 %Offset) { 40; CHECK-LABEL: @test1_nuw( 41; CHECK-NEXT: entry: 42; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 2 43; CHECK-NEXT: br label [[BB:%.*]] 44; CHECK: bb: 45; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 46; CHECK-NEXT: [[RHS_ADD]] = add nuw nsw i32 [[RHS_IDX]], 4 47; CHECK-NEXT: [[COND:%.*]] = icmp samesign ugt i32 [[RHS_IDX]], 400 48; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 49; CHECK: bb2: 50; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[RHS_IDX]] 51; CHECK-NEXT: ret ptr [[RHS_PTR]] 52; 53entry: 54 %tmp = getelementptr inbounds nuw i32, ptr %A, i32 %Offset 55 br label %bb 56 57bb: 58 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 59 %LHS = getelementptr inbounds nuw i32, ptr %A, i32 100 60 %RHS.next = getelementptr inbounds nuw i32, ptr %RHS, i64 1 61 %cond = icmp ult ptr %LHS, %RHS 62 br i1 %cond, label %bb2, label %bb 63 64bb2: 65 ret ptr %RHS 66} 67 68define ptr @test1_not_all_nuw(ptr %A, i32 %Offset) { 69; CHECK-LABEL: @test1_not_all_nuw( 70; CHECK-NEXT: entry: 71; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2 72; CHECK-NEXT: br label [[BB:%.*]] 73; CHECK: bb: 74; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 75; CHECK-NEXT: [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4 76; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400 77; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 78; CHECK: bb2: 79; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i32 [[RHS_IDX]] 80; CHECK-NEXT: ret ptr [[RHS_PTR]] 81; 82entry: 83 %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset 84 br label %bb 85 86bb: 87 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 88 %LHS = getelementptr inbounds nuw i32, ptr %A, i32 100 89 %RHS.next = getelementptr inbounds nuw i32, ptr %RHS, i64 1 90 %cond = icmp ult ptr %LHS, %RHS 91 br i1 %cond, label %bb2, label %bb 92 93bb2: 94 ret ptr %RHS 95} 96 97define ptr@test2(i32 %A, i32 %Offset) { 98; CHECK-LABEL: @test2( 99; CHECK-NEXT: entry: 100; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2 101; CHECK-NEXT: br label [[BB:%.*]] 102; CHECK: bb: 103; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 104; CHECK-NEXT: [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4 105; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400 106; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 107; CHECK: bb2: 108; CHECK-NEXT: [[A_PTR:%.*]] = inttoptr i32 [[A:%.*]] to ptr 109; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A_PTR]], i32 [[RHS_IDX]] 110; CHECK-NEXT: ret ptr [[RHS_PTR]] 111; 112entry: 113 %A.ptr = inttoptr i32 %A to ptr 114 %tmp = getelementptr inbounds i32, ptr %A.ptr, i32 %Offset 115 br label %bb 116 117bb: 118 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 119 %LHS = getelementptr inbounds i32, ptr %A.ptr, i32 100 120 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 121 %cmp0 = ptrtoint ptr %LHS to i32 122 %cmp1 = ptrtoint ptr %RHS to i32 123 %cond = icmp ult i32 %cmp0, %cmp1 124 br i1 %cond, label %bb2, label %bb 125 126bb2: 127 ret ptr %RHS 128} 129 130; Perform the transformation only if we know that the GEPs used are inbounds. 131define ptr @test3_no_inbounds1(ptr %A, i32 %Offset) { 132; CHECK-LABEL: @test3_no_inbounds1( 133; CHECK-NEXT: entry: 134; CHECK-NEXT: [[TMP:%.*]] = getelementptr i32, ptr [[A:%.*]], i32 [[OFFSET:%.*]] 135; CHECK-NEXT: br label [[BB:%.*]] 136; CHECK: bb: 137; CHECK-NEXT: [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ] 138; CHECK-NEXT: [[LHS:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 400 139; CHECK-NEXT: [[RHS_NEXT]] = getelementptr inbounds nuw i8, ptr [[RHS]], i32 4 140; CHECK-NEXT: [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]] 141; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 142; CHECK: bb2: 143; CHECK-NEXT: ret ptr [[RHS]] 144; 145entry: 146 %tmp = getelementptr i32, ptr %A, i32 %Offset 147 br label %bb 148 149bb: 150 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 151 %LHS = getelementptr inbounds i32, ptr %A, i32 100 152 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 153 %cond = icmp ult ptr %LHS, %RHS 154 br i1 %cond, label %bb2, label %bb 155 156bb2: 157 ret ptr %RHS 158} 159 160define ptr @test3_no_inbounds2(ptr %A, i32 %Offset) { 161; CHECK-LABEL: @test3_no_inbounds2( 162; CHECK-NEXT: entry: 163; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[OFFSET:%.*]] 164; CHECK-NEXT: br label [[BB:%.*]] 165; CHECK: bb: 166; CHECK-NEXT: [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ] 167; CHECK-NEXT: [[LHS:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 400 168; CHECK-NEXT: [[RHS_NEXT]] = getelementptr i8, ptr [[RHS]], i32 4 169; CHECK-NEXT: [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]] 170; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 171; CHECK: bb2: 172; CHECK-NEXT: ret ptr [[RHS]] 173; 174entry: 175 %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset 176 br label %bb 177 178bb: 179 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 180 %LHS = getelementptr inbounds i32, ptr %A, i32 100 181 %RHS.next = getelementptr i32, ptr %RHS, i64 1 182 %cond = icmp ult ptr %LHS, %RHS 183 br i1 %cond, label %bb2, label %bb 184 185bb2: 186 ret ptr %RHS 187} 188 189define ptr @test3_no_inbounds3(ptr %A, i32 %Offset) { 190; CHECK-LABEL: @test3_no_inbounds3( 191; CHECK-NEXT: entry: 192; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[OFFSET:%.*]] 193; CHECK-NEXT: br label [[BB:%.*]] 194; CHECK: bb: 195; CHECK-NEXT: [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ] 196; CHECK-NEXT: [[LHS:%.*]] = getelementptr i8, ptr [[A]], i32 400 197; CHECK-NEXT: [[RHS_NEXT]] = getelementptr inbounds nuw i8, ptr [[RHS]], i32 4 198; CHECK-NEXT: [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]] 199; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 200; CHECK: bb2: 201; CHECK-NEXT: ret ptr [[RHS]] 202; 203entry: 204 %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset 205 br label %bb 206 207bb: 208 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 209 %LHS = getelementptr i32, ptr %A, i32 100 210 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 211 %cond = icmp ult ptr %LHS, %RHS 212 br i1 %cond, label %bb2, label %bb 213 214bb2: 215 ret ptr %RHS 216} 217 218; An inttoptr that requires an extension or truncation will be opaque when determining 219; the base pointer. In this case we can still perform the transformation by considering 220; A.ptr as being the base pointer. 221define ptr@test4(i16 %A, i32 %Offset) { 222; CHECK-LABEL: @test4( 223; CHECK-NEXT: entry: 224; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2 225; CHECK-NEXT: br label [[BB:%.*]] 226; CHECK: bb: 227; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 228; CHECK-NEXT: [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4 229; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400 230; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 231; CHECK: bb2: 232; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[A:%.*]] to i32 233; CHECK-NEXT: [[A_PTR:%.*]] = inttoptr i32 [[TMP0]] to ptr 234; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A_PTR]], i32 [[RHS_IDX]] 235; CHECK-NEXT: ret ptr [[RHS_PTR]] 236; 237entry: 238 %A.ptr = inttoptr i16 %A to ptr 239 %tmp = getelementptr inbounds i32, ptr %A.ptr, i32 %Offset 240 br label %bb 241 242bb: 243 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 244 %LHS = getelementptr inbounds i32, ptr %A.ptr, i32 100 245 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 246 %cmp0 = ptrtoint ptr %LHS to i32 247 %cmp1 = ptrtoint ptr %RHS to i32 248 %cond = icmp ult i32 %cmp0, %cmp1 249 br i1 %cond, label %bb2, label %bb 250 251bb2: 252 ret ptr %RHS 253} 254 255declare ptr @fun_ptr() 256 257define ptr@test5(i32 %Offset) personality ptr @__gxx_personality_v0 { 258; CHECK-LABEL: @test5( 259; CHECK-NEXT: entry: 260; CHECK-NEXT: [[A:%.*]] = invoke ptr @fun_ptr() 261; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD:%.*]] 262; CHECK: cont: 263; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2 264; CHECK-NEXT: br label [[BB:%.*]] 265; CHECK: bb: 266; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[CONT]] ] 267; CHECK-NEXT: [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4 268; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400 269; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 270; CHECK: bb2: 271; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A]], i32 [[RHS_IDX]] 272; CHECK-NEXT: ret ptr [[RHS_PTR]] 273; CHECK: lpad: 274; CHECK-NEXT: [[L:%.*]] = landingpad { ptr, i32 } 275; CHECK-NEXT: cleanup 276; CHECK-NEXT: ret ptr null 277; 278entry: 279 %A = invoke ptr@fun_ptr() to label %cont unwind label %lpad 280 281cont: 282 %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset 283 br label %bb 284 285bb: 286 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %cont ] 287 %LHS = getelementptr inbounds i32, ptr %A, i32 100 288 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 289 %cond = icmp ult ptr %LHS, %RHS 290 br i1 %cond, label %bb2, label %bb 291 292bb2: 293 ret ptr %RHS 294 295lpad: 296 %l = landingpad { ptr, i32 } cleanup 297 ret ptr null 298} 299 300declare i32 @fun_i32() 301 302define ptr@test6(i32 %Offset) personality ptr @__gxx_personality_v0 { 303; CHECK-LABEL: @test6( 304; CHECK-NEXT: entry: 305; CHECK-NEXT: [[A:%.*]] = invoke i32 @fun_i32() 306; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD:%.*]] 307; CHECK: cont: 308; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2 309; CHECK-NEXT: br label [[BB:%.*]] 310; CHECK: bb: 311; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[CONT]] ] 312; CHECK-NEXT: [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4 313; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400 314; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 315; CHECK: bb2: 316; CHECK-NEXT: [[A_PTR:%.*]] = inttoptr i32 [[A]] to ptr 317; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A_PTR]], i32 [[RHS_IDX]] 318; CHECK-NEXT: ret ptr [[RHS_PTR]] 319; CHECK: lpad: 320; CHECK-NEXT: [[L:%.*]] = landingpad { ptr, i32 } 321; CHECK-NEXT: cleanup 322; CHECK-NEXT: ret ptr null 323; 324entry: 325 %A = invoke i32 @fun_i32() to label %cont unwind label %lpad 326 327cont: 328 %A.ptr = inttoptr i32 %A to ptr 329 %tmp = getelementptr inbounds i32, ptr %A.ptr, i32 %Offset 330 br label %bb 331 332bb: 333 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %cont ] 334 %LHS = getelementptr inbounds i32, ptr %A.ptr, i32 100 335 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 336 %cond = icmp ult ptr %LHS, %RHS 337 br i1 %cond, label %bb2, label %bb 338 339bb2: 340 ret ptr %RHS 341 342lpad: 343 %l = landingpad { ptr, i32 } cleanup 344 ret ptr null 345} 346 347 348@pr30402 = constant i64 3 349define i1 @test7() { 350; CHECK-LABEL: @test7( 351; CHECK-NEXT: entry: 352; CHECK-NEXT: br label [[BB7:%.*]] 353; CHECK: bb7: 354; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[BB7]] ] 355; CHECK-NEXT: br i1 [[CMP]], label [[BB10:%.*]], label [[BB7]] 356; CHECK: bb10: 357; CHECK-NEXT: ret i1 true 358; 359entry: 360 br label %bb7 361 362bb7: ; preds = %bb10, %entry-block 363 %phi = phi ptr [ @pr30402, %entry ], [ getelementptr inbounds (i64, ptr @pr30402, i32 1), %bb7 ] 364 %cmp = icmp eq ptr %phi, getelementptr inbounds (i64, ptr @pr30402, i32 1) 365 br i1 %cmp, label %bb10, label %bb7 366 367bb10: 368 ret i1 %cmp 369} 370 371declare i32 @__gxx_personality_v0(...) 372 373define i1 @test8(ptr %in, i64 %offset) { 374; CHECK-LABEL: @test8( 375; CHECK-NEXT: entry: 376; CHECK-NEXT: [[LD:%.*]] = load i64, ptr [[IN:%.*]], align 8 377; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[LD]] to i32 378; CHECK-NEXT: [[CASTI8:%.*]] = inttoptr i32 [[TMP0]] to ptr 379; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[OFFSET:%.*]] to i32 380; CHECK-NEXT: [[GEPI8:%.*]] = getelementptr inbounds i8, ptr [[CASTI8]], i32 [[TMP1]] 381; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[LD]] to i32 382; CHECK-NEXT: [[PTRCAST:%.*]] = inttoptr i32 [[TMP2]] to ptr 383; CHECK-NEXT: [[GEPI32:%.*]] = getelementptr inbounds nuw i8, ptr [[PTRCAST]], i32 4 384; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEPI32]], [[GEPI8]] 385; CHECK-NEXT: ret i1 [[CMP]] 386; 387entry: 388 %ld = load i64, ptr %in, align 8 389 %casti8 = inttoptr i64 %ld to ptr 390 %gepi8 = getelementptr inbounds i8, ptr %casti8, i64 %offset 391 %ptrcast = inttoptr i64 %ld to ptr 392 %gepi32 = getelementptr inbounds ptr, ptr %ptrcast, i64 1 393 %cmp = icmp eq ptr %gepi32, %gepi8 394 ret i1 %cmp 395} 396 397define void @test_zero_offset_cycle(ptr %arg) { 398; CHECK-LABEL: @test_zero_offset_cycle( 399; CHECK-NEXT: entry: 400; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG:%.*]], i32 8 401; CHECK-NEXT: [[GEP_INT:%.*]] = ptrtoint ptr [[GEP]] to i32 402; CHECK-NEXT: br label [[LOOP:%.*]] 403; CHECK: loop: 404; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[GEP_INT]], [[ENTRY:%.*]] ], [ [[GEP_INT2:%.*]], [[LOOP_CONT:%.*]] ], [ [[PHI]], [[LOOP]] ] 405; CHECK-NEXT: [[PHI_PTR:%.*]] = inttoptr i32 [[PHI]] to ptr 406; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP]], [[PHI_PTR]] 407; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[LOOP_CONT]] 408; CHECK: loop.cont: 409; CHECK-NEXT: [[GEP_INT2]] = ptrtoint ptr [[GEP]] to i32 410; CHECK-NEXT: br label [[LOOP]] 411; 412entry: 413 %gep = getelementptr inbounds { i64, i64 }, ptr %arg, i32 0, i32 1 414 %gep.int = ptrtoint ptr %gep to i32 415 br label %loop 416 417loop: 418 %phi = phi i32 [ %gep.int, %entry ], [ %gep.int2, %loop.cont ], [ %phi, %loop ] 419 %phi.ptr = inttoptr i32 %phi to ptr 420 %cmp = icmp eq ptr %gep, %phi.ptr 421 br i1 %cmp, label %loop, label %loop.cont 422 423loop.cont: 424 %gep.int2 = ptrtoint ptr %gep to i32 425 br label %loop 426} 427