1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='require<domtree>,loop(loop-simplifycfg),gvn' -enable-split-backedge-in-load-pre -S %s | FileCheck %s 3 4define i32 @test_pointer_phi_select_same_object(ptr %ptr, ptr %end) { 5; CHECK-LABEL: @test_pointer_phi_select_same_object( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 8; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 9; CHECK-NEXT: br label [[LOOP:%.*]] 10; CHECK: loop: 11; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 12; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 13; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 14; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 15; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 16; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 17; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 18; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 19; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 20; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 21; CHECK: exit: 22; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 23; CHECK-NEXT: ret i32 [[RES]] 24; 25entry: 26 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 27 br label %loop 28 29loop: 30 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 31 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 32 %l.1 = load i32, ptr %ptr.iv, align 4 33 %l.2 = load i32, ptr %min.ptr, align 4 34 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 35 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 36 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 37 %ec = icmp eq ptr %ptr.iv.next, %end 38 br i1 %ec, label %exit, label %loop 39 40exit: 41 %res = load i32, ptr %min.select, align 4 42 ret i32 %res 43} 44 45define i32 @test_pointer_phi_select_same_object_lcssa(ptr %ptr, ptr %end) { 46; CHECK-LABEL: @test_pointer_phi_select_same_object_lcssa( 47; CHECK-NEXT: entry: 48; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 49; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 50; CHECK-NEXT: br label [[LOOP:%.*]] 51; CHECK: loop: 52; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 53; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 54; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 55; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 56; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 57; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 58; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 59; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 60; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 61; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 62; CHECK: exit: 63; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 64; CHECK-NEXT: ret i32 [[RES]] 65; 66entry: 67 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 68 br label %loop 69 70loop: 71 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 72 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 73 %l.1 = load i32, ptr %ptr.iv, align 4 74 %l.2 = load i32, ptr %min.ptr, align 4 75 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 76 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 77 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 78 %ec = icmp eq ptr %ptr.iv.next, %end 79 br i1 %ec, label %exit, label %loop 80 81exit: 82 %lcssa.min = phi ptr [ %min.select, %loop ] 83 %res = load i32, ptr %lcssa.min, align 4 84 ret i32 %res 85} 86 87define i32 @test_pointer_phi_select_different_objects(ptr %A, ptr %B, ptr %end) { 88; CHECK-LABEL: @test_pointer_phi_select_different_objects( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[B:%.*]], align 4 91; CHECK-NEXT: br label [[LOOP:%.*]] 92; CHECK: loop: 93; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 94; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 95; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 96; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 97; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 98; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 99; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 100; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 101; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 102; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 103; CHECK: exit: 104; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 105; CHECK-NEXT: ret i32 [[RES]] 106; 107entry: 108 br label %loop 109 110loop: 111 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ] 112 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ] 113 %l.1 = load i32, ptr %ptr.iv, align 4 114 %l.2 = load i32, ptr %min.ptr, align 4 115 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 116 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 117 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 118 %ec = icmp eq ptr %ptr.iv.next, %end 119 br i1 %ec, label %exit, label %loop 120 121exit: 122 %res = load i32, ptr %min.select, align 4 123 ret i32 %res 124} 125 126define i32 @test_pointer_phi_select_same_object_multiple_loads_1(ptr %ptr, ptr %end) { 127; CHECK-LABEL: @test_pointer_phi_select_same_object_multiple_loads_1( 128; CHECK-NEXT: entry: 129; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 130; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 131; CHECK-NEXT: br label [[LOOP:%.*]] 132; CHECK: loop: 133; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 134; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 135; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 136; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 137; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 138; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 139; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 140; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 141; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 142; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 143; CHECK: exit: 144; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 145; CHECK-NEXT: ret i32 [[RES]] 146; 147entry: 148 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 149 br label %loop 150 151loop: 152 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 153 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 154 %l.1 = load i32, ptr %ptr.iv, align 4 155 %l.2 = load i32, ptr %min.ptr, align 4 156 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 157 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 158 %l.3 = load i32, ptr %min.ptr, align 4 159 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 160 %ec = icmp eq ptr %ptr.iv.next, %end 161 br i1 %ec, label %exit, label %loop 162 163exit: 164 %res = load i32, ptr %min.select, align 4 165 ret i32 %res 166} 167 168define i32 @test_pointer_phi_select_same_object_multiple_loads_2(ptr %ptr, ptr %end) { 169; CHECK-LABEL: @test_pointer_phi_select_same_object_multiple_loads_2( 170; CHECK-NEXT: entry: 171; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 172; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 173; CHECK-NEXT: br label [[LOOP:%.*]] 174; CHECK: loop: 175; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 176; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 177; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 178; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 179; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 180; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 181; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 182; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 183; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 184; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 185; CHECK: exit: 186; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 187; CHECK-NEXT: ret i32 [[RES]] 188; 189entry: 190 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 191 br label %loop 192 193loop: 194 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 195 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 196 %l.1 = load i32, ptr %ptr.iv, align 4 197 %l.2 = load i32, ptr %min.ptr, align 4 198 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 199 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 200 %l.3 = load i32, ptr %ptr.iv, align 4 201 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 202 %ec = icmp eq ptr %ptr.iv.next, %end 203 br i1 %ec, label %exit, label %loop 204 205exit: 206 %res = load i32, ptr %min.select, align 4 207 ret i32 %res 208} 209 210define i32 @test_pointer_phi_select_load_after(ptr %A, ptr %B, ptr %end) { 211; CHECK-LABEL: @test_pointer_phi_select_load_after( 212; CHECK-NEXT: entry: 213; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[B:%.*]], align 4 214; CHECK-NEXT: br label [[LOOP:%.*]] 215; CHECK: loop: 216; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[L_3:%.*]], [[LOOP]] ] 217; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 218; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 219; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 220; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 221; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 222; CHECK-NEXT: [[L_3]] = load i32, ptr [[MIN_SELECT]], align 4 223; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]] 224; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 225; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 226; CHECK: exit: 227; CHECK-NEXT: ret i32 [[L_3]] 228; 229entry: 230 br label %loop 231 232loop: 233 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ] 234 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ] 235 %l.1 = load i32, ptr %ptr.iv, align 4 236 %l.2 = load i32, ptr %min.ptr, align 4 237 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 238 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 239 %l.3 = load i32, ptr %min.select, align 4 240 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3 241 %ec = icmp eq ptr %ptr.iv.next, %end 242 br i1 %ec, label %exit, label %loop 243 244exit: 245 %res = load i32, ptr %min.select, align 4 246 ret i32 %res 247} 248 249define i32 @test_pointer_phi_select_same_object_split_edge(ptr %ptr, ptr %end, i1 %c) { 250; CHECK-LABEL: @test_pointer_phi_select_same_object_split_edge( 251; CHECK-NEXT: entry: 252; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 253; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 254; CHECK: loop.preheader: 255; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 256; CHECK-NEXT: br label [[LOOP:%.*]] 257; CHECK: loop: 258; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[TMP0:%.*]], [[LOOP]] ], [ [[L_2_PRE]], [[LOOP_PREHEADER]] ] 259; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ], [ [[START_PTR]], [[LOOP_PREHEADER]] ] 260; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[MIN_SELECT:%.*]], [[LOOP]] ], [ [[PTR]], [[LOOP_PREHEADER]] ] 261; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 262; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 263; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 264; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 265; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 266; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 267; CHECK-NEXT: br i1 [[EC]], label [[LOOP_EXIT:%.*]], label [[LOOP]] 268; CHECK: loop.exit: 269; CHECK-NEXT: br label [[EXIT]] 270; CHECK: exit: 271; CHECK-NEXT: [[LCSSA_PHI_2:%.*]] = phi ptr [ [[END]], [[ENTRY:%.*]] ], [ [[MIN_SELECT]], [[LOOP_EXIT]] ] 272; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[LCSSA_PHI_2]], align 4 273; CHECK-NEXT: ret i32 [[RES]] 274; 275entry: 276 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 277 br i1 %c, label %exit, label %loop 278 279loop: 280 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 281 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 282 %l.1 = load i32, ptr %ptr.iv, align 4 283 %l.2 = load i32, ptr %min.ptr, align 4 284 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 285 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 286 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 287 %ec = icmp eq ptr %ptr.iv.next, %end 288 br i1 %ec, label %loop.exit, label %loop 289 290loop.exit: 291 %lcssa.phi.1 = phi ptr [ %min.select, %loop ] 292 br label %exit 293 294exit: 295 %lcssa.phi.2 = phi ptr [ %end, %entry ], [ %lcssa.phi.1, %loop.exit ] 296 %res = load i32, ptr %lcssa.phi.2, align 4 297 ret i32 %res 298} 299 300 301declare void @may_throw() readonly 302 303define i32 @test_pointer_phi_select_load_may_not_execute_1(ptr %A, ptr %B, ptr %end) { 304; CHECK-LABEL: @test_pointer_phi_select_load_may_not_execute_1( 305; CHECK-NEXT: entry: 306; CHECK-NEXT: br label [[LOOP:%.*]] 307; CHECK: loop: 308; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 309; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B:%.*]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 310; CHECK-NEXT: call void @may_throw() 311; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 312; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 313; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 314; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 315; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 316; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 317; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 318; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 319; CHECK: exit: 320; CHECK-NEXT: ret i32 [[TMP0]] 321; 322entry: 323 br label %loop 324 325loop: 326 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ] 327 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ] 328 call void @may_throw() 329 %l.1 = load i32, ptr %ptr.iv, align 4 330 %l.2 = load i32, ptr %min.ptr, align 4 331 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 332 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 333 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 334 %ec = icmp eq ptr %ptr.iv.next, %end 335 br i1 %ec, label %exit, label %loop 336 337exit: 338 %res = load i32, ptr %min.select, align 4 339 ret i32 %res 340} 341 342define i32 @test_pointer_phi_select_load_may_not_execute_2(ptr %A, ptr %B, ptr %end) { 343; CHECK-LABEL: @test_pointer_phi_select_load_may_not_execute_2( 344; CHECK-NEXT: entry: 345; CHECK-NEXT: br label [[LOOP:%.*]] 346; CHECK: loop: 347; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 348; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B:%.*]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 349; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 350; CHECK-NEXT: call void @may_throw() 351; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 352; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 353; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 354; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 355; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 356; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 357; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 358; CHECK: exit: 359; CHECK-NEXT: ret i32 [[TMP0]] 360; 361entry: 362 br label %loop 363 364loop: 365 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ] 366 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ] 367 %l.1 = load i32, ptr %ptr.iv, align 4 368 call void @may_throw() 369 %l.2 = load i32, ptr %min.ptr, align 4 370 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 371 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 372 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 373 %ec = icmp eq ptr %ptr.iv.next, %end 374 br i1 %ec, label %exit, label %loop 375 376exit: 377 %res = load i32, ptr %min.select, align 4 378 ret i32 %res 379} 380 381define i32 @test_pointer_phi_select_same_object_store_1(ptr %ptr, ptr %end) { 382; CHECK-LABEL: @test_pointer_phi_select_same_object_store_1( 383; CHECK-NEXT: entry: 384; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 385; CHECK-NEXT: br label [[LOOP:%.*]] 386; CHECK: loop: 387; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 388; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 389; CHECK-NEXT: store i32 3, ptr [[MIN_PTR]], align 4 390; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 391; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], 3 392; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 393; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 394; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 395; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 396; CHECK: exit: 397; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 398; CHECK-NEXT: ret i32 [[RES]] 399; 400entry: 401 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 402 br label %loop 403 404loop: 405 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 406 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 407 store i32 3, ptr %min.ptr 408 %l.1 = load i32, ptr %ptr.iv, align 4 409 %l.2 = load i32, ptr %min.ptr, align 4 410 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 411 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 412 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 413 %ec = icmp eq ptr %ptr.iv.next, %end 414 br i1 %ec, label %exit, label %loop 415 416exit: 417 %res = load i32, ptr %min.select, align 4 418 ret i32 %res 419} 420 421define i32 @test_pointer_phi_select_same_object_store_2(ptr %ptr, ptr %end) { 422; CHECK-LABEL: @test_pointer_phi_select_same_object_store_2( 423; CHECK-NEXT: entry: 424; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 425; CHECK-NEXT: br label [[LOOP:%.*]] 426; CHECK: loop: 427; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 428; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 429; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 430; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 431; CHECK-NEXT: store i32 3, ptr [[MIN_PTR]], align 4 432; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 433; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 434; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 435; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 436; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 437; CHECK: exit: 438; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 439; CHECK-NEXT: ret i32 [[RES]] 440; 441entry: 442 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 443 br label %loop 444 445loop: 446 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 447 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 448 %l.1 = load i32, ptr %ptr.iv, align 4 449 %l.2 = load i32, ptr %min.ptr, align 4 450 store i32 3, ptr %min.ptr 451 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 452 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 453 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 454 %ec = icmp eq ptr %ptr.iv.next, %end 455 br i1 %ec, label %exit, label %loop 456 457exit: 458 %res = load i32, ptr %min.select, align 4 459 ret i32 %res 460} 461 462define i32 @test_pointer_phi_select_same_object_store_3(ptr %ptr, ptr %end) { 463; CHECK-LABEL: @test_pointer_phi_select_same_object_store_3( 464; CHECK-NEXT: entry: 465; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 466; CHECK-NEXT: br label [[LOOP:%.*]] 467; CHECK: loop: 468; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 469; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 470; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 471; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 472; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 473; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 474; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 475; CHECK-NEXT: store i32 3, ptr [[MIN_PTR]], align 4 476; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 477; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 478; CHECK: exit: 479; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 480; CHECK-NEXT: ret i32 [[RES]] 481; 482entry: 483 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 484 br label %loop 485 486loop: 487 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 488 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 489 %l.1 = load i32, ptr %ptr.iv, align 4 490 %l.2 = load i32, ptr %min.ptr, align 4 491 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 492 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 493 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 494 store i32 3, ptr %min.ptr 495 %ec = icmp eq ptr %ptr.iv.next, %end 496 br i1 %ec, label %exit, label %loop 497 498exit: 499 %res = load i32, ptr %min.select, align 4 500 ret i32 %res 501} 502 503declare void @may_write() 504 505define i32 @test_pointer_phi_select_same_object_may_write_call_1(ptr %ptr, ptr %end) { 506; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_1( 507; CHECK-NEXT: entry: 508; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 509; CHECK-NEXT: br label [[LOOP:%.*]] 510; CHECK: loop: 511; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 512; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 513; CHECK-NEXT: call void @may_write() 514; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 515; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 516; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 517; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 518; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 519; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 520; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 521; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 522; CHECK: exit: 523; CHECK-NEXT: ret i32 [[TMP0]] 524; 525entry: 526 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 527 br label %loop 528 529loop: 530 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 531 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 532 call void @may_write() 533 %l.1 = load i32, ptr %ptr.iv, align 4 534 %l.2 = load i32, ptr %min.ptr, align 4 535 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 536 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 537 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 538 %ec = icmp eq ptr %ptr.iv.next, %end 539 br i1 %ec, label %exit, label %loop 540 541exit: 542 %res = load i32, ptr %min.select, align 4 543 ret i32 %res 544} 545 546define i32 @test_pointer_phi_select_same_object_may_write_call_2(ptr %ptr, ptr %end) { 547; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_2( 548; CHECK-NEXT: entry: 549; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 550; CHECK-NEXT: br label [[LOOP:%.*]] 551; CHECK: loop: 552; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 553; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 554; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 555; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 556; CHECK-NEXT: call void @may_write() 557; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 558; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 559; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 560; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 561; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 562; CHECK: exit: 563; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 564; CHECK-NEXT: ret i32 [[RES]] 565; 566entry: 567 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 568 br label %loop 569 570loop: 571 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 572 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 573 %l.1 = load i32, ptr %ptr.iv, align 4 574 %l.2 = load i32, ptr %min.ptr, align 4 575 call void @may_write() 576 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 577 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 578 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 579 %ec = icmp eq ptr %ptr.iv.next, %end 580 br i1 %ec, label %exit, label %loop 581 582exit: 583 %res = load i32, ptr %min.select, align 4 584 ret i32 %res 585} 586 587define i32 @test_pointer_phi_select_same_object_may_write_call_3(ptr %ptr, ptr %end) { 588; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_3( 589; CHECK-NEXT: entry: 590; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 591; CHECK-NEXT: br label [[LOOP:%.*]] 592; CHECK: loop: 593; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 594; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 595; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 596; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 597; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 598; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 599; CHECK-NEXT: call void @may_write() 600; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 601; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 602; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 603; CHECK: exit: 604; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 605; CHECK-NEXT: ret i32 [[RES]] 606; 607entry: 608 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 609 br label %loop 610 611loop: 612 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 613 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 614 %l.1 = load i32, ptr %ptr.iv, align 4 615 %l.2 = load i32, ptr %min.ptr, align 4 616 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 617 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 618 call void @may_write() 619 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 620 %ec = icmp eq ptr %ptr.iv.next, %end 621 br i1 %ec, label %exit, label %loop 622 623exit: 624 %res = load i32, ptr %min.select, align 4 625 ret i32 %res 626} 627 628define i32 @test_pointer_phi_select_same_object_header_exit(ptr %ptr, ptr %end) { 629; CHECK-LABEL: @test_pointer_phi_select_same_object_header_exit( 630; CHECK-NEXT: entry: 631; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 632; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 633; CHECK: loop.header: 634; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 635; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP_LATCH]] ] 636; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 637; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 638; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LATCH]] 639; CHECK: loop.latch: 640; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 641; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 642; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 643; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 644; CHECK-NEXT: br label [[LOOP_HEADER]] 645; CHECK: exit: 646; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_PTR]], align 4 647; CHECK-NEXT: ret i32 [[RES]] 648; 649entry: 650 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 651 br label %loop.header 652 653loop.header: 654 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop.latch ] 655 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop.latch ] 656 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 657 %ec = icmp eq ptr %ptr.iv.next, %end 658 br i1 %ec, label %exit, label %loop.latch 659 660loop.latch: 661 %l.1 = load i32, ptr %ptr.iv, align 4 662 %l.2 = load i32, ptr %min.ptr, align 4 663 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 664 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 665 br label %loop.header 666 667exit: 668 %res = load i32, ptr %min.ptr, align 4 669 ret i32 %res 670} 671 672define i32 @test_pointer_phi_select_same_object_ptr_use_cycle(ptr %ptr, ptr %end) { 673; CHECK-LABEL: @test_pointer_phi_select_same_object_ptr_use_cycle( 674; CHECK-NEXT: entry: 675; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 676; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 677; CHECK-NEXT: br label [[LOOP:%.*]] 678; CHECK: loop: 679; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 680; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 681; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 682; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 683; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 684; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 685; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 686; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 687; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 688; CHECK-NEXT: br i1 [[EC]], label [[EXIT_PREHEADER:%.*]], label [[LOOP]] 689; CHECK: exit.preheader: 690; CHECK-NEXT: br label [[EXIT:%.*]] 691; CHECK: exit: 692; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_NEXT:%.*]], [[EXIT]] ], [ [[MIN_SELECT]], [[EXIT_PREHEADER]] ] 693; CHECK-NEXT: store i32 0, ptr [[P]], align 4 694; CHECK-NEXT: [[P_NEXT]] = getelementptr inbounds i32, ptr [[P]], i64 1 695; CHECK-NEXT: br label [[EXIT]] 696; 697entry: 698 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 699 br label %loop 700 701loop: 702 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 703 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 704 %l.1 = load i32, ptr %ptr.iv, align 4 705 %l.2 = load i32, ptr %min.ptr, align 4 706 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 707 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 708 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 709 %ec = icmp eq ptr %ptr.iv.next, %end 710 br i1 %ec, label %exit, label %loop 711 712exit: 713 %p = phi ptr [ %min.select, %loop ], [ %p.next, %exit ] 714 store i32 0, ptr %p 715 %p.next = getelementptr inbounds i32, ptr %p, i64 1 716 br label %exit 717} 718 719define i32 @test_pointer_phi_select_same_object_maybe_clobbered_in_exit(ptr %ptr, ptr %end) { 720; CHECK-LABEL: @test_pointer_phi_select_same_object_maybe_clobbered_in_exit( 721; CHECK-NEXT: entry: 722; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 723; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 724; CHECK-NEXT: br label [[LOOP:%.*]] 725; CHECK: loop: 726; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 727; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 728; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 729; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 730; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 731; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 732; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 733; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 734; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 735; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 736; CHECK: exit: 737; CHECK-NEXT: store i32 0, ptr [[START_PTR]], align 4 738; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 739; CHECK-NEXT: ret i32 [[RES]] 740; 741entry: 742 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 743 br label %loop 744 745loop: 746 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 747 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 748 %l.1 = load i32, ptr %ptr.iv, align 4 749 %l.2 = load i32, ptr %min.ptr, align 4 750 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 751 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 752 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 753 %ec = icmp eq ptr %ptr.iv.next, %end 754 br i1 %ec, label %exit, label %loop 755 756exit: 757 store i32 0, ptr %start.ptr 758 %res = load i32, ptr %min.select, align 4 759 ret i32 %res 760} 761 762define i32 @test_pointer_phi_select_same_object_maybe_clobbered_in_exit_2(ptr %ptr, ptr %end) { 763; CHECK-LABEL: @test_pointer_phi_select_same_object_maybe_clobbered_in_exit_2( 764; CHECK-NEXT: entry: 765; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 766; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 767; CHECK-NEXT: br label [[LOOP:%.*]] 768; CHECK: loop: 769; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 770; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 771; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 772; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 773; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 774; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 775; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 776; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 777; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 778; CHECK-NEXT: br i1 [[EC]], label [[EXIT_1:%.*]], label [[LOOP]] 779; CHECK: exit.1: 780; CHECK-NEXT: store i32 0, ptr [[START_PTR]], align 4 781; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 782; CHECK-NEXT: ret i32 [[RES]] 783; 784entry: 785 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 786 br label %loop 787 788loop: 789 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 790 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 791 %l.1 = load i32, ptr %ptr.iv, align 4 792 %l.2 = load i32, ptr %min.ptr, align 4 793 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 794 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 795 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 796 %ec = icmp eq ptr %ptr.iv.next, %end 797 br i1 %ec, label %exit.1, label %loop 798 799exit.1: 800 %lcssa.min = phi ptr [ %min.select, %loop ] 801 store i32 0, ptr %start.ptr 802 br label %exit.2 803 804exit.2: 805 %res = load i32, ptr %lcssa.min, align 4 806 ret i32 %res 807} 808 809declare i32 @__CxxFrameHandler3(...) 810 811define i32 @test_pointer_phi_select_same_object_invoke_in_chain(ptr %ptr, ptr %end) personality ptr @__CxxFrameHandler3 { 812; CHECK-LABEL: @test_pointer_phi_select_same_object_invoke_in_chain( 813; CHECK-NEXT: entry: 814; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 815; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 816; CHECK-NEXT: br label [[LOOP:%.*]] 817; CHECK: loop: 818; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 819; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 820; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 821; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 822; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 823; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 824; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 825; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 826; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 827; CHECK-NEXT: br i1 [[EC]], label [[EXIT_1:%.*]], label [[LOOP]] 828; CHECK: exit.1: 829; CHECK-NEXT: store i32 0, ptr [[START_PTR]], align 4 830; CHECK-NEXT: invoke void @may_throw() 831; CHECK-NEXT: to label [[EXIT_2:%.*]] unwind label [[CATCH_OBJECT:%.*]] 832; CHECK: exit.2: 833; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 834; CHECK-NEXT: ret i32 [[RES]] 835; CHECK: catch.object: 836; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 } 837; CHECK-NEXT: catch ptr null 838; CHECK-NEXT: unreachable 839; 840entry: 841 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 842 br label %loop 843 844loop: 845 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 846 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 847 %l.1 = load i32, ptr %ptr.iv, align 4 848 %l.2 = load i32, ptr %min.ptr, align 4 849 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 850 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 851 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 852 %ec = icmp eq ptr %ptr.iv.next, %end 853 br i1 %ec, label %exit.1, label %loop 854 855exit.1: 856 %lcssa.min = phi ptr [ %min.select, %loop ] 857 store i32 0, ptr %start.ptr 858 invoke void @may_throw() 859 to label %exit.2 unwind label %catch.object 860 861exit.2: 862 %res = load i32, ptr %lcssa.min, align 4 863 ret i32 %res 864 865catch.object: 866 %lp = landingpad { ptr, i32 } 867 catch ptr null 868 unreachable 869} 870 871define i32 @test_pointer_phi_select_used_by_others_in_loop(ptr %ptr, ptr %end) { 872; CHECK-LABEL: @test_pointer_phi_select_used_by_others_in_loop( 873; CHECK-NEXT: entry: 874; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 875; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 876; CHECK-NEXT: br label [[LOOP:%.*]] 877; CHECK: loop: 878; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[L_3:%.*]], [[LOOP]] ] 879; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 880; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 881; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 882; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 883; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 884; CHECK-NEXT: [[L_3]] = load i32, ptr [[MIN_SELECT]], align 4 885; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]] 886; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 887; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 888; CHECK: exit: 889; CHECK-NEXT: ret i32 [[L_3]] 890; 891entry: 892 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 893 br label %loop 894 895loop: 896 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 897 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 898 %l.1 = load i32, ptr %ptr.iv, align 4 899 %l.2 = load i32, ptr %min.ptr, align 4 900 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 901 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 902 %l.3 = load i32, ptr %min.select, align 4 903 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3 904 %ec = icmp eq ptr %ptr.iv.next, %end 905 br i1 %ec, label %exit, label %loop 906 907exit: 908 %res = load i32, ptr %min.select, align 4 909 ret i32 %res 910} 911 912define i32 @test_pointer_phi_used_by_others_in_loop_1(ptr %ptr, ptr %end) { 913; CHECK-LABEL: @test_pointer_phi_used_by_others_in_loop_1( 914; CHECK-NEXT: entry: 915; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 916; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 917; CHECK-NEXT: br label [[LOOP:%.*]] 918; CHECK: loop: 919; CHECK-NEXT: [[L_3:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[L_3_PRE:%.*]], [[LOOP_LOOP_CRIT_EDGE:%.*]] ] 920; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY]] ], [ [[TMP0:%.*]], [[LOOP_LOOP_CRIT_EDGE]] ] 921; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LOOP_CRIT_EDGE]] ] 922; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP_LOOP_CRIT_EDGE]] ] 923; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 924; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 925; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 926; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 927; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]] 928; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 929; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LOOP_CRIT_EDGE]] 930; CHECK: loop.loop_crit_edge: 931; CHECK-NEXT: [[L_3_PRE]] = load i32, ptr [[MIN_SELECT]], align 4 932; CHECK-NEXT: br label [[LOOP]] 933; CHECK: exit: 934; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 935; CHECK-NEXT: ret i32 [[RES]] 936; 937entry: 938 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 939 br label %loop 940 941loop: 942 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 943 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 944 %l.1 = load i32, ptr %ptr.iv, align 4 945 %l.2 = load i32, ptr %min.ptr, align 4 946 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 947 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 948 %l.3 = load i32, ptr %min.ptr, align 4 949 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3 950 %ec = icmp eq ptr %ptr.iv.next, %end 951 br i1 %ec, label %exit, label %loop 952 953exit: 954 %res = load i32, ptr %min.select, align 4 955 ret i32 %res 956} 957 958define i32 @test_pointer_phi_used_by_others_in_loop_2(ptr %ptr, ptr %end) { 959; CHECK-LABEL: @test_pointer_phi_used_by_others_in_loop_2( 960; CHECK-NEXT: entry: 961; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 962; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4 963; CHECK-NEXT: br label [[LOOP:%.*]] 964; CHECK: loop: 965; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ] 966; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 967; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 968; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4 969; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 970; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 971; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 972; CHECK-NEXT: [[GEP_MIN_PTR:%.*]] = getelementptr inbounds i32, ptr [[MIN_PTR]], i32 1 973; CHECK-NEXT: [[L_3:%.*]] = load i32, ptr [[GEP_MIN_PTR]], align 4 974; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]] 975; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 976; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 977; CHECK: exit: 978; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 979; CHECK-NEXT: ret i32 [[RES]] 980; 981entry: 982 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 983 br label %loop 984 985loop: 986 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 987 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 988 %l.1 = load i32, ptr %ptr.iv, align 4 989 %l.2 = load i32, ptr %min.ptr, align 4 990 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 991 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 992 %gep.min.ptr = getelementptr inbounds i32, ptr %min.ptr, i32 1 993 %l.3 = load i32, ptr %gep.min.ptr, align 4 994 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3 995 %ec = icmp eq ptr %ptr.iv.next, %end 996 br i1 %ec, label %exit, label %loop 997 998exit: 999 %res = load i32, ptr %min.select, align 4 1000 ret i32 %res 1001} 1002 1003define i32 @test_pointer_phi_select_no_iter_load(ptr %ptr, ptr %end) { 1004; CHECK-LABEL: @test_pointer_phi_select_no_iter_load( 1005; CHECK-NEXT: entry: 1006; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 1007; CHECK-NEXT: br label [[LOOP:%.*]] 1008; CHECK: loop: 1009; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ] 1010; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ] 1011; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4 1012; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 10, [[L_2]] 1013; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]] 1014; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1 1015; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]] 1016; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 1017; CHECK: exit: 1018; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 1019; CHECK-NEXT: ret i32 [[RES]] 1020; 1021entry: 1022 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1 1023 br label %loop 1024 1025loop: 1026 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ] 1027 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ] 1028 %l.2 = load i32, ptr %min.ptr, align 4 1029 %cmp.i.i.i = icmp ult i32 10, %l.2 1030 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr 1031 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1 1032 %ec = icmp eq ptr %ptr.iv.next, %end 1033 br i1 %ec, label %exit, label %loop 1034 1035exit: 1036 %res = load i32, ptr %min.select, align 4 1037 ret i32 %res 1038} 1039