742 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4define void @int_iv_nuw(i64 %base, i64 %end) {5; CHECK-LABEL: define void @int_iv_nuw(6; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {7; CHECK-NEXT: entry:8; CHECK-NEXT: br label [[LOOP:%.*]]9; CHECK: loop:10; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]11; CHECK-NEXT: [[IV2:%.*]] = add nuw i64 [[IV]], [[BASE]]12; CHECK-NEXT: call void @use.i64(i64 [[IV2]])13; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 414; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]15; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]16; CHECK: exit:17; CHECK-NEXT: ret void18;19entry:20 br label %loop21 22loop:23 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]24 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]25 call void @use.i64(i64 %iv2)26 %iv.next = add nuw nsw i64 %iv, 427 %iv2.next = add nuw i64 %iv.next, %base28 %cmp = icmp eq i64 %iv.next, %end29 br i1 %cmp, label %exit, label %loop30 31exit:32 ret void33}34 35define void @int_iv_nsw(i64 %base, i64 %end) {36; CHECK-LABEL: define void @int_iv_nsw(37; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {38; CHECK-NEXT: entry:39; CHECK-NEXT: br label [[LOOP:%.*]]40; CHECK: loop:41; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]42; CHECK-NEXT: [[IV2:%.*]] = add nsw i64 [[IV]], [[BASE]]43; CHECK-NEXT: call void @use.i64(i64 [[IV2]])44; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 445; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]46; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]47; CHECK: exit:48; CHECK-NEXT: ret void49;50entry:51 br label %loop52 53loop:54 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]55 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]56 call void @use.i64(i64 %iv2)57 %iv.next = add nuw nsw i64 %iv, 458 %iv2.next = add nsw i64 %iv.next, %base59 %cmp = icmp eq i64 %iv.next, %end60 br i1 %cmp, label %exit, label %loop61 62exit:63 ret void64}65 66define void @int_iv_commuted_add(i64 %base, i64 %end) {67; CHECK-LABEL: define void @int_iv_commuted_add(68; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {69; CHECK-NEXT: entry:70; CHECK-NEXT: [[BASE2:%.*]] = mul i64 [[BASE]], 4271; CHECK-NEXT: br label [[LOOP:%.*]]72; CHECK: loop:73; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]74; CHECK-NEXT: [[IV2:%.*]] = add i64 [[IV]], [[BASE2]]75; CHECK-NEXT: call void @use.i64(i64 [[IV2]])76; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 477; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]78; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]79; CHECK: exit:80; CHECK-NEXT: ret void81;82entry:83 %base2 = mul i64 %base, 42 ; thwart complexity-based canonicalization84 br label %loop85 86loop:87 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base2, %entry ]88 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]89 call void @use.i64(i64 %iv2)90 %iv.next = add nuw nsw i64 %iv, 491 %iv2.next = add i64 %base2, %iv.next92 %cmp = icmp eq i64 %iv.next, %end93 br i1 %cmp, label %exit, label %loop94 95exit:96 ret void97}98 99define void @int_iv_commuted_phi1(i64 %base, i64 %end) {100; CHECK-LABEL: define void @int_iv_commuted_phi1(101; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {102; CHECK-NEXT: entry:103; CHECK-NEXT: br label [[LOOP:%.*]]104; CHECK: loop:105; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]106; CHECK-NEXT: [[IV2:%.*]] = add i64 [[IV]], [[BASE]]107; CHECK-NEXT: call void @use.i64(i64 [[IV2]])108; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4109; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]110; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]111; CHECK: exit:112; CHECK-NEXT: ret void113;114entry:115 br label %loop116 117loop:118 %iv2 = phi i64 [ %base, %entry ], [ %iv2.next, %loop ]119 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]120 call void @use.i64(i64 %iv2)121 %iv.next = add nuw nsw i64 %iv, 4122 %iv2.next = add i64 %iv.next, %base123 %cmp = icmp eq i64 %iv.next, %end124 br i1 %cmp, label %exit, label %loop125 126exit:127 ret void128}129 130define void @int_iv_commuted_phi2(i64 %base, i64 %end) {131; CHECK-LABEL: define void @int_iv_commuted_phi2(132; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {133; CHECK-NEXT: entry:134; CHECK-NEXT: br label [[LOOP:%.*]]135; CHECK: loop:136; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]137; CHECK-NEXT: [[IV2:%.*]] = add i64 [[IV]], [[BASE]]138; CHECK-NEXT: call void @use.i64(i64 [[IV2]])139; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4140; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]141; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]142; CHECK: exit:143; CHECK-NEXT: ret void144;145entry:146 br label %loop147 148loop:149 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]150 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]151 call void @use.i64(i64 %iv2)152 %iv.next = add nuw nsw i64 %iv, 4153 %iv2.next = add i64 %iv.next, %base154 %cmp = icmp eq i64 %iv.next, %end155 br i1 %cmp, label %exit, label %loop156 157exit:158 ret void159}160 161define void @int_iv_vector(<2 x i64> %base) {162; CHECK-LABEL: define void @int_iv_vector(163; CHECK-SAME: <2 x i64> [[BASE:%.*]]) {164; CHECK-NEXT: entry:165; CHECK-NEXT: br label [[LOOP:%.*]]166; CHECK: loop:167; CHECK-NEXT: [[IV:%.*]] = phi <2 x i64> [ [[IV_NEXT:%.*]], [[LOOP]] ], [ zeroinitializer, [[ENTRY:%.*]] ]168; CHECK-NEXT: [[IV2:%.*]] = add <2 x i64> [[IV]], [[BASE]]169; CHECK-NEXT: call void @use.v2i64(<2 x i64> [[IV2]])170; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw <2 x i64> [[IV]], splat (i64 4)171; CHECK-NEXT: [[CMP:%.*]] = call i1 @get.i1()172; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]173; CHECK: exit:174; CHECK-NEXT: ret void175;176entry:177 br label %loop178 179loop:180 %iv2 = phi <2 x i64> [ %iv2.next, %loop ], [ %base, %entry ]181 %iv = phi <2 x i64> [ %iv.next, %loop ], [ zeroinitializer, %entry ]182 call void @use.v2i64(<2 x i64> %iv2)183 %iv.next = add nuw nsw <2 x i64> %iv, <i64 4, i64 4>184 %iv2.next = add <2 x i64> %iv.next, %base185 %cmp = call i1 @get.i1()186 br i1 %cmp, label %exit, label %loop187 188exit:189 ret void190}191 192define void @int_iv_vector_poison_invalid(<2 x i64> %base) {193; CHECK-LABEL: define void @int_iv_vector_poison_invalid(194; CHECK-SAME: <2 x i64> [[BASE:%.*]]) {195; CHECK-NEXT: entry:196; CHECK-NEXT: br label [[LOOP:%.*]]197; CHECK: loop:198; CHECK-NEXT: [[IV2:%.*]] = phi <2 x i64> [ [[IV2_NEXT:%.*]], [[LOOP]] ], [ [[BASE]], [[ENTRY:%.*]] ]199; CHECK-NEXT: [[IV:%.*]] = phi <2 x i64> [ [[IV_NEXT:%.*]], [[LOOP]] ], [ <i64 0, i64 poison>, [[ENTRY]] ]200; CHECK-NEXT: call void @use.v2i64(<2 x i64> [[IV2]])201; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw <2 x i64> [[IV]], splat (i64 4)202; CHECK-NEXT: [[IV2_NEXT]] = add <2 x i64> [[IV_NEXT]], [[BASE]]203; CHECK-NEXT: [[CMP:%.*]] = call i1 @get.i1()204; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]205; CHECK: exit:206; CHECK-NEXT: ret void207;208entry:209 br label %loop210 211loop:212 %iv2 = phi <2 x i64> [ %iv2.next, %loop ], [ %base, %entry ]213 %iv = phi <2 x i64> [ %iv.next, %loop ], [ <i64 0, i64 poison>, %entry ]214 call void @use.v2i64(<2 x i64> %iv2)215 %iv.next = add nuw nsw <2 x i64> %iv, <i64 4, i64 4>216 %iv2.next = add <2 x i64> %iv.next, %base217 %cmp = call i1 @get.i1()218 br i1 %cmp, label %exit, label %loop219 220exit:221 ret void222}223 224define void @int_iv_loop_variant_step(i64 %base, i64 %end) {225; CHECK-LABEL: define void @int_iv_loop_variant_step(226; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {227; CHECK-NEXT: entry:228; CHECK-NEXT: br label [[LOOP:%.*]]229; CHECK: loop:230; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]231; CHECK-NEXT: [[IV2:%.*]] = add nuw i64 [[IV]], [[BASE]]232; CHECK-NEXT: call void @use.i64(i64 [[IV2]])233; CHECK-NEXT: [[STEP:%.*]] = call i64 @get.i64()234; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], [[STEP]]235; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]236; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]237; CHECK: exit:238; CHECK-NEXT: ret void239;240entry:241 br label %loop242 243loop:244 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]245 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]246 call void @use.i64(i64 %iv2)247 %step = call i64 @get.i64()248 %iv.next = add nuw nsw i64 %iv, %step249 %iv2.next = add nuw i64 %iv.next, %base250 %cmp = icmp eq i64 %iv.next, %end251 br i1 %cmp, label %exit, label %loop252 253exit:254 ret void255}256 257define void @int_iv_xor(i64 %base, i64 %end) {258; CHECK-LABEL: define void @int_iv_xor(259; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {260; CHECK-NEXT: entry:261; CHECK-NEXT: br label [[LOOP:%.*]]262; CHECK: loop:263; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]264; CHECK-NEXT: [[IV2:%.*]] = xor i64 [[IV]], [[BASE]]265; CHECK-NEXT: call void @use.i64(i64 [[IV2]])266; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4267; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]268; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]269; CHECK: exit:270; CHECK-NEXT: ret void271;272entry:273 br label %loop274 275loop:276 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]277 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]278 call void @use.i64(i64 %iv2)279 %iv.next = add nuw nsw i64 %iv, 4280 %iv2.next = xor i64 %iv.next, %base281 %cmp = icmp eq i64 %iv.next, %end282 br i1 %cmp, label %exit, label %loop283 284exit:285 ret void286}287 288define void @int_iv_or(i64 %base, i64 %end) {289; CHECK-LABEL: define void @int_iv_or(290; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {291; CHECK-NEXT: entry:292; CHECK-NEXT: br label [[LOOP:%.*]]293; CHECK: loop:294; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]295; CHECK-NEXT: [[IV2:%.*]] = or i64 [[IV]], [[BASE]]296; CHECK-NEXT: call void @use.i64(i64 [[IV2]])297; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4298; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]299; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]300; CHECK: exit:301; CHECK-NEXT: ret void302;303entry:304 br label %loop305 306loop:307 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]308 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]309 call void @use.i64(i64 %iv2)310 %iv.next = add nuw nsw i64 %iv, 4311 %iv2.next = or i64 %iv.next, %base312 %cmp = icmp eq i64 %iv.next, %end313 br i1 %cmp, label %exit, label %loop314 315exit:316 ret void317}318 319define void @int_iv_or_disjoint(i64 %base, i64 %end) {320; CHECK-LABEL: define void @int_iv_or_disjoint(321; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {322; CHECK-NEXT: entry:323; CHECK-NEXT: br label [[LOOP:%.*]]324; CHECK: loop:325; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]326; CHECK-NEXT: [[IV2:%.*]] = or disjoint i64 [[IV]], [[BASE]]327; CHECK-NEXT: call void @use.i64(i64 [[IV2]])328; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4329; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]330; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]331; CHECK: exit:332; CHECK-NEXT: ret void333;334entry:335 br label %loop336 337loop:338 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]339 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]340 call void @use.i64(i64 %iv2)341 %iv.next = add nuw nsw i64 %iv, 4342 %iv2.next = or disjoint i64 %iv.next, %base343 %cmp = icmp eq i64 %iv.next, %end344 br i1 %cmp, label %exit, label %loop345 346exit:347 ret void348}349 350define void @int_iv_and(i64 %base, i64 %end) {351; CHECK-LABEL: define void @int_iv_and(352; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {353; CHECK-NEXT: entry:354; CHECK-NEXT: br label [[LOOP:%.*]]355; CHECK: loop:356; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ -1, [[ENTRY:%.*]] ]357; CHECK-NEXT: [[IV2:%.*]] = and i64 [[IV]], [[BASE]]358; CHECK-NEXT: call void @use.i64(i64 [[IV2]])359; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4360; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]361; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]362; CHECK: exit:363; CHECK-NEXT: ret void364;365entry:366 br label %loop367 368loop:369 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]370 %iv = phi i64 [ %iv.next, %loop ], [ -1, %entry ]371 call void @use.i64(i64 %iv2)372 %iv.next = add nuw nsw i64 %iv, 4373 %iv2.next = and i64 %iv.next, %base374 %cmp = icmp eq i64 %iv.next, %end375 br i1 %cmp, label %exit, label %loop376 377exit:378 ret void379}380 381define void @int_iv_sub(i64 %base, i64 %end) {382; CHECK-LABEL: define void @int_iv_sub(383; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {384; CHECK-NEXT: entry:385; CHECK-NEXT: br label [[LOOP:%.*]]386; CHECK: loop:387; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP]] ], [ [[BASE]], [[ENTRY:%.*]] ]388; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]389; CHECK-NEXT: call void @use.i64(i64 [[IV2]])390; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4391; CHECK-NEXT: [[IV2_NEXT]] = sub i64 [[BASE]], [[IV_NEXT]]392; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]393; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]394; CHECK: exit:395; CHECK-NEXT: ret void396;397entry:398 br label %loop399 400loop:401 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]402 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]403 call void @use.i64(i64 %iv2)404 %iv.next = add nuw nsw i64 %iv, 4405 %iv2.next = sub i64 %base, %iv.next406 %cmp = icmp eq i64 %iv.next, %end407 br i1 %cmp, label %exit, label %loop408 409exit:410 ret void411}412 413define void @int_iv_sub_invalid_order(i64 %base, i64 %end) {414; CHECK-LABEL: define void @int_iv_sub_invalid_order(415; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {416; CHECK-NEXT: entry:417; CHECK-NEXT: br label [[LOOP:%.*]]418; CHECK: loop:419; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP]] ], [ [[BASE]], [[ENTRY:%.*]] ]420; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]421; CHECK-NEXT: call void @use.i64(i64 [[IV2]])422; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4423; CHECK-NEXT: [[IV2_NEXT]] = sub i64 [[IV_NEXT]], [[BASE]]424; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]425; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]426; CHECK: exit:427; CHECK-NEXT: ret void428;429entry:430 br label %loop431 432loop:433 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]434 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]435 call void @use.i64(i64 %iv2)436 %iv.next = add nuw nsw i64 %iv, 4437 %iv2.next = sub i64 %iv.next, %base438 %cmp = icmp eq i64 %iv.next, %end439 br i1 %cmp, label %exit, label %loop440 441exit:442 ret void443}444 445define void @int_iv_add_wrong_start(i64 %base, i64 %end) {446; CHECK-LABEL: define void @int_iv_add_wrong_start(447; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {448; CHECK-NEXT: entry:449; CHECK-NEXT: br label [[LOOP:%.*]]450; CHECK: loop:451; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP]] ], [ [[BASE]], [[ENTRY:%.*]] ]452; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 1, [[ENTRY]] ]453; CHECK-NEXT: call void @use.i64(i64 [[IV2]])454; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4455; CHECK-NEXT: [[IV2_NEXT]] = add i64 [[BASE]], [[IV_NEXT]]456; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]457; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]458; CHECK: exit:459; CHECK-NEXT: ret void460;461entry:462 br label %loop463 464loop:465 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]466 %iv = phi i64 [ %iv.next, %loop ], [ 1, %entry ]467 call void @use.i64(i64 %iv2)468 %iv.next = add nuw nsw i64 %iv, 4469 %iv2.next = add i64 %base, %iv.next470 %cmp = icmp eq i64 %iv.next, %end471 br i1 %cmp, label %exit, label %loop472 473exit:474 ret void475}476 477define void @int_iv_and_wrong_start(i64 %base, i64 %end) {478; CHECK-LABEL: define void @int_iv_and_wrong_start(479; CHECK-SAME: i64 [[BASE:%.*]], i64 [[END:%.*]]) {480; CHECK-NEXT: entry:481; CHECK-NEXT: br label [[LOOP:%.*]]482; CHECK: loop:483; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP]] ], [ [[BASE]], [[ENTRY:%.*]] ]484; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]485; CHECK-NEXT: call void @use.i64(i64 [[IV2]])486; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4487; CHECK-NEXT: [[IV2_NEXT]] = and i64 [[IV_NEXT]], [[BASE]]488; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]489; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]490; CHECK: exit:491; CHECK-NEXT: ret void492;493entry:494 br label %loop495 496loop:497 %iv2 = phi i64 [ %iv2.next, %loop ], [ %base, %entry ]498 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]499 call void @use.i64(i64 %iv2)500 %iv.next = add nuw nsw i64 %iv, 4501 %iv2.next = and i64 %iv.next, %base502 %cmp = icmp eq i64 %iv.next, %end503 br i1 %cmp, label %exit, label %loop504 505exit:506 ret void507}508 509define void @ptr_iv_inbounds(ptr %base, i64 %end) {510; CHECK-LABEL: define void @ptr_iv_inbounds(511; CHECK-SAME: ptr [[BASE:%.*]], i64 [[END:%.*]]) {512; CHECK-NEXT: entry:513; CHECK-NEXT: br label [[LOOP:%.*]]514; CHECK: loop:515; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]516; CHECK-NEXT: [[IV_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[BASE]], i64 [[IV]]517; CHECK-NEXT: call void @use.p0(ptr [[IV_PTR]])518; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4519; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]520; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]521; CHECK: exit:522; CHECK-NEXT: ret void523;524entry:525 br label %loop526 527loop:528 %iv.ptr = phi ptr [ %iv.ptr.next, %loop ], [ %base, %entry ]529 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]530 call void @use.p0(ptr %iv.ptr)531 %iv.next = add nuw nsw i64 %iv, 4532 %iv.ptr.next = getelementptr inbounds i8, ptr %base, i64 %iv.next533 %cmp = icmp eq i64 %iv.next, %end534 br i1 %cmp, label %exit, label %loop535 536exit:537 ret void538}539 540define void @ptr_iv_nuw(ptr %base, i64 %end) {541; CHECK-LABEL: define void @ptr_iv_nuw(542; CHECK-SAME: ptr [[BASE:%.*]], i64 [[END:%.*]]) {543; CHECK-NEXT: entry:544; CHECK-NEXT: br label [[LOOP:%.*]]545; CHECK: loop:546; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]547; CHECK-NEXT: [[IV_PTR:%.*]] = getelementptr nuw i8, ptr [[BASE]], i64 [[IV]]548; CHECK-NEXT: call void @use.p0(ptr [[IV_PTR]])549; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4550; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]551; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]552; CHECK: exit:553; CHECK-NEXT: ret void554;555entry:556 br label %loop557 558loop:559 %iv.ptr = phi ptr [ %iv.ptr.next, %loop ], [ %base, %entry ]560 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]561 call void @use.p0(ptr %iv.ptr)562 %iv.next = add nuw nsw i64 %iv, 4563 %iv.ptr.next = getelementptr nuw i8, ptr %base, i64 %iv.next564 %cmp = icmp eq i64 %iv.next, %end565 br i1 %cmp, label %exit, label %loop566 567exit:568 ret void569}570 571define void @ptr_iv_no_flags(ptr %base, i64 %end) {572; CHECK-LABEL: define void @ptr_iv_no_flags(573; CHECK-SAME: ptr [[BASE:%.*]], i64 [[END:%.*]]) {574; CHECK-NEXT: entry:575; CHECK-NEXT: br label [[LOOP:%.*]]576; CHECK: loop:577; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]578; CHECK-NEXT: [[IV_PTR:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[IV]]579; CHECK-NEXT: call void @use.p0(ptr [[IV_PTR]])580; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4581; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]582; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]583; CHECK: exit:584; CHECK-NEXT: ret void585;586entry:587 br label %loop588 589loop:590 %iv.ptr = phi ptr [ %iv.ptr.next, %loop ], [ %base, %entry ]591 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]592 call void @use.p0(ptr %iv.ptr)593 %iv.next = add nuw nsw i64 %iv, 4594 %iv.ptr.next = getelementptr i8, ptr %base, i64 %iv.next595 %cmp = icmp eq i64 %iv.next, %end596 br i1 %cmp, label %exit, label %loop597 598exit:599 ret void600}601 602define void @ptr_iv_non_i8_type(ptr %base, i64 %end) {603; CHECK-LABEL: define void @ptr_iv_non_i8_type(604; CHECK-SAME: ptr [[BASE:%.*]], i64 [[END:%.*]]) {605; CHECK-NEXT: entry:606; CHECK-NEXT: br label [[LOOP:%.*]]607; CHECK: loop:608; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]609; CHECK-NEXT: [[IV_PTR:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[IV]]610; CHECK-NEXT: call void @use.p0(ptr [[IV_PTR]])611; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4612; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]613; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]614; CHECK: exit:615; CHECK-NEXT: ret void616;617entry:618 br label %loop619 620loop:621 %iv.ptr = phi ptr [ %iv.ptr.next, %loop ], [ %base, %entry ]622 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]623 call void @use.p0(ptr %iv.ptr)624 %iv.next = add nuw nsw i64 %iv, 4625 %iv.ptr.next = getelementptr i32, ptr %base, i64 %iv.next626 %cmp = icmp eq i64 %iv.next, %end627 br i1 %cmp, label %exit, label %loop628 629exit:630 ret void631}632 633define void @ptr_iv_vector(<2 x ptr> %base, i64 %end) {634; CHECK-LABEL: define void @ptr_iv_vector(635; CHECK-SAME: <2 x ptr> [[BASE:%.*]], i64 [[END:%.*]]) {636; CHECK-NEXT: entry:637; CHECK-NEXT: br label [[LOOP:%.*]]638; CHECK: loop:639; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]640; CHECK-NEXT: [[IV_PTR:%.*]] = getelementptr inbounds i8, <2 x ptr> [[BASE]], i64 [[IV]]641; CHECK-NEXT: call void @use.v2p0(<2 x ptr> [[IV_PTR]])642; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4643; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], [[END]]644; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]645; CHECK: exit:646; CHECK-NEXT: ret void647;648entry:649 br label %loop650 651loop:652 %iv.ptr = phi <2 x ptr> [ %iv.ptr.next, %loop ], [ %base, %entry ]653 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]654 call void @use.v2p0(<2 x ptr> %iv.ptr)655 %iv.next = add nuw nsw i64 %iv, 4656 %iv.ptr.next = getelementptr inbounds i8, <2 x ptr> %base, i64 %iv.next657 %cmp = icmp eq i64 %iv.next, %end658 br i1 %cmp, label %exit, label %loop659 660exit:661 ret void662}663 664define void @ptr_iv_vector2(<2 x ptr> %base) {665; CHECK-LABEL: define void @ptr_iv_vector2(666; CHECK-SAME: <2 x ptr> [[BASE:%.*]]) {667; CHECK-NEXT: entry:668; CHECK-NEXT: br label [[LOOP:%.*]]669; CHECK: loop:670; CHECK-NEXT: [[IV:%.*]] = phi <2 x i64> [ [[IV_NEXT:%.*]], [[LOOP]] ], [ zeroinitializer, [[ENTRY:%.*]] ]671; CHECK-NEXT: [[IV_PTR:%.*]] = getelementptr i8, <2 x ptr> [[BASE]], <2 x i64> [[IV]]672; CHECK-NEXT: call void @use.v2p0(<2 x ptr> [[IV_PTR]])673; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw <2 x i64> [[IV]], splat (i64 4)674; CHECK-NEXT: [[CMP:%.*]] = call i1 @get.i1()675; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]676; CHECK: exit:677; CHECK-NEXT: ret void678;679entry:680 br label %loop681 682loop:683 %iv.ptr = phi <2 x ptr> [ %iv.ptr.next, %loop ], [ %base, %entry ]684 %iv = phi <2 x i64> [ %iv.next, %loop ], [ zeroinitializer, %entry ]685 call void @use.v2p0(<2 x ptr> %iv.ptr)686 %iv.next = add nuw nsw <2 x i64> %iv, <i64 4, i64 4>687 %iv.ptr.next = getelementptr i8, <2 x ptr> %base, <2 x i64> %iv.next688 %cmp = call i1 @get.i1()689 br i1 %cmp, label %exit, label %loop690 691exit:692 ret void693}694 695define void @different_loops(i64 %base) {696; CHECK-LABEL: define void @different_loops(697; CHECK-SAME: i64 [[BASE:%.*]]) {698; CHECK-NEXT: entry:699; CHECK-NEXT: br label [[LOOP1:%.*]]700; CHECK: loop1:701; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP1]] ], [ 0, [[ENTRY:%.*]] ]702; CHECK-NEXT: call void @use.i64(i64 [[IV]])703; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 4704; CHECK-NEXT: [[CMP:%.*]] = call i1 @get.i1()705; CHECK-NEXT: br i1 [[CMP]], label [[LOOP2:%.*]], label [[LOOP1]]706; CHECK: loop2:707; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP2]] ], [ [[BASE]], [[LOOP1]] ]708; CHECK-NEXT: call void @use.i64(i64 [[IV2]])709; CHECK-NEXT: [[IV2_NEXT]] = add nuw i64 [[BASE]], [[IV_NEXT]]710; CHECK-NEXT: [[CMP2:%.*]] = call i1 @get.i1()711; CHECK-NEXT: br i1 [[CMP2]], label [[EXIT:%.*]], label [[LOOP2]]712; CHECK: exit:713; CHECK-NEXT: ret void714;715entry:716 br label %loop1717 718loop1:719 %iv = phi i64 [ %iv.next, %loop1 ], [ 0, %entry ]720 call void @use.i64(i64 %iv)721 %iv.next = add nuw nsw i64 %iv, 4722 %cmp = call i1 @get.i1()723 br i1 %cmp, label %loop2, label %loop1724 725loop2:726 %iv2 = phi i64 [ %iv2.next, %loop2 ], [ %base, %loop1 ]727 call void @use.i64(i64 %iv2)728 %iv2.next = add nuw i64 %base, %iv.next729 %cmp2 = call i1 @get.i1()730 br i1 %cmp2, label %exit, label %loop2731 732exit:733 ret void734}735 736declare void @use.p0(ptr)737declare void @use.v2p0(<2 x ptr>)738declare void @use.i64(i64)739declare void @use.v2i64(<2 x i64>)740declare i1 @get.i1()741declare i64 @get.i64()742