945 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='gvn' -S %s | FileCheck %s3 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 18; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 49; 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 415; 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 119; 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 423; CHECK-NEXT: ret i32 [[RES]]24;25entry:26 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 127 %l.2.pre = load i32, ptr %ptr, align 428 br label %loop29 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 435 %cmp.1 = icmp ult i32 %l.1, %l.236 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.237 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr38 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 139 %ec = icmp eq ptr %ptr.iv.next, %end40 br i1 %ec, label %exit, label %loop41 42exit:43 %res = load i32, ptr %min.select, align 444 ret i32 %res45}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 151; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 452; 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 458; 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 162; 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 466; CHECK-NEXT: ret i32 [[RES]]67;68entry:69 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 170 %l.2.pre = load i32, ptr %ptr, align 471 br label %loop72 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 478 %cmp.1 = icmp ult i32 %l.1, %l.279 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.280 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr81 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 182 %ec = icmp eq ptr %ptr.iv.next, %end83 br i1 %ec, label %exit, label %loop84 85exit:86 %res = load i32, ptr %min.select, align 487 ret i32 %res88}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 194; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 495; 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 4101; 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 1105; 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 4109; CHECK-NEXT: ret i32 [[RES]]110;111entry:112 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1113 %l.2.pre = load i32, ptr %ptr, align 4114 br label %loop115 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 4121 %cmp.1 = icmp ult i32 %l.1, %l.2122 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2123 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr124 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1125 %ec = icmp eq ptr %ptr.iv.next, %end126 br i1 %ec, label %exit, label %loop127 128exit:129 %res = load i32, ptr %min.select, align 4130 ret i32 %res131}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 1137; 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 4143; 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 1147; 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 4151; CHECK-NEXT: ret i32 [[RES]]152;153entry:154 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1155 br label %loop156 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 4162 %cmp.1 = icmp ult i32 %l.1, %l.2163 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2164 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr165 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1166 %ec = icmp eq ptr %ptr.iv.next, %end167 br i1 %ec, label %exit, label %loop168 169exit:170 %res = load i32, ptr %min.select, align 4171 ret i32 %res172}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 1178; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4179; 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 4185; 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 1189; 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 4193; CHECK-NEXT: ret i32 [[RES]]194;195entry:196 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1197 %l.2.pre = load i32, ptr %ptr, align 4198 br label %loop199 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 4205 %cmp.1 = icmp ult i32 %l.1, %l.2206 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2207 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr208 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1209 %ec = icmp eq ptr %ptr.iv.next, %end210 br i1 %ec, label %exit, label %loop211 212exit:213 %res = load i32, ptr %min.select, align 4214 ret i32 %res215}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 1221; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4222; 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 4230; 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 1234; 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 4238; CHECK-NEXT: ret i32 [[RES]]239; CHECK: exit.2:240; CHECK-NEXT: ret i32 0241;242entry:243 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1244 %l.2.pre = load i32, ptr %ptr, align 4245 br i1 %c, label %ph, label %exit.2246 247ph:248 br label %loop249 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 4255 %cmp.1 = icmp ult i32 %l.1, %l.2256 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2257 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr258 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1259 %ec = icmp eq ptr %ptr.iv.next, %end260 br i1 %ec, label %exit, label %loop261 262exit:263 %res = load i32, ptr %min.select, align 4264 ret i32 %res265 266exit.2:267 ret i32 0268}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 1274; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4275; 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 4281; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]282; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[L_1]], 10283; 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 1286; 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 4290; CHECK-NEXT: ret i32 [[RES]]291;292entry:293 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1294 %l.2.pre = load i32, ptr %ptr, align 4295 br label %loop296 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 4302 %cmp.1 = icmp ult i32 %l.1, %l.2303 %cmp.2 = icmp ult i32 %l.1, 10304 %min.val = select i1 %cmp.2, i32 %l.1, i32 %l.2305 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr306 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1307 %ec = icmp eq ptr %ptr.iv.next, %end308 br i1 %ec, label %exit, label %loop309 310exit:311 %res = load i32, ptr %min.select, align 4312 ret i32 %res313}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 1320; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4321; 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 4327; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]328; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 10329; 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 1331; 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 4335; CHECK-NEXT: ret i32 [[RES]]336;337entry:338 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1339 %l.2.pre = load i32, ptr %ptr, align 4340 br label %loop341 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 4347 %cmp.1 = icmp ult i32 %l.1, %l.2348 %min.val = select i1 %cmp.1, i32 %l.1, i32 10349 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr350 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1351 %ec = icmp eq ptr %ptr.iv.next, %end352 br i1 %ec, label %exit, label %loop353 354exit:355 %res = load i32, ptr %min.select, align 4356 ret i32 %res357}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 1363; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4364; CHECK-NEXT: [[L_1_PRE:%.*]] = load i32, ptr [[PTR_2:%.*]], align 4365; 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 1374; 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 4378; CHECK-NEXT: ret i32 [[RES]]379;380entry:381 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1382 %l.2.pre = load i32, ptr %ptr, align 4383 br label %loop384 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 4390 %cmp.1 = icmp ult i32 %l.1, %l.2391 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2392 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr393 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1394 %ec = icmp eq ptr %ptr.iv.next, %end395 br i1 %ec, label %exit, label %loop396 397exit:398 %res = load i32, ptr %min.select, align 4399 ret i32 %res400}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 1406; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4407; CHECK-NEXT: store i32 99, ptr [[PTR]], align 4408; 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 4414; 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 1418; 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 4422; CHECK-NEXT: ret i32 [[RES]]423;424entry:425 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1426 %l.2.pre = load i32, ptr %ptr, align 4427 store i32 99, ptr %ptr428 br label %loop429 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 4435 %cmp.1 = icmp ult i32 %l.1, %l.2436 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2437 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr438 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1439 %ec = icmp eq ptr %ptr.iv.next, %end440 br i1 %ec, label %exit, label %loop441 442exit:443 %res = load i32, ptr %min.select, align 4444 ret i32 %res445}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 1451; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4452; 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 4458; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4459; 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 1463; 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 4467; CHECK-NEXT: ret i32 [[RES]]468;469entry:470 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1471 %l.2.pre = load i32, ptr %ptr, align 4472 br label %loop473 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 %ptr479 %l.1 = load i32, ptr %ptr.iv, align 4480 %cmp.1 = icmp ult i32 %l.1, %l.2481 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2482 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr483 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1484 %ec = icmp eq ptr %ptr.iv.next, %end485 br i1 %ec, label %exit, label %loop486 487exit:488 %res = load i32, ptr %min.select, align 4489 ret i32 %res490}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 1496; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4497; 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 4503; CHECK-NEXT: store i32 99, ptr [[PTR]], align 4504; 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 1508; 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 4512; CHECK-NEXT: ret i32 [[RES]]513;514entry:515 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1516 %l.2.pre = load i32, ptr %ptr, align 4517 br label %loop518 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 4524 store i32 99, ptr %ptr525 %cmp.1 = icmp ult i32 %l.1, %l.2526 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2527 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr528 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1529 %ec = icmp eq ptr %ptr.iv.next, %end530 br i1 %ec, label %exit, label %loop531 532exit:533 %res = load i32, ptr %min.select, align 4534 ret i32 %res535}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 1541; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4542; 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 4548; CHECK-NEXT: store i32 99, ptr [[PTR_IV]], align 4549; 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 1553; 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 4557; CHECK-NEXT: ret i32 [[RES]]558;559entry:560 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1561 %l.2.pre = load i32, ptr %ptr, align 4562 br label %loop563 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 4569 store i32 99, ptr %ptr.iv570 %cmp.1 = icmp ult i32 %l.1, %l.2571 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2572 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr573 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1574 %ec = icmp eq ptr %ptr.iv.next, %end575 br i1 %ec, label %exit, label %loop576 577exit:578 %res = load i32, ptr %min.select, align 4579 ret i32 %res580}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 1586; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4587; 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 4593; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4594; 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 1598; 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 4602; CHECK-NEXT: ret i32 [[RES]]603;604entry:605 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1606 %l.2.pre = load i32, ptr %ptr, align 4607 br label %loop608 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.2614 %l.1 = load i32, ptr %ptr.iv, align 4615 %cmp.1 = icmp ult i32 %l.1, %l.2616 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2617 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr618 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1619 %ec = icmp eq ptr %ptr.iv.next, %end620 br i1 %ec, label %exit, label %loop621 622exit:623 %res = load i32, ptr %min.select, align 4624 ret i32 %res625}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 1633; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4634; 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 4641; 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 1645; 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 4649; CHECK-NEXT: ret i32 [[RES]]650;651entry:652 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1653 %l.2.pre = load i32, ptr %ptr, align 4654 call void @may_write()655 br label %loop656 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 4662 %cmp.1 = icmp ult i32 %l.1, %l.2663 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2664 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr665 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1666 %ec = icmp eq ptr %ptr.iv.next, %end667 br i1 %ec, label %exit, label %loop668 669exit:670 %res = load i32, ptr %min.select, align 4671 ret i32 %res672}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 1678; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4679; 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 4686; 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 1690; 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 4694; CHECK-NEXT: ret i32 [[RES]]695;696entry:697 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1698 %l.2.pre = load i32, ptr %ptr, align 4699 br label %loop700 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 4707 %cmp.1 = icmp ult i32 %l.1, %l.2708 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2709 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr710 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1711 %ec = icmp eq ptr %ptr.iv.next, %end712 br i1 %ec, label %exit, label %loop713 714exit:715 %res = load i32, ptr %min.select, align 4716 ret i32 %res717}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 1723; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4724; 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 4730; 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 1734; 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 4739; CHECK-NEXT: ret i32 [[RES]]740;741entry:742 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1743 %l.2.pre = load i32, ptr %ptr, align 4744 br label %loop745 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 4751 %cmp.1 = icmp ult i32 %l.1, %l.2752 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2753 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr754 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1755 %ec = icmp eq ptr %ptr.iv.next, %end756 br i1 %ec, label %exit, label %loop757 758exit:759 call void @may_write()760 %res = load i32, ptr %min.select, align 4761 ret i32 %res762}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 1768; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4769; 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 4775; 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 1779; 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 4783; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4784; CHECK-NEXT: ret i32 [[RES]]785;786entry:787 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1788 %l.2.pre = load i32, ptr %ptr, align 4789 br label %loop790 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 4796 %cmp.1 = icmp ult i32 %l.1, %l.2797 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2798 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr799 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1800 %ec = icmp eq ptr %ptr.iv.next, %end801 br i1 %ec, label %exit, label %loop802 803exit:804 store i32 99, ptr %ptr805 %res = load i32, ptr %min.select, align 4806 ret i32 %res807}808 809declare void @may_throw() readonly810 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 1815; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4816; 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 4823; 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 1827; 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 4831; CHECK-NEXT: ret i32 [[RES]]832;833entry:834 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1835 %l.2.pre = load i32, ptr %ptr, align 4836 call void @may_throw()837 br label %loop838 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 4844 %cmp.1 = icmp ult i32 %l.1, %l.2845 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2846 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr847 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1848 %ec = icmp eq ptr %ptr.iv.next, %end849 br i1 %ec, label %exit, label %loop850 851exit:852 %res = load i32, ptr %min.select, align 4853 ret i32 %res854}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 1860; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4861; 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 4867; 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 1872; 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 4876; CHECK-NEXT: ret i32 [[RES]]877;878entry:879 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1880 %l.2.pre = load i32, ptr %ptr, align 4881 br label %loop882 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 4888 call void @may_throw()889 %cmp.1 = icmp ult i32 %l.1, %l.2890 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2891 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr892 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1893 %ec = icmp eq ptr %ptr.iv.next, %end894 br i1 %ec, label %exit, label %loop895 896exit:897 %res = load i32, ptr %min.select, align 4898 ret i32 %res899}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 1905; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4906; 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 4912; 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 1916; 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 4921; CHECK-NEXT: ret i32 [[RES]]922;923entry:924 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1925 %l.2.pre = load i32, ptr %ptr, align 4926 br label %loop927 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 4933 %cmp.1 = icmp ult i32 %l.1, %l.2934 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2935 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr936 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1937 %ec = icmp eq ptr %ptr.iv.next, %end938 br i1 %ec, label %exit, label %loop939 940exit:941 call void @may_throw()942 %res = load i32, ptr %min.select, align 4943 ret i32 %res944}945