2300 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mcpu=corei7 < %s -S | FileCheck %s --check-prefixes=CHECK,NOLZCNT3; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mcpu=core-avx2 < %s -S | FileCheck %s --check-prefixes=CHECK,LZCNT4 5declare void @escape_inner(i8, i8, i8, i1, i8)6declare void @escape_outer(i8, i8, i8, i1, i8)7 8declare i8 @gen.i8()9 10; Most basic pattern; Note that iff the shift amount is offset, said offsetting11; must not cause an overflow, but `add nsw` is fine.12define i8 @p0(i8 %val, i8 %start, i8 %extraoffset) {13; NOLZCNT-LABEL: @p0(14; NOLZCNT-NEXT: entry:15; NOLZCNT-NEXT: br label [[LOOP:%.*]]16; NOLZCNT: loop:17; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]18; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]19; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]20; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 021; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 122; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])23; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]24; NOLZCNT: end:25; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]26; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]27; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]28; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]29; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]30; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])31; NOLZCNT-NEXT: ret i8 [[IV_RES]]32;33; LZCNT-LABEL: @p0(34; LZCNT-NEXT: entry:35; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)36; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]37; LZCNT-NEXT: [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]38; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]39; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])40; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]41; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 142; LZCNT-NEXT: br label [[LOOP:%.*]]43; LZCNT: loop:44; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]45; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 146; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]47; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]48; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]49; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]50; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 151; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])52; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]53; LZCNT: end:54; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]55; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]56; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]57; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]58; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]59; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])60; LZCNT-NEXT: ret i8 [[IV_RES]]61;62entry:63 br label %loop64 65loop:66 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]67 %nbits = add nsw i8 %iv, %extraoffset68 %val.shifted = shl i8 %val, %nbits69 %val.shifted.iszero = icmp eq i8 %val.shifted, 070 %iv.next = add i8 %iv, 171 72 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)73 74 br i1 %val.shifted.iszero, label %end, label %loop75 76end:77 %iv.res = phi i8 [ %iv, %loop ]78 %nbits.res = phi i8 [ %nbits, %loop ]79 %val.shifted.res = phi i8 [ %val.shifted, %loop ]80 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]81 %iv.next.res = phi i8 [ %iv.next, %loop ]82 83 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)84 85 ret i8 %iv.res86}87 88; `add nuw` is also fine.89define i8 @p1(i8 %val, i8 %start, i8 %extraoffset) {90; NOLZCNT-LABEL: @p1(91; NOLZCNT-NEXT: entry:92; NOLZCNT-NEXT: br label [[LOOP:%.*]]93; NOLZCNT: loop:94; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]95; NOLZCNT-NEXT: [[NBITS:%.*]] = add nuw i8 [[IV]], [[EXTRAOFFSET:%.*]]96; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]97; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 098; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 199; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])100; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]101; NOLZCNT: end:102; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]103; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]104; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]105; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]106; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]107; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])108; NOLZCNT-NEXT: ret i8 [[IV_RES]]109;110; LZCNT-LABEL: @p1(111; LZCNT-NEXT: entry:112; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)113; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]114; LZCNT-NEXT: [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]115; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]116; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])117; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]118; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1119; LZCNT-NEXT: br label [[LOOP:%.*]]120; LZCNT: loop:121; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]122; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1123; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]124; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]125; LZCNT-NEXT: [[NBITS:%.*]] = add nuw i8 [[IV]], [[EXTRAOFFSET]]126; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]127; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1128; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])129; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]130; LZCNT: end:131; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]132; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]133; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]134; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]135; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]136; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])137; LZCNT-NEXT: ret i8 [[IV_RES]]138;139entry:140 br label %loop141 142loop:143 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]144 %nbits = add nuw i8 %iv, %extraoffset145 %val.shifted = shl i8 %val, %nbits146 %val.shifted.iszero = icmp eq i8 %val.shifted, 0147 %iv.next = add i8 %iv, 1148 149 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)150 151 br i1 %val.shifted.iszero, label %end, label %loop152 153end:154 %iv.res = phi i8 [ %iv, %loop ]155 %nbits.res = phi i8 [ %nbits, %loop ]156 %val.shifted.res = phi i8 [ %val.shifted, %loop ]157 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]158 %iv.next.res = phi i8 [ %iv.next, %loop ]159 160 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)161 162 ret i8 %iv.res163}164 165; `sub nsw` is also fine.166define i8 @p2(i8 %val, i8 %start, i8 %extraoffset) {167; NOLZCNT-LABEL: @p2(168; NOLZCNT-NEXT: entry:169; NOLZCNT-NEXT: br label [[LOOP:%.*]]170; NOLZCNT: loop:171; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]172; NOLZCNT-NEXT: [[NBITS:%.*]] = sub nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]173; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]174; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0175; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1176; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])177; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]178; NOLZCNT: end:179; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]180; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]181; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]182; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]183; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]184; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])185; NOLZCNT-NEXT: ret i8 [[IV_RES]]186;187; LZCNT-LABEL: @p2(188; LZCNT-NEXT: entry:189; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)190; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]191; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]192; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])193; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]194; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1195; LZCNT-NEXT: br label [[LOOP:%.*]]196; LZCNT: loop:197; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]198; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1199; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]200; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]201; LZCNT-NEXT: [[NBITS:%.*]] = sub nsw i8 [[IV]], [[EXTRAOFFSET]]202; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]203; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1204; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])205; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]206; LZCNT: end:207; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]208; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]209; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]210; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]211; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]212; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])213; LZCNT-NEXT: ret i8 [[IV_RES]]214;215entry:216 br label %loop217 218loop:219 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]220 %nbits = sub nsw i8 %iv, %extraoffset221 %val.shifted = shl i8 %val, %nbits222 %val.shifted.iszero = icmp eq i8 %val.shifted, 0223 %iv.next = add i8 %iv, 1224 225 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)226 227 br i1 %val.shifted.iszero, label %end, label %loop228 229end:230 %iv.res = phi i8 [ %iv, %loop ]231 %nbits.res = phi i8 [ %nbits, %loop ]232 %val.shifted.res = phi i8 [ %val.shifted, %loop ]233 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]234 %iv.next.res = phi i8 [ %iv.next, %loop ]235 236 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)237 238 ret i8 %iv.res239}240 241; But `sub nuw` is not fine..242define i8 @n3(i8 %val, i8 %start, i8 %extraoffset) {243; CHECK-LABEL: @n3(244; CHECK-NEXT: entry:245; CHECK-NEXT: br label [[LOOP:%.*]]246; CHECK: loop:247; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]248; CHECK-NEXT: [[NBITS:%.*]] = sub nuw i8 [[IV]], [[EXTRAOFFSET:%.*]]249; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]250; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0251; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1252; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])253; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]254; CHECK: end:255; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]256; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]257; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]258; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]259; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]260; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])261; CHECK-NEXT: ret i8 [[IV_RES]]262;263entry:264 br label %loop265 266loop:267 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]268 %nbits = sub nuw i8 %iv, %extraoffset269 %val.shifted = shl i8 %val, %nbits270 %val.shifted.iszero = icmp eq i8 %val.shifted, 0271 %iv.next = add i8 %iv, 1272 273 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)274 275 br i1 %val.shifted.iszero, label %end, label %loop276 277end:278 %iv.res = phi i8 [ %iv, %loop ]279 %nbits.res = phi i8 [ %nbits, %loop ]280 %val.shifted.res = phi i8 [ %val.shifted, %loop ]281 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]282 %iv.next.res = phi i8 [ %iv.next, %loop ]283 284 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)285 286 ret i8 %iv.res287}288 289; Likewise, plain `sub` is not fine.290define i8 @n4(i8 %val, i8 %start, i8 %extraoffset) {291; CHECK-LABEL: @n4(292; CHECK-NEXT: entry:293; CHECK-NEXT: br label [[LOOP:%.*]]294; CHECK: loop:295; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]296; CHECK-NEXT: [[NBITS:%.*]] = sub i8 [[IV]], [[EXTRAOFFSET:%.*]]297; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]298; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0299; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1300; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])301; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]302; CHECK: end:303; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]304; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]305; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]306; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]307; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]308; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])309; CHECK-NEXT: ret i8 [[IV_RES]]310;311entry:312 br label %loop313 314loop:315 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]316 %nbits = sub i8 %iv, %extraoffset317 %val.shifted = shl i8 %val, %nbits318 %val.shifted.iszero = icmp eq i8 %val.shifted, 0319 %iv.next = add i8 %iv, 1320 321 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)322 323 br i1 %val.shifted.iszero, label %end, label %loop324 325end:326 %iv.res = phi i8 [ %iv, %loop ]327 %nbits.res = phi i8 [ %nbits, %loop ]328 %val.shifted.res = phi i8 [ %val.shifted, %loop ]329 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]330 %iv.next.res = phi i8 [ %iv.next, %loop ]331 332 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)333 334 ret i8 %iv.res335}336 337; Likewise, plain `add` is not fine.338define i8 @n5(i8 %val, i8 %start, i8 %extraoffset) {339; CHECK-LABEL: @n5(340; CHECK-NEXT: entry:341; CHECK-NEXT: br label [[LOOP:%.*]]342; CHECK: loop:343; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]344; CHECK-NEXT: [[NBITS:%.*]] = add i8 [[IV]], [[EXTRAOFFSET:%.*]]345; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]346; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0347; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1348; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])349; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]350; CHECK: end:351; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]352; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]353; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]354; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]355; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]356; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])357; CHECK-NEXT: ret i8 [[IV_RES]]358;359entry:360 br label %loop361 362loop:363 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]364 %nbits = add i8 %iv, %extraoffset365 %val.shifted = shl i8 %val, %nbits366 %val.shifted.iszero = icmp eq i8 %val.shifted, 0367 %iv.next = add i8 %iv, 1368 369 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)370 371 br i1 %val.shifted.iszero, label %end, label %loop372 373end:374 %iv.res = phi i8 [ %iv, %loop ]375 %nbits.res = phi i8 [ %nbits, %loop ]376 %val.shifted.res = phi i8 [ %val.shifted, %loop ]377 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]378 %iv.next.res = phi i8 [ %iv.next, %loop ]379 380 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)381 382 ret i8 %iv.res383}384 385; Of course, we don't have to have an offset386define i8 @p6(i8 %val, i8 %start) {387; NOLZCNT-LABEL: @p6(388; NOLZCNT-NEXT: entry:389; NOLZCNT-NEXT: br label [[LOOP:%.*]]390; NOLZCNT: loop:391; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]392; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[IV]]393; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0394; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1395; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[IV]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])396; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]397; NOLZCNT: end:398; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]399; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]400; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]401; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]402; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[IV_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])403; NOLZCNT-NEXT: ret i8 [[IV_RES]]404;405; LZCNT-LABEL: @p6(406; LZCNT-NEXT: entry:407; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)408; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]409; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i8 [[VAL_NUMACTIVEBITS]], 0410; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])411; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i8 [[IV_FINAL]], [[START]]412; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1413; LZCNT-NEXT: br label [[LOOP:%.*]]414; LZCNT: loop:415; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]416; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1417; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]418; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]419; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[IV]]420; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1421; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[IV]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])422; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]423; LZCNT: end:424; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]425; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]426; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]427; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]428; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[IV_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])429; LZCNT-NEXT: ret i8 [[IV_RES]]430;431entry:432 br label %loop433 434loop:435 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]436 %val.shifted = shl i8 %val, %iv437 %val.shifted.iszero = icmp eq i8 %val.shifted, 0438 %iv.next = add i8 %iv, 1439 440 call void @escape_inner(i8 %iv, i8 %iv, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)441 442 br i1 %val.shifted.iszero, label %end, label %loop443 444end:445 %iv.res = phi i8 [ %iv, %loop ]446 %val.shifted.res = phi i8 [ %val.shifted, %loop ]447 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]448 %iv.next.res = phi i8 [ %iv.next, %loop ]449 450 call void @escape_outer(i8 %iv.res, i8 %iv.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)451 452 ret i8 %iv.res453}454 455declare void @escape_inner.i7(i7, i7, i7, i1, i7)456declare void @escape_outer.i7(i7, i7, i7, i1, i7)457 458; Other bitwidths are fine also459define i7 @p7(i7 %val, i7 %start, i7 %extraoffset) {460; NOLZCNT-LABEL: @p7(461; NOLZCNT-NEXT: entry:462; NOLZCNT-NEXT: br label [[LOOP:%.*]]463; NOLZCNT: loop:464; NOLZCNT-NEXT: [[IV:%.*]] = phi i7 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]465; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i7 [[IV]], [[EXTRAOFFSET:%.*]]466; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i7 [[VAL:%.*]], [[NBITS]]467; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i7 [[VAL_SHIFTED]], 0468; NOLZCNT-NEXT: [[IV_NEXT]] = add i7 [[IV]], 1469; NOLZCNT-NEXT: call void @escape_inner.i7(i7 [[IV]], i7 [[NBITS]], i7 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i7 [[IV_NEXT]])470; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]471; NOLZCNT: end:472; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i7 [ [[IV]], [[LOOP]] ]473; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i7 [ [[NBITS]], [[LOOP]] ]474; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i7 [ [[VAL_SHIFTED]], [[LOOP]] ]475; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]476; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i7 [ [[IV_NEXT]], [[LOOP]] ]477; NOLZCNT-NEXT: call void @escape_outer.i7(i7 [[IV_RES]], i7 [[NBITS_RES]], i7 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i7 [[IV_NEXT_RES]])478; NOLZCNT-NEXT: ret i7 [[IV_RES]]479;480; LZCNT-LABEL: @p7(481; LZCNT-NEXT: entry:482; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i7 @llvm.cttz.i7(i7 [[VAL:%.*]], i1 false)483; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i7 7, [[VAL_NUMLEADINGZEROS]]484; LZCNT-NEXT: [[TMP0:%.*]] = sub i7 0, [[EXTRAOFFSET:%.*]]485; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i7 [[VAL_NUMACTIVEBITS]], [[TMP0]]486; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i7 @llvm.smax.i7(i7 [[VAL_NUMACTIVEBITS_OFFSET]], i7 [[START:%.*]])487; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i7 [[IV_FINAL]], [[START]]488; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i7 [[LOOP_BACKEDGETAKENCOUNT]], 1489; LZCNT-NEXT: br label [[LOOP:%.*]]490; LZCNT: loop:491; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i7 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]492; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i7 [[LOOP_IV]], 1493; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i7 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]494; LZCNT-NEXT: [[IV:%.*]] = add nsw i7 [[LOOP_IV]], [[START]]495; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i7 [[IV]], [[EXTRAOFFSET]]496; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i7 [[VAL]], [[NBITS]]497; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i7 [[IV]], 1498; LZCNT-NEXT: call void @escape_inner.i7(i7 [[IV]], i7 [[NBITS]], i7 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i7 [[IV_NEXT]])499; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]500; LZCNT: end:501; LZCNT-NEXT: [[IV_RES:%.*]] = phi i7 [ [[IV_FINAL]], [[LOOP]] ]502; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i7 [ [[NBITS]], [[LOOP]] ]503; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i7 [ [[VAL_SHIFTED]], [[LOOP]] ]504; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]505; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i7 [ [[IV_NEXT]], [[LOOP]] ]506; LZCNT-NEXT: call void @escape_outer.i7(i7 [[IV_RES]], i7 [[NBITS_RES]], i7 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i7 [[IV_NEXT_RES]])507; LZCNT-NEXT: ret i7 [[IV_RES]]508;509entry:510 br label %loop511 512loop:513 %iv = phi i7 [ %start, %entry ], [ %iv.next, %loop ]514 %nbits = add nsw i7 %iv, %extraoffset515 %val.shifted = shl i7 %val, %nbits516 %val.shifted.iszero = icmp eq i7 %val.shifted, 0517 %iv.next = add i7 %iv, 1518 519 call void @escape_inner.i7(i7 %iv, i7 %nbits, i7 %val.shifted, i1 %val.shifted.iszero, i7 %iv.next)520 521 br i1 %val.shifted.iszero, label %end, label %loop522 523end:524 %iv.res = phi i7 [ %iv, %loop ]525 %nbits.res = phi i7 [ %nbits, %loop ]526 %val.shifted.res = phi i7 [ %val.shifted, %loop ]527 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]528 %iv.next.res = phi i7 [ %iv.next, %loop ]529 530 call void @escape_outer.i7(i7 %iv.res, i7 %nbits.res, i7 %val.shifted.res, i1 %val.shifted.iszero.res, i7 %iv.next.res)531 532 ret i7 %iv.res533}534 535; Step must be 1536define i8 @n8(i8 %val, i8 %start, i8 %extraoffset) {537; CHECK-LABEL: @n8(538; CHECK-NEXT: entry:539; CHECK-NEXT: br label [[LOOP:%.*]]540; CHECK: loop:541; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]542; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]543; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]544; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0545; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 2546; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])547; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]548; CHECK: end:549; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]550; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]551; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]552; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]553; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]554; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])555; CHECK-NEXT: ret i8 [[IV_RES]]556;557entry:558 br label %loop559 560loop:561 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]562 %nbits = add nsw i8 %iv, %extraoffset563 %val.shifted = shl i8 %val, %nbits564 %val.shifted.iszero = icmp eq i8 %val.shifted, 0565 %iv.next = add i8 %iv, 2 ; not 1566 567 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)568 569 br i1 %val.shifted.iszero, label %end, label %loop570 571end:572 %iv.res = phi i8 [ %iv, %loop ]573 %nbits.res = phi i8 [ %nbits, %loop ]574 %val.shifted.res = phi i8 [ %val.shifted, %loop ]575 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]576 %iv.next.res = phi i8 [ %iv.next, %loop ]577 578 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)579 580 ret i8 %iv.res581}582 583; Cmp-br are commutable584define i8 @t9(i8 %val, i8 %start, i8 %extraoffset) {585; NOLZCNT-LABEL: @t9(586; NOLZCNT-NEXT: entry:587; NOLZCNT-NEXT: br label [[LOOP:%.*]]588; NOLZCNT: loop:589; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]590; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]591; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]592; NOLZCNT-NEXT: [[VAL_SHIFTED_ISNOTZERO:%.*]] = icmp ne i8 [[VAL_SHIFTED]], 0593; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1594; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISNOTZERO]], i8 [[IV_NEXT]])595; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISNOTZERO]], label [[LOOP]], label [[END:%.*]]596; NOLZCNT: end:597; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]598; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]599; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]600; NOLZCNT-NEXT: [[VAL_SHIFTED_ISNOTZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISNOTZERO]], [[LOOP]] ]601; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]602; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISNOTZERO_RES]], i8 [[IV_NEXT_RES]])603; NOLZCNT-NEXT: ret i8 [[IV_RES]]604;605; LZCNT-LABEL: @t9(606; LZCNT-NEXT: entry:607; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)608; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]609; LZCNT-NEXT: [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]610; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]611; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])612; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]613; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1614; LZCNT-NEXT: br label [[LOOP:%.*]]615; LZCNT: loop:616; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]617; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1618; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]619; LZCNT-NEXT: [[VAL_SHIFTED_ISNOTZERO:%.*]] = xor i1 [[LOOP_IVCHECK]], true620; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]621; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]622; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]623; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1624; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISNOTZERO]], i8 [[IV_NEXT]])625; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]626; LZCNT: end:627; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]628; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]629; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]630; LZCNT-NEXT: [[VAL_SHIFTED_ISNOTZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISNOTZERO]], [[LOOP]] ]631; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]632; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISNOTZERO_RES]], i8 [[IV_NEXT_RES]])633; LZCNT-NEXT: ret i8 [[IV_RES]]634;635entry:636 br label %loop637 638loop:639 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]640 %nbits = add nsw i8 %iv, %extraoffset641 %val.shifted = shl i8 %val, %nbits642 %val.shifted.isnotzero = icmp ne i8 %val.shifted, 0643 %iv.next = add i8 %iv, 1644 645 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.isnotzero, i8 %iv.next)646 647 br i1 %val.shifted.isnotzero, label %loop, label %end648 649end:650 %iv.res = phi i8 [ %iv, %loop ]651 %nbits.res = phi i8 [ %nbits, %loop ]652 %val.shifted.res = phi i8 [ %val.shifted, %loop ]653 %val.shifted.isnotzero.res = phi i1 [ %val.shifted.isnotzero, %loop ]654 %iv.next.res = phi i8 [ %iv.next, %loop ]655 656 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.isnotzero.res, i8 %iv.next.res)657 658 ret i8 %iv.res659}660 661; We want to exit once it becomes zero662define i8 @n10(i8 %val, i8 %start, i8 %extraoffset) {663; CHECK-LABEL: @n10(664; CHECK-NEXT: entry:665; CHECK-NEXT: br label [[LOOP:%.*]]666; CHECK: loop:667; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]668; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]669; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]670; CHECK-NEXT: [[VAL_SHIFTED_ISNOTZERO:%.*]] = icmp ne i8 [[VAL_SHIFTED]], 0671; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1672; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISNOTZERO]], i8 [[IV_NEXT]])673; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISNOTZERO]], label [[END:%.*]], label [[LOOP]]674; CHECK: end:675; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]676; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]677; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]678; CHECK-NEXT: [[VAL_SHIFTED_ISNOTZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISNOTZERO]], [[LOOP]] ]679; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]680; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISNOTZERO_RES]], i8 [[IV_NEXT_RES]])681; CHECK-NEXT: ret i8 [[IV_RES]]682;683entry:684 br label %loop685 686loop:687 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]688 %nbits = add nsw i8 %iv, %extraoffset689 %val.shifted = shl i8 %val, %nbits690 %val.shifted.isnotzero = icmp ne i8 %val.shifted, 0 ; not eq691 %iv.next = add i8 %iv, 1692 693 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.isnotzero, i8 %iv.next)694 695 br i1 %val.shifted.isnotzero, label %end, label %loop696 697end:698 %iv.res = phi i8 [ %iv, %loop ]699 %nbits.res = phi i8 [ %nbits, %loop ]700 %val.shifted.res = phi i8 [ %val.shifted, %loop ]701 %val.shifted.isnotzero.res = phi i1 [ %val.shifted.isnotzero, %loop ]702 %iv.next.res = phi i8 [ %iv.next, %loop ]703 704 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.isnotzero.res, i8 %iv.next.res)705 706 ret i8 %iv.res707}708 709; Once it compares zero, we want to exit, not exit when it compares non-zero710define i8 @n11(i8 %val, i8 %start, i8 %extraoffset) {711; CHECK-LABEL: @n11(712; CHECK-NEXT: entry:713; CHECK-NEXT: br label [[LOOP:%.*]]714; CHECK: loop:715; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]716; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]717; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]718; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0719; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1720; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])721; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[LOOP]], label [[END:%.*]]722; CHECK: end:723; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]724; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]725; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]726; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]727; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]728; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])729; CHECK-NEXT: ret i8 [[IV_RES]]730;731entry:732 br label %loop733 734loop:735 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]736 %nbits = add nsw i8 %iv, %extraoffset737 %val.shifted = shl i8 %val, %nbits738 %val.shifted.iszero = icmp eq i8 %val.shifted, 0739 %iv.next = add i8 %iv, 1740 741 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)742 743 br i1 %val.shifted.iszero, label %loop, label %end ; wrong destinations744 745end:746 %iv.res = phi i8 [ %iv, %loop ]747 %nbits.res = phi i8 [ %nbits, %loop ]748 %val.shifted.res = phi i8 [ %val.shifted, %loop ]749 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]750 %iv.next.res = phi i8 [ %iv.next, %loop ]751 752 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)753 754 ret i8 %iv.res755}756 757; We must be comparing with 0758define i8 @n12(i8 %val, i8 %start, i8 %extraoffset) {759; CHECK-LABEL: @n12(760; CHECK-NEXT: entry:761; CHECK-NEXT: br label [[LOOP:%.*]]762; CHECK: loop:763; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]764; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]765; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]766; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 1767; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1768; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])769; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]770; CHECK: end:771; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]772; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]773; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]774; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]775; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]776; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])777; CHECK-NEXT: ret i8 [[IV_RES]]778;779entry:780 br label %loop781 782loop:783 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]784 %nbits = add nsw i8 %iv, %extraoffset785 %val.shifted = shl i8 %val, %nbits786 %val.shifted.iszero = icmp eq i8 %val.shifted, 1 ; not 0787 %iv.next = add i8 %iv, 1788 789 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)790 791 br i1 %val.shifted.iszero, label %end, label %loop792 793end:794 %iv.res = phi i8 [ %iv, %loop ]795 %nbits.res = phi i8 [ %nbits, %loop ]796 %val.shifted.res = phi i8 [ %val.shifted, %loop ]797 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]798 %iv.next.res = phi i8 [ %iv.next, %loop ]799 800 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)801 802 ret i8 %iv.res803}804 805; Loop must have a single block.806define i8 @n13(i8 %val, i8 %start, i8 %extraoffset) {807; CHECK-LABEL: @n13(808; CHECK-NEXT: entry:809; CHECK-NEXT: br label [[LOOP:%.*]]810; CHECK: loop:811; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_END:%.*]] ]812; CHECK-NEXT: br label [[LOOP_END]]813; CHECK: loop.end:814; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]815; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]816; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0817; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1818; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])819; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]820; CHECK: end:821; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP_END]] ]822; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP_END]] ]823; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP_END]] ]824; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP_END]] ]825; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP_END]] ]826; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])827; CHECK-NEXT: ret i8 [[IV_RES]]828;829entry:830 br label %loop831 832loop:833 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop.end ]834 br label %loop.end835 836loop.end:837 %nbits = add nsw i8 %iv, %extraoffset838 %val.shifted = shl i8 %val, %nbits839 %val.shifted.iszero = icmp eq i8 %val.shifted, 0840 %iv.next = add i8 %iv, 1841 842 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)843 844 br i1 %val.shifted.iszero, label %end, label %loop845 846end:847 %iv.res = phi i8 [ %iv, %loop.end ]848 %nbits.res = phi i8 [ %nbits, %loop.end ]849 %val.shifted.res = phi i8 [ %val.shifted, %loop.end ]850 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop.end ]851 %iv.next.res = phi i8 [ %iv.next, %loop.end ]852 853 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)854 855 ret i8 %iv.res856}857 858; The comparison must have an equality predicate859define i8 @n14(i8 %val, i8 %start, i8 %extraoffset) {860; CHECK-LABEL: @n14(861; CHECK-NEXT: entry:862; CHECK-NEXT: br label [[LOOP:%.*]]863; CHECK: loop:864; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]865; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]866; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]867; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp ult i8 [[VAL_SHIFTED]], 1868; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1869; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])870; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]871; CHECK: end:872; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]873; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]874; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]875; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]876; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]877; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])878; CHECK-NEXT: ret i8 [[IV_RES]]879;880entry:881 br label %loop882 883loop:884 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]885 %nbits = add nsw i8 %iv, %extraoffset886 %val.shifted = shl i8 %val, %nbits887 %val.shifted.iszero = icmp ult i8 %val.shifted, 1 ; not `==0`888 %iv.next = add i8 %iv, 1889 890 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)891 892 br i1 %val.shifted.iszero, label %end, label %loop893 894end:895 %iv.res = phi i8 [ %iv, %loop ]896 %nbits.res = phi i8 [ %nbits, %loop ]897 %val.shifted.res = phi i8 [ %val.shifted, %loop ]898 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]899 %iv.next.res = phi i8 [ %iv.next, %loop ]900 901 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)902 903 ret i8 %iv.res904}905 906; offset computation can be commuted907define i8 @t15(i8 %val, i8 %start, i8 %extraoffset) {908; NOLZCNT-LABEL: @t15(909; NOLZCNT-NEXT: entry:910; NOLZCNT-NEXT: br label [[LOOP:%.*]]911; NOLZCNT: loop:912; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]913; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[EXTRAOFFSET:%.*]], [[IV]]914; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]915; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0916; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1917; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])918; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]919; NOLZCNT: end:920; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]921; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]922; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]923; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]924; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]925; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])926; NOLZCNT-NEXT: ret i8 [[IV_RES]]927;928; LZCNT-LABEL: @t15(929; LZCNT-NEXT: entry:930; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)931; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]932; LZCNT-NEXT: [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]933; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]934; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])935; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]936; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1937; LZCNT-NEXT: br label [[LOOP:%.*]]938; LZCNT: loop:939; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]940; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1941; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]942; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]943; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[EXTRAOFFSET]], [[IV]]944; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]945; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1946; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])947; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]948; LZCNT: end:949; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]950; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]951; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]952; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]953; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]954; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])955; LZCNT-NEXT: ret i8 [[IV_RES]]956;957entry:958 br label %loop959 960loop:961 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]962 %nbits = add nsw i8 %extraoffset, %iv ; swapped order963 %val.shifted = shl i8 %val, %nbits964 %val.shifted.iszero = icmp eq i8 %val.shifted, 0965 %iv.next = add i8 %iv, 1966 967 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)968 969 br i1 %val.shifted.iszero, label %end, label %loop970 971end:972 %iv.res = phi i8 [ %iv, %loop ]973 %nbits.res = phi i8 [ %nbits, %loop ]974 %val.shifted.res = phi i8 [ %val.shifted, %loop ]975 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]976 %iv.next.res = phi i8 [ %iv.next, %loop ]977 978 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)979 980 ret i8 %iv.res981}982 983; But for `sub nsw`, it is not commutable.984define i8 @n16(i8 %val, i8 %start, i8 %extraoffset) {985; CHECK-LABEL: @n16(986; CHECK-NEXT: entry:987; CHECK-NEXT: br label [[LOOP:%.*]]988; CHECK: loop:989; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]990; CHECK-NEXT: [[NBITS:%.*]] = sub nsw i8 [[EXTRAOFFSET:%.*]], [[IV]]991; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]992; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0993; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1994; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])995; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]996; CHECK: end:997; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]998; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]999; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1000; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1001; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1002; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1003; CHECK-NEXT: ret i8 [[IV_RES]]1004;1005entry:1006 br label %loop1007 1008loop:1009 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]1010 %nbits = sub nsw i8 %extraoffset, %iv1011 %val.shifted = shl i8 %val, %nbits1012 %val.shifted.iszero = icmp eq i8 %val.shifted, 01013 %iv.next = add i8 %iv, 11014 1015 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1016 1017 br i1 %val.shifted.iszero, label %end, label %loop1018 1019end:1020 %iv.res = phi i8 [ %iv, %loop ]1021 %nbits.res = phi i8 [ %nbits, %loop ]1022 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1023 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1024 %iv.next.res = phi i8 [ %iv.next, %loop ]1025 1026 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1027 1028 ret i8 %iv.res1029}1030 1031; The offset must be loop-invariant1032define i8 @n17(i8 %val, i8 %start) {1033; CHECK-LABEL: @n17(1034; CHECK-NEXT: entry:1035; CHECK-NEXT: br label [[LOOP:%.*]]1036; CHECK: loop:1037; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1038; CHECK-NEXT: [[EXTRAOFFSET:%.*]] = call i8 @gen.i8()1039; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]1040; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]1041; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01042; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 11043; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1044; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1045; CHECK: end:1046; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1047; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1048; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1049; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1050; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1051; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1052; CHECK-NEXT: ret i8 [[IV_RES]]1053;1054entry:1055 br label %loop1056 1057loop:1058 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]1059 %extraoffset = call i8 @gen.i8()1060 %nbits = add nsw i8 %iv, %extraoffset1061 %val.shifted = shl i8 %val, %nbits1062 %val.shifted.iszero = icmp eq i8 %val.shifted, 01063 %iv.next = add i8 %iv, 11064 1065 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1066 1067 br i1 %val.shifted.iszero, label %end, label %loop1068 1069end:1070 %iv.res = phi i8 [ %iv, %loop ]1071 %nbits.res = phi i8 [ %nbits, %loop ]1072 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1073 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1074 %iv.next.res = phi i8 [ %iv.next, %loop ]1075 1076 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1077 1078 ret i8 %iv.res1079}1080 1081; Likewise for `sub nsw`.1082define i8 @n18(i8 %val, i8 %start) {1083; CHECK-LABEL: @n18(1084; CHECK-NEXT: entry:1085; CHECK-NEXT: br label [[LOOP:%.*]]1086; CHECK: loop:1087; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1088; CHECK-NEXT: [[EXTRAOFFSET:%.*]] = call i8 @gen.i8()1089; CHECK-NEXT: [[NBITS:%.*]] = sub nsw i8 [[IV]], [[EXTRAOFFSET]]1090; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]1091; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01092; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 11093; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1094; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1095; CHECK: end:1096; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1097; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1098; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1099; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1100; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1101; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1102; CHECK-NEXT: ret i8 [[IV_RES]]1103;1104entry:1105 br label %loop1106 1107loop:1108 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]1109 %extraoffset = call i8 @gen.i8()1110 %nbits = sub nsw i8 %iv, %extraoffset1111 %val.shifted = shl i8 %val, %nbits1112 %val.shifted.iszero = icmp eq i8 %val.shifted, 01113 %iv.next = add i8 %iv, 11114 1115 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1116 1117 br i1 %val.shifted.iszero, label %end, label %loop1118 1119end:1120 %iv.res = phi i8 [ %iv, %loop ]1121 %nbits.res = phi i8 [ %nbits, %loop ]1122 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1123 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1124 %iv.next.res = phi i8 [ %iv.next, %loop ]1125 1126 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1127 1128 ret i8 %iv.res1129}1130 1131; The "induction variable" must be in the loop header.1132define i8 @n19(i8 %val, i8 %start, i8 %extraoffset) {1133; CHECK-LABEL: @n19(1134; CHECK-NEXT: entry:1135; CHECK-NEXT: br label [[LOOP_PREHEADER:%.*]]1136; CHECK: loop.preheader:1137; CHECK-NEXT: [[NOTIV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ]1138; CHECK-NEXT: br label [[LOOP:%.*]]1139; CHECK: loop:1140; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[LOOP_PREHEADER]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1141; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[NOTIV]], [[EXTRAOFFSET:%.*]]1142; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]1143; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01144; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 11145; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1146; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1147; CHECK: end:1148; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1149; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1150; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1151; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1152; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1153; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1154; CHECK-NEXT: ret i8 [[IV_RES]]1155;1156entry:1157 br label %loop.preheader1158 1159loop.preheader:1160 %notiv = phi i8 [ 0, %entry ]1161 br label %loop1162 1163loop:1164 %iv = phi i8 [ %start, %loop.preheader ], [ %iv.next, %loop ]1165 %nbits = add nsw i8 %notiv, %extraoffset ; uses %notiv instead of %iv1166 %val.shifted = shl i8 %val, %nbits1167 %val.shifted.iszero = icmp eq i8 %val.shifted, 01168 %iv.next = add i8 %iv, 11169 1170 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1171 1172 br i1 %val.shifted.iszero, label %end, label %loop1173 1174end:1175 %iv.res = phi i8 [ %iv, %loop ]1176 %nbits.res = phi i8 [ %nbits, %loop ]1177 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1178 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1179 %iv.next.res = phi i8 [ %iv.next, %loop ]1180 1181 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1182 1183 ret i8 %iv.res1184}1185 1186; IV must really be a PHI1187define i8 @n20(i8 %val, i8 %start, i8 %extraoffset) {1188; CHECK-LABEL: @n20(1189; CHECK-NEXT: entry:1190; CHECK-NEXT: br label [[LOOP:%.*]]1191; CHECK: loop:1192; CHECK-NEXT: [[IV:%.*]] = add i8 0, 01193; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]1194; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]1195; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01196; CHECK-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 11197; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1198; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1199; CHECK: end:1200; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1201; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1202; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1203; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1204; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1205; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1206; CHECK-NEXT: ret i8 [[IV_RES]]1207;1208entry:1209 br label %loop1210 1211loop:1212 %iv = add i8 0, 0 ; again not IV1213 %nbits = add nsw i8 %iv, %extraoffset1214 %val.shifted = shl i8 %val, %nbits1215 %val.shifted.iszero = icmp eq i8 %val.shifted, 01216 %iv.next = add i8 %iv, 11217 1218 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1219 1220 br i1 %val.shifted.iszero, label %end, label %loop1221 1222end:1223 %iv.res = phi i8 [ %iv, %loop ]1224 %nbits.res = phi i8 [ %nbits, %loop ]1225 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1226 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1227 %iv.next.res = phi i8 [ %iv.next, %loop ]1228 1229 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1230 1231 ret i8 %iv.res1232}1233 1234; The induction should be actually increasing IV1235define i8 @n21(i8 %val, i8 %start, i8 %extraoffset) {1236; CHECK-LABEL: @n21(1237; CHECK-NEXT: entry:1238; CHECK-NEXT: br label [[LOOP:%.*]]1239; CHECK: loop:1240; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1241; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]1242; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]1243; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01244; CHECK-NEXT: [[IV_NEXT]] = add i8 0, 11245; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1246; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1247; CHECK: end:1248; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1249; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1250; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1251; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1252; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1253; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1254; CHECK-NEXT: ret i8 [[IV_RES]]1255;1256entry:1257 br label %loop1258 1259loop:1260 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]1261 %nbits = add nsw i8 %iv, %extraoffset1262 %val.shifted = shl i8 %val, %nbits1263 %val.shifted.iszero = icmp eq i8 %val.shifted, 01264 %iv.next = add i8 0, 1 ; should be adding to IV1265 1266 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1267 1268 br i1 %val.shifted.iszero, label %end, label %loop1269 1270end:1271 %iv.res = phi i8 [ %iv, %loop ]1272 %nbits.res = phi i8 [ %nbits, %loop ]1273 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1274 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1275 %iv.next.res = phi i8 [ %iv.next, %loop ]1276 1277 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1278 1279 ret i8 %iv.res1280}1281 1282; We should not just blindly look for add, we should look what IV actually uses.1283define i8 @n22(i8 %val, i8 %start, i8 %extraoffset) {1284; NOLZCNT-LABEL: @n22(1285; NOLZCNT-NEXT: entry:1286; NOLZCNT-NEXT: br label [[LOOP:%.*]]1287; NOLZCNT: loop:1288; NOLZCNT-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1289; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]1290; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL:%.*]], [[NBITS]]1291; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01292; NOLZCNT-NEXT: [[NOT_IV_NEXT:%.*]] = add i8 [[IV]], 11293; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 11294; NOLZCNT-NEXT: [[ALSO_IV_NEXT:%.*]] = add i8 [[IV]], 11295; NOLZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1296; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1297; NOLZCNT: end:1298; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1299; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1300; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1301; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1302; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1303; NOLZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1304; NOLZCNT-NEXT: ret i8 [[IV_RES]]1305;1306; LZCNT-LABEL: @n22(1307; LZCNT-NEXT: entry:1308; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.cttz.i8(i8 [[VAL:%.*]], i1 false)1309; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]1310; LZCNT-NEXT: [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]1311; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]1312; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])1313; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]1314; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 11315; LZCNT-NEXT: br label [[LOOP:%.*]]1316; LZCNT: loop:1317; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1318; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 11319; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1320; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]1321; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]1322; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]1323; LZCNT-NEXT: [[NOT_IV_NEXT:%.*]] = add i8 [[IV]], 11324; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 11325; LZCNT-NEXT: [[ALSO_IV_NEXT:%.*]] = add i8 [[IV]], 11326; LZCNT-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])1327; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1328; LZCNT: end:1329; LZCNT-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]1330; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1331; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1332; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1333; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1334; LZCNT-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1335; LZCNT-NEXT: ret i8 [[IV_RES]]1336;1337entry:1338 br label %loop1339 1340loop:1341 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]1342 %nbits = add nsw i8 %iv, %extraoffset1343 %val.shifted = shl i8 %val, %nbits1344 %val.shifted.iszero = icmp eq i8 %val.shifted, 01345 %not.iv.next = add i8 %iv, 1 ; not used by %iv1346 %iv.next = add i8 %iv, 11347 %also.iv.next = add i8 %iv, 1 ; not used by %iv1348 1349 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1350 1351 br i1 %val.shifted.iszero, label %end, label %loop1352 1353end:1354 %iv.res = phi i8 [ %iv, %loop ]1355 %nbits.res = phi i8 [ %nbits, %loop ]1356 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1357 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1358 %iv.next.res = phi i8 [ %iv.next, %loop ]1359 1360 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1361 1362 ret i8 %iv.res1363}1364 1365define i8 @n23(i8 %start, i8 %extraoffset) {1366; CHECK-LABEL: @n23(1367; CHECK-NEXT: entry:1368; CHECK-NEXT: br label [[LOOP:%.*]]1369; CHECK: loop:1370; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1371; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]1372; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen.i8()1373; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = shl i8 [[VAL]], [[NBITS]]1374; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 01375; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 11376; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])1377; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1378; CHECK: end:1379; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]1380; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]1381; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]1382; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1383; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]1384; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])1385; CHECK-NEXT: ret i8 [[IV_RES]]1386;1387entry:1388 br label %loop1389 1390loop:1391 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]1392 %nbits = add nsw i8 %iv, %extraoffset1393 %val = call i8 @gen.i8()1394 %val.shifted = shl i8 %val, %nbits1395 %val.shifted.iszero = icmp eq i8 %val.shifted, 01396 %iv.next = add i8 %iv, 11397 1398 call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)1399 1400 br i1 %val.shifted.iszero, label %end, label %loop1401 1402end:1403 %iv.res = phi i8 [ %iv, %loop ]1404 %nbits.res = phi i8 [ %nbits, %loop ]1405 %val.shifted.res = phi i8 [ %val.shifted, %loop ]1406 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1407 %iv.next.res = phi i8 [ %iv.next, %loop ]1408 1409 call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)1410 1411 ret i8 %iv.res1412}1413 1414; Tests with some small bit widths1415declare void @escape_inner.i1(i1, i1, i1, i1, i1)1416declare void @escape_outer.i1(i1, i1, i1, i1, i1)1417declare void @escape_inner.i2(i2, i2, i2, i1, i2)1418declare void @escape_outer.i2(i2, i2, i2, i1, i2)1419declare void @escape_inner.i3(i3, i3, i3, i1, i3)1420declare void @escape_outer.i3(i3, i3, i3, i1, i3)1421 1422define i1 @t24_nooffset_i1(i1 %val, i1 %start) {1423; NOLZCNT-LABEL: @t24_nooffset_i1(1424; NOLZCNT-NEXT: entry:1425; NOLZCNT-NEXT: br label [[LOOP:%.*]]1426; NOLZCNT: loop:1427; NOLZCNT-NEXT: [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1428; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL:%.*]], [[IV]]1429; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false1430; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true1431; NOLZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[IV]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])1432; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1433; NOLZCNT: end:1434; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]1435; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]1436; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1437; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]1438; NOLZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[IV_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])1439; NOLZCNT-NEXT: ret i1 [[IV_RES]]1440;1441; LZCNT-LABEL: @t24_nooffset_i1(1442; LZCNT-NEXT: entry:1443; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.cttz.i1(i1 [[VAL:%.*]], i1 false)1444; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]1445; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i1 [[VAL_NUMACTIVEBITS]], false1446; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])1447; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i1 [[IV_FINAL]], [[START]]1448; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true1449; LZCNT-NEXT: br label [[LOOP:%.*]]1450; LZCNT: loop:1451; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1452; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true1453; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1454; LZCNT-NEXT: [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]1455; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL]], [[IV]]1456; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true1457; LZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[IV]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])1458; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1459; LZCNT: end:1460; LZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]1461; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]1462; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1463; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]1464; LZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[IV_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])1465; LZCNT-NEXT: ret i1 [[IV_RES]]1466;1467entry:1468 br label %loop1469 1470loop:1471 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]1472 %val.shifted = shl i1 %val, %iv1473 %val.shifted.iszero = icmp eq i1 %val.shifted, 01474 %iv.next = add i1 %iv, 11475 1476 call void @escape_inner.i1(i1 %iv, i1 %iv, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)1477 1478 br i1 %val.shifted.iszero, label %end, label %loop1479 1480end:1481 %iv.res = phi i1 [ %iv, %loop ]1482 %val.shifted.res = phi i1 [ %val.shifted, %loop ]1483 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1484 %iv.next.res = phi i1 [ %iv.next, %loop ]1485 1486 call void @escape_outer.i1(i1 %iv.res, i1 %iv.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)1487 1488 ret i1 %iv.res1489}1490define i2 @t25_nooffset_i2(i2 %val, i2 %start) {1491; NOLZCNT-LABEL: @t25_nooffset_i2(1492; NOLZCNT-NEXT: entry:1493; NOLZCNT-NEXT: br label [[LOOP:%.*]]1494; NOLZCNT: loop:1495; NOLZCNT-NEXT: [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1496; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL:%.*]], [[IV]]1497; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 01498; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 11499; NOLZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[IV]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])1500; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1501; NOLZCNT: end:1502; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]1503; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]1504; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1505; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]1506; NOLZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[IV_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])1507; NOLZCNT-NEXT: ret i2 [[IV_RES]]1508;1509; LZCNT-LABEL: @t25_nooffset_i2(1510; LZCNT-NEXT: entry:1511; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.cttz.i2(i2 [[VAL:%.*]], i1 false)1512; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]1513; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i2 [[VAL_NUMACTIVEBITS]], 01514; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])1515; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i2 [[IV_FINAL]], [[START]]1516; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 11517; LZCNT-NEXT: br label [[LOOP:%.*]]1518; LZCNT: loop:1519; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1520; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 11521; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1522; LZCNT-NEXT: [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]1523; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL]], [[IV]]1524; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 11525; LZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[IV]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])1526; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1527; LZCNT: end:1528; LZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]1529; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]1530; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1531; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]1532; LZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[IV_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])1533; LZCNT-NEXT: ret i2 [[IV_RES]]1534;1535entry:1536 br label %loop1537 1538loop:1539 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]1540 %val.shifted = shl i2 %val, %iv1541 %val.shifted.iszero = icmp eq i2 %val.shifted, 01542 %iv.next = add i2 %iv, 11543 1544 call void @escape_inner.i2(i2 %iv, i2 %iv, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)1545 1546 br i1 %val.shifted.iszero, label %end, label %loop1547 1548end:1549 %iv.res = phi i2 [ %iv, %loop ]1550 %val.shifted.res = phi i2 [ %val.shifted, %loop ]1551 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1552 %iv.next.res = phi i2 [ %iv.next, %loop ]1553 1554 call void @escape_outer.i2(i2 %iv.res, i2 %iv.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)1555 1556 ret i2 %iv.res1557}1558define i3 @t26_nooffset_i3(i3 %val, i3 %start) {1559; NOLZCNT-LABEL: @t26_nooffset_i3(1560; NOLZCNT-NEXT: entry:1561; NOLZCNT-NEXT: br label [[LOOP:%.*]]1562; NOLZCNT: loop:1563; NOLZCNT-NEXT: [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1564; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL:%.*]], [[IV]]1565; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 01566; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 11567; NOLZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[IV]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])1568; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1569; NOLZCNT: end:1570; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]1571; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]1572; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1573; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]1574; NOLZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[IV_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])1575; NOLZCNT-NEXT: ret i3 [[IV_RES]]1576;1577; LZCNT-LABEL: @t26_nooffset_i3(1578; LZCNT-NEXT: entry:1579; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.cttz.i3(i3 [[VAL:%.*]], i1 false)1580; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]1581; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i3 [[VAL_NUMACTIVEBITS]], 01582; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])1583; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i3 [[IV_FINAL]], [[START]]1584; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 11585; LZCNT-NEXT: br label [[LOOP:%.*]]1586; LZCNT: loop:1587; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1588; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 11589; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1590; LZCNT-NEXT: [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]1591; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL]], [[IV]]1592; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 11593; LZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[IV]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])1594; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1595; LZCNT: end:1596; LZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]1597; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]1598; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1599; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]1600; LZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[IV_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])1601; LZCNT-NEXT: ret i3 [[IV_RES]]1602;1603entry:1604 br label %loop1605 1606loop:1607 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]1608 %val.shifted = shl i3 %val, %iv1609 %val.shifted.iszero = icmp eq i3 %val.shifted, 01610 %iv.next = add i3 %iv, 11611 1612 call void @escape_inner.i3(i3 %iv, i3 %iv, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)1613 1614 br i1 %val.shifted.iszero, label %end, label %loop1615 1616end:1617 %iv.res = phi i3 [ %iv, %loop ]1618 %val.shifted.res = phi i3 [ %val.shifted, %loop ]1619 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1620 %iv.next.res = phi i3 [ %iv.next, %loop ]1621 1622 call void @escape_outer.i3(i3 %iv.res, i3 %iv.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)1623 1624 ret i3 %iv.res1625}1626 1627define i1 @t27_addnsw_i1(i1 %val, i1 %start, i1 %extraoffset) {1628; NOLZCNT-LABEL: @t27_addnsw_i1(1629; NOLZCNT-NEXT: entry:1630; NOLZCNT-NEXT: br label [[LOOP:%.*]]1631; NOLZCNT: loop:1632; NOLZCNT-NEXT: [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1633; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i1 [[IV]], [[EXTRAOFFSET:%.*]]1634; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL:%.*]], [[NBITS]]1635; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false1636; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true1637; NOLZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])1638; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1639; NOLZCNT: end:1640; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]1641; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]1642; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]1643; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1644; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]1645; NOLZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])1646; NOLZCNT-NEXT: ret i1 [[IV_RES]]1647;1648; LZCNT-LABEL: @t27_addnsw_i1(1649; LZCNT-NEXT: entry:1650; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.cttz.i1(i1 [[VAL:%.*]], i1 false)1651; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]1652; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i1 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]1653; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])1654; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i1 [[IV_FINAL]], [[START]]1655; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true1656; LZCNT-NEXT: br label [[LOOP:%.*]]1657; LZCNT: loop:1658; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1659; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true1660; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1661; LZCNT-NEXT: [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]1662; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i1 [[IV]], [[EXTRAOFFSET]]1663; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL]], [[NBITS]]1664; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true1665; LZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])1666; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1667; LZCNT: end:1668; LZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]1669; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]1670; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]1671; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1672; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]1673; LZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])1674; LZCNT-NEXT: ret i1 [[IV_RES]]1675;1676entry:1677 br label %loop1678 1679loop:1680 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]1681 %nbits = add nsw i1 %iv, %extraoffset1682 %val.shifted = shl i1 %val, %nbits1683 %val.shifted.iszero = icmp eq i1 %val.shifted, 01684 %iv.next = add i1 %iv, 11685 1686 call void @escape_inner.i1(i1 %iv, i1 %nbits, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)1687 1688 br i1 %val.shifted.iszero, label %end, label %loop1689 1690end:1691 %iv.res = phi i1 [ %iv, %loop ]1692 %nbits.res = phi i1 [ %nbits, %loop ]1693 %val.shifted.res = phi i1 [ %val.shifted, %loop ]1694 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1695 %iv.next.res = phi i1 [ %iv.next, %loop ]1696 1697 call void @escape_outer.i1(i1 %iv.res, i1 %nbits.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)1698 1699 ret i1 %iv.res1700}1701define i2 @t28_addnsw_i2(i2 %val, i2 %start, i2 %extraoffset) {1702; NOLZCNT-LABEL: @t28_addnsw_i2(1703; NOLZCNT-NEXT: entry:1704; NOLZCNT-NEXT: br label [[LOOP:%.*]]1705; NOLZCNT: loop:1706; NOLZCNT-NEXT: [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1707; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i2 [[IV]], [[EXTRAOFFSET:%.*]]1708; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL:%.*]], [[NBITS]]1709; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 01710; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 11711; NOLZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])1712; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1713; NOLZCNT: end:1714; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]1715; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]1716; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]1717; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1718; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]1719; NOLZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])1720; NOLZCNT-NEXT: ret i2 [[IV_RES]]1721;1722; LZCNT-LABEL: @t28_addnsw_i2(1723; LZCNT-NEXT: entry:1724; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.cttz.i2(i2 [[VAL:%.*]], i1 false)1725; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]1726; LZCNT-NEXT: [[TMP0:%.*]] = sub i2 0, [[EXTRAOFFSET:%.*]]1727; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i2 [[VAL_NUMACTIVEBITS]], [[TMP0]]1728; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])1729; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i2 [[IV_FINAL]], [[START]]1730; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 11731; LZCNT-NEXT: br label [[LOOP:%.*]]1732; LZCNT: loop:1733; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1734; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 11735; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1736; LZCNT-NEXT: [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]1737; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i2 [[IV]], [[EXTRAOFFSET]]1738; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL]], [[NBITS]]1739; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 11740; LZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])1741; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1742; LZCNT: end:1743; LZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]1744; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]1745; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]1746; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1747; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]1748; LZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])1749; LZCNT-NEXT: ret i2 [[IV_RES]]1750;1751entry:1752 br label %loop1753 1754loop:1755 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]1756 %nbits = add nsw i2 %iv, %extraoffset1757 %val.shifted = shl i2 %val, %nbits1758 %val.shifted.iszero = icmp eq i2 %val.shifted, 01759 %iv.next = add i2 %iv, 11760 1761 call void @escape_inner.i2(i2 %iv, i2 %nbits, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)1762 1763 br i1 %val.shifted.iszero, label %end, label %loop1764 1765end:1766 %iv.res = phi i2 [ %iv, %loop ]1767 %nbits.res = phi i2 [ %nbits, %loop ]1768 %val.shifted.res = phi i2 [ %val.shifted, %loop ]1769 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1770 %iv.next.res = phi i2 [ %iv.next, %loop ]1771 1772 call void @escape_outer.i2(i2 %iv.res, i2 %nbits.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)1773 1774 ret i2 %iv.res1775}1776define i3 @t29_addnsw_i3(i3 %val, i3 %start, i3 %extraoffset) {1777; NOLZCNT-LABEL: @t29_addnsw_i3(1778; NOLZCNT-NEXT: entry:1779; NOLZCNT-NEXT: br label [[LOOP:%.*]]1780; NOLZCNT: loop:1781; NOLZCNT-NEXT: [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1782; NOLZCNT-NEXT: [[NBITS:%.*]] = add nsw i3 [[IV]], [[EXTRAOFFSET:%.*]]1783; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL:%.*]], [[NBITS]]1784; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 01785; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 11786; NOLZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])1787; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1788; NOLZCNT: end:1789; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]1790; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]1791; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]1792; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1793; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]1794; NOLZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])1795; NOLZCNT-NEXT: ret i3 [[IV_RES]]1796;1797; LZCNT-LABEL: @t29_addnsw_i3(1798; LZCNT-NEXT: entry:1799; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.cttz.i3(i3 [[VAL:%.*]], i1 false)1800; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]1801; LZCNT-NEXT: [[TMP0:%.*]] = sub i3 0, [[EXTRAOFFSET:%.*]]1802; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i3 [[VAL_NUMACTIVEBITS]], [[TMP0]]1803; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])1804; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i3 [[IV_FINAL]], [[START]]1805; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 11806; LZCNT-NEXT: br label [[LOOP:%.*]]1807; LZCNT: loop:1808; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1809; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 11810; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1811; LZCNT-NEXT: [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]1812; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i3 [[IV]], [[EXTRAOFFSET]]1813; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL]], [[NBITS]]1814; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 11815; LZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])1816; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1817; LZCNT: end:1818; LZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]1819; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]1820; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]1821; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1822; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]1823; LZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])1824; LZCNT-NEXT: ret i3 [[IV_RES]]1825;1826entry:1827 br label %loop1828 1829loop:1830 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]1831 %nbits = add nsw i3 %iv, %extraoffset1832 %val.shifted = shl i3 %val, %nbits1833 %val.shifted.iszero = icmp eq i3 %val.shifted, 01834 %iv.next = add i3 %iv, 11835 1836 call void @escape_inner.i3(i3 %iv, i3 %nbits, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)1837 1838 br i1 %val.shifted.iszero, label %end, label %loop1839 1840end:1841 %iv.res = phi i3 [ %iv, %loop ]1842 %nbits.res = phi i3 [ %nbits, %loop ]1843 %val.shifted.res = phi i3 [ %val.shifted, %loop ]1844 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1845 %iv.next.res = phi i3 [ %iv.next, %loop ]1846 1847 call void @escape_outer.i3(i3 %iv.res, i3 %nbits.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)1848 1849 ret i3 %iv.res1850}1851 1852define i1 @t30_addnuw_i1(i1 %val, i1 %start, i1 %extraoffset) {1853; NOLZCNT-LABEL: @t30_addnuw_i1(1854; NOLZCNT-NEXT: entry:1855; NOLZCNT-NEXT: br label [[LOOP:%.*]]1856; NOLZCNT: loop:1857; NOLZCNT-NEXT: [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1858; NOLZCNT-NEXT: [[NBITS:%.*]] = add nuw i1 [[IV]], [[EXTRAOFFSET:%.*]]1859; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL:%.*]], [[NBITS]]1860; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false1861; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true1862; NOLZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])1863; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1864; NOLZCNT: end:1865; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]1866; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]1867; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]1868; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1869; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]1870; NOLZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])1871; NOLZCNT-NEXT: ret i1 [[IV_RES]]1872;1873; LZCNT-LABEL: @t30_addnuw_i1(1874; LZCNT-NEXT: entry:1875; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.cttz.i1(i1 [[VAL:%.*]], i1 false)1876; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]1877; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i1 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]1878; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])1879; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i1 [[IV_FINAL]], [[START]]1880; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true1881; LZCNT-NEXT: br label [[LOOP:%.*]]1882; LZCNT: loop:1883; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1884; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true1885; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1886; LZCNT-NEXT: [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]1887; LZCNT-NEXT: [[NBITS:%.*]] = add nuw i1 [[IV]], [[EXTRAOFFSET]]1888; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL]], [[NBITS]]1889; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true1890; LZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])1891; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1892; LZCNT: end:1893; LZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]1894; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]1895; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]1896; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1897; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]1898; LZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])1899; LZCNT-NEXT: ret i1 [[IV_RES]]1900;1901entry:1902 br label %loop1903 1904loop:1905 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]1906 %nbits = add nuw i1 %iv, %extraoffset1907 %val.shifted = shl i1 %val, %nbits1908 %val.shifted.iszero = icmp eq i1 %val.shifted, 01909 %iv.next = add i1 %iv, 11910 1911 call void @escape_inner.i1(i1 %iv, i1 %nbits, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)1912 1913 br i1 %val.shifted.iszero, label %end, label %loop1914 1915end:1916 %iv.res = phi i1 [ %iv, %loop ]1917 %nbits.res = phi i1 [ %nbits, %loop ]1918 %val.shifted.res = phi i1 [ %val.shifted, %loop ]1919 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1920 %iv.next.res = phi i1 [ %iv.next, %loop ]1921 1922 call void @escape_outer.i1(i1 %iv.res, i1 %nbits.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)1923 1924 ret i1 %iv.res1925}1926define i2 @t31_addnuw_i2(i2 %val, i2 %start, i2 %extraoffset) {1927; NOLZCNT-LABEL: @t31_addnuw_i2(1928; NOLZCNT-NEXT: entry:1929; NOLZCNT-NEXT: br label [[LOOP:%.*]]1930; NOLZCNT: loop:1931; NOLZCNT-NEXT: [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1932; NOLZCNT-NEXT: [[NBITS:%.*]] = add nuw i2 [[IV]], [[EXTRAOFFSET:%.*]]1933; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL:%.*]], [[NBITS]]1934; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 01935; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 11936; NOLZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])1937; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]1938; NOLZCNT: end:1939; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]1940; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]1941; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]1942; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]1943; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]1944; NOLZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])1945; NOLZCNT-NEXT: ret i2 [[IV_RES]]1946;1947; LZCNT-LABEL: @t31_addnuw_i2(1948; LZCNT-NEXT: entry:1949; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.cttz.i2(i2 [[VAL:%.*]], i1 false)1950; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]1951; LZCNT-NEXT: [[TMP0:%.*]] = sub i2 0, [[EXTRAOFFSET:%.*]]1952; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i2 [[VAL_NUMACTIVEBITS]], [[TMP0]]1953; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])1954; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i2 [[IV_FINAL]], [[START]]1955; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 11956; LZCNT-NEXT: br label [[LOOP:%.*]]1957; LZCNT: loop:1958; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]1959; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 11960; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]1961; LZCNT-NEXT: [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]1962; LZCNT-NEXT: [[NBITS:%.*]] = add nuw i2 [[IV]], [[EXTRAOFFSET]]1963; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL]], [[NBITS]]1964; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 11965; LZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])1966; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]1967; LZCNT: end:1968; LZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]1969; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]1970; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]1971; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]1972; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]1973; LZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])1974; LZCNT-NEXT: ret i2 [[IV_RES]]1975;1976entry:1977 br label %loop1978 1979loop:1980 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]1981 %nbits = add nuw i2 %iv, %extraoffset1982 %val.shifted = shl i2 %val, %nbits1983 %val.shifted.iszero = icmp eq i2 %val.shifted, 01984 %iv.next = add i2 %iv, 11985 1986 call void @escape_inner.i2(i2 %iv, i2 %nbits, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)1987 1988 br i1 %val.shifted.iszero, label %end, label %loop1989 1990end:1991 %iv.res = phi i2 [ %iv, %loop ]1992 %nbits.res = phi i2 [ %nbits, %loop ]1993 %val.shifted.res = phi i2 [ %val.shifted, %loop ]1994 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]1995 %iv.next.res = phi i2 [ %iv.next, %loop ]1996 1997 call void @escape_outer.i2(i2 %iv.res, i2 %nbits.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)1998 1999 ret i2 %iv.res2000}2001define i3 @t32_addnuw_i3(i3 %val, i3 %start, i3 %extraoffset) {2002; NOLZCNT-LABEL: @t32_addnuw_i3(2003; NOLZCNT-NEXT: entry:2004; NOLZCNT-NEXT: br label [[LOOP:%.*]]2005; NOLZCNT: loop:2006; NOLZCNT-NEXT: [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]2007; NOLZCNT-NEXT: [[NBITS:%.*]] = add nuw i3 [[IV]], [[EXTRAOFFSET:%.*]]2008; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL:%.*]], [[NBITS]]2009; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 02010; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 12011; NOLZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])2012; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]2013; NOLZCNT: end:2014; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]2015; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]2016; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]2017; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]2018; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]2019; NOLZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])2020; NOLZCNT-NEXT: ret i3 [[IV_RES]]2021;2022; LZCNT-LABEL: @t32_addnuw_i3(2023; LZCNT-NEXT: entry:2024; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.cttz.i3(i3 [[VAL:%.*]], i1 false)2025; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]2026; LZCNT-NEXT: [[TMP0:%.*]] = sub i3 0, [[EXTRAOFFSET:%.*]]2027; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i3 [[VAL_NUMACTIVEBITS]], [[TMP0]]2028; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])2029; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i3 [[IV_FINAL]], [[START]]2030; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 12031; LZCNT-NEXT: br label [[LOOP:%.*]]2032; LZCNT: loop:2033; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]2034; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 12035; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]2036; LZCNT-NEXT: [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]2037; LZCNT-NEXT: [[NBITS:%.*]] = add nuw i3 [[IV]], [[EXTRAOFFSET]]2038; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL]], [[NBITS]]2039; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 12040; LZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])2041; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]2042; LZCNT: end:2043; LZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]2044; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]2045; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]2046; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]2047; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]2048; LZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])2049; LZCNT-NEXT: ret i3 [[IV_RES]]2050;2051entry:2052 br label %loop2053 2054loop:2055 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]2056 %nbits = add nuw i3 %iv, %extraoffset2057 %val.shifted = shl i3 %val, %nbits2058 %val.shifted.iszero = icmp eq i3 %val.shifted, 02059 %iv.next = add i3 %iv, 12060 2061 call void @escape_inner.i3(i3 %iv, i3 %nbits, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)2062 2063 br i1 %val.shifted.iszero, label %end, label %loop2064 2065end:2066 %iv.res = phi i3 [ %iv, %loop ]2067 %nbits.res = phi i3 [ %nbits, %loop ]2068 %val.shifted.res = phi i3 [ %val.shifted, %loop ]2069 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]2070 %iv.next.res = phi i3 [ %iv.next, %loop ]2071 2072 call void @escape_outer.i3(i3 %iv.res, i3 %nbits.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)2073 2074 ret i3 %iv.res2075}2076 2077 2078define i1 @t33_subnsw_i1(i1 %val, i1 %start, i1 %extraoffset) {2079; NOLZCNT-LABEL: @t33_subnsw_i1(2080; NOLZCNT-NEXT: entry:2081; NOLZCNT-NEXT: br label [[LOOP:%.*]]2082; NOLZCNT: loop:2083; NOLZCNT-NEXT: [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]2084; NOLZCNT-NEXT: [[NBITS:%.*]] = sub nsw i1 [[IV]], [[EXTRAOFFSET:%.*]]2085; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL:%.*]], [[NBITS]]2086; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false2087; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true2088; NOLZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])2089; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]2090; NOLZCNT: end:2091; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]2092; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]2093; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]2094; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]2095; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]2096; NOLZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])2097; NOLZCNT-NEXT: ret i1 [[IV_RES]]2098;2099; LZCNT-LABEL: @t33_subnsw_i1(2100; LZCNT-NEXT: entry:2101; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.cttz.i1(i1 [[VAL:%.*]], i1 false)2102; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]2103; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i1 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]2104; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])2105; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i1 [[IV_FINAL]], [[START]]2106; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true2107; LZCNT-NEXT: br label [[LOOP:%.*]]2108; LZCNT: loop:2109; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]2110; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true2111; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]2112; LZCNT-NEXT: [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]2113; LZCNT-NEXT: [[NBITS:%.*]] = sub nsw i1 [[IV]], [[EXTRAOFFSET]]2114; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i1 [[VAL]], [[NBITS]]2115; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true2116; LZCNT-NEXT: call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])2117; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]2118; LZCNT: end:2119; LZCNT-NEXT: [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]2120; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]2121; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]2122; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]2123; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]2124; LZCNT-NEXT: call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])2125; LZCNT-NEXT: ret i1 [[IV_RES]]2126;2127entry:2128 br label %loop2129 2130loop:2131 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]2132 %nbits = sub nsw i1 %iv, %extraoffset2133 %val.shifted = shl i1 %val, %nbits2134 %val.shifted.iszero = icmp eq i1 %val.shifted, 02135 %iv.next = add i1 %iv, 12136 2137 call void @escape_inner.i1(i1 %iv, i1 %nbits, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)2138 2139 br i1 %val.shifted.iszero, label %end, label %loop2140 2141end:2142 %iv.res = phi i1 [ %iv, %loop ]2143 %nbits.res = phi i1 [ %nbits, %loop ]2144 %val.shifted.res = phi i1 [ %val.shifted, %loop ]2145 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]2146 %iv.next.res = phi i1 [ %iv.next, %loop ]2147 2148 call void @escape_outer.i1(i1 %iv.res, i1 %nbits.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)2149 2150 ret i1 %iv.res2151}2152define i2 @t34_addnuw_i2(i2 %val, i2 %start, i2 %extraoffset) {2153; NOLZCNT-LABEL: @t34_addnuw_i2(2154; NOLZCNT-NEXT: entry:2155; NOLZCNT-NEXT: br label [[LOOP:%.*]]2156; NOLZCNT: loop:2157; NOLZCNT-NEXT: [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]2158; NOLZCNT-NEXT: [[NBITS:%.*]] = sub nsw i2 [[IV]], [[EXTRAOFFSET:%.*]]2159; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL:%.*]], [[NBITS]]2160; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 02161; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 12162; NOLZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])2163; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]2164; NOLZCNT: end:2165; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]2166; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]2167; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]2168; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]2169; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]2170; NOLZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])2171; NOLZCNT-NEXT: ret i2 [[IV_RES]]2172;2173; LZCNT-LABEL: @t34_addnuw_i2(2174; LZCNT-NEXT: entry:2175; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.cttz.i2(i2 [[VAL:%.*]], i1 false)2176; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]2177; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i2 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]2178; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])2179; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i2 [[IV_FINAL]], [[START]]2180; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 12181; LZCNT-NEXT: br label [[LOOP:%.*]]2182; LZCNT: loop:2183; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]2184; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 12185; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]2186; LZCNT-NEXT: [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]2187; LZCNT-NEXT: [[NBITS:%.*]] = sub nsw i2 [[IV]], [[EXTRAOFFSET]]2188; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i2 [[VAL]], [[NBITS]]2189; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 12190; LZCNT-NEXT: call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])2191; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]2192; LZCNT: end:2193; LZCNT-NEXT: [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]2194; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]2195; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]2196; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]2197; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]2198; LZCNT-NEXT: call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])2199; LZCNT-NEXT: ret i2 [[IV_RES]]2200;2201entry:2202 br label %loop2203 2204loop:2205 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]2206 %nbits = sub nsw i2 %iv, %extraoffset2207 %val.shifted = shl i2 %val, %nbits2208 %val.shifted.iszero = icmp eq i2 %val.shifted, 02209 %iv.next = add i2 %iv, 12210 2211 call void @escape_inner.i2(i2 %iv, i2 %nbits, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)2212 2213 br i1 %val.shifted.iszero, label %end, label %loop2214 2215end:2216 %iv.res = phi i2 [ %iv, %loop ]2217 %nbits.res = phi i2 [ %nbits, %loop ]2218 %val.shifted.res = phi i2 [ %val.shifted, %loop ]2219 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]2220 %iv.next.res = phi i2 [ %iv.next, %loop ]2221 2222 call void @escape_outer.i2(i2 %iv.res, i2 %nbits.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)2223 2224 ret i2 %iv.res2225}2226define i3 @t35_addnuw_i3(i3 %val, i3 %start, i3 %extraoffset) {2227; NOLZCNT-LABEL: @t35_addnuw_i3(2228; NOLZCNT-NEXT: entry:2229; NOLZCNT-NEXT: br label [[LOOP:%.*]]2230; NOLZCNT: loop:2231; NOLZCNT-NEXT: [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]2232; NOLZCNT-NEXT: [[NBITS:%.*]] = sub nsw i3 [[IV]], [[EXTRAOFFSET:%.*]]2233; NOLZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL:%.*]], [[NBITS]]2234; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 02235; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 12236; NOLZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])2237; NOLZCNT-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]2238; NOLZCNT: end:2239; NOLZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]2240; NOLZCNT-NEXT: [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]2241; NOLZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]2242; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]2243; NOLZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]2244; NOLZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])2245; NOLZCNT-NEXT: ret i3 [[IV_RES]]2246;2247; LZCNT-LABEL: @t35_addnuw_i3(2248; LZCNT-NEXT: entry:2249; LZCNT-NEXT: [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.cttz.i3(i3 [[VAL:%.*]], i1 false)2250; LZCNT-NEXT: [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]2251; LZCNT-NEXT: [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i3 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]2252; LZCNT-NEXT: [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])2253; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i3 [[IV_FINAL]], [[START]]2254; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 12255; LZCNT-NEXT: br label [[LOOP:%.*]]2256; LZCNT: loop:2257; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]2258; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 12259; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]2260; LZCNT-NEXT: [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]2261; LZCNT-NEXT: [[NBITS:%.*]] = sub nsw i3 [[IV]], [[EXTRAOFFSET]]2262; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = shl i3 [[VAL]], [[NBITS]]2263; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 12264; LZCNT-NEXT: call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])2265; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]2266; LZCNT: end:2267; LZCNT-NEXT: [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]2268; LZCNT-NEXT: [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]2269; LZCNT-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]2270; LZCNT-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]2271; LZCNT-NEXT: [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]2272; LZCNT-NEXT: call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])2273; LZCNT-NEXT: ret i3 [[IV_RES]]2274;2275entry:2276 br label %loop2277 2278loop:2279 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]2280 %nbits = sub nsw i3 %iv, %extraoffset2281 %val.shifted = shl i3 %val, %nbits2282 %val.shifted.iszero = icmp eq i3 %val.shifted, 02283 %iv.next = add i3 %iv, 12284 2285 call void @escape_inner.i3(i3 %iv, i3 %nbits, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)2286 2287 br i1 %val.shifted.iszero, label %end, label %loop2288 2289end:2290 %iv.res = phi i3 [ %iv, %loop ]2291 %nbits.res = phi i3 [ %nbits, %loop ]2292 %val.shifted.res = phi i3 [ %val.shifted, %loop ]2293 %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]2294 %iv.next.res = phi i3 [ %iv.next, %loop ]2295 2296 call void @escape_outer.i3(i3 %iv.res, i3 %nbits.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)2297 2298 ret i3 %iv.res2299}2300