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