1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mcpu=corei7 < %s -S | FileCheck %s --check-prefixes=CHECK,NOLZCNT 3; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mcpu=core-avx2 < %s -S | FileCheck %s --check-prefixes=CHECK,LZCNT 4 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 offsetting 11; 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 20; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 21; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 22; 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.ctlz.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]], 1 42; 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]], 1 46; 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:%.*]] = lshr i8 [[VAL]], [[NBITS]] 50; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 51; 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 %loop 64 65loop: 66 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 67 %nbits = add nsw i8 %iv, %extraoffset 68 %val.shifted = lshr i8 %val, %nbits 69 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 70 %iv.next = add i8 %iv, 1 71 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 %loop 75 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.res 86} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 97; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 98; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 99; 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.ctlz.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]], 1 119; 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]], 1 123; 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:%.*]] = lshr i8 [[VAL]], [[NBITS]] 127; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 128; 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 %loop 141 142loop: 143 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 144 %nbits = add nuw i8 %iv, %extraoffset 145 %val.shifted = lshr i8 %val, %nbits 146 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 147 %iv.next = add i8 %iv, 1 148 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 %loop 152 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.res 163} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 174; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 175; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 176; 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.ctlz.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]], 1 195; 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]], 1 199; 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:%.*]] = lshr i8 [[VAL]], [[NBITS]] 203; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 204; 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 %loop 217 218loop: 219 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 220 %nbits = sub nsw i8 %iv, %extraoffset 221 %val.shifted = lshr i8 %val, %nbits 222 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 223 %iv.next = add i8 %iv, 1 224 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 %loop 228 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.res 239} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 250; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 251; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 252; 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 %loop 265 266loop: 267 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 268 %nbits = sub nuw i8 %iv, %extraoffset 269 %val.shifted = lshr i8 %val, %nbits 270 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 271 %iv.next = add i8 %iv, 1 272 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 %loop 276 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.res 287} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 298; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 299; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 300; 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 %loop 313 314loop: 315 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 316 %nbits = sub i8 %iv, %extraoffset 317 %val.shifted = lshr i8 %val, %nbits 318 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 319 %iv.next = add i8 %iv, 1 320 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 %loop 324 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.res 335} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 346; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 347; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 348; 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 %loop 361 362loop: 363 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 364 %nbits = add i8 %iv, %extraoffset 365 %val.shifted = lshr i8 %val, %nbits 366 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 367 %iv.next = add i8 %iv, 1 368 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 %loop 372 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.res 383} 384 385; Of course, we don't have to have an offset 386define 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:%.*]] = lshr i8 [[VAL:%.*]], [[IV]] 393; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 394; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 395; 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.ctlz.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]], 0 410; 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]], 1 413; 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]], 1 417; 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:%.*]] = lshr i8 [[VAL]], [[IV]] 420; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 421; 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 %loop 433 434loop: 435 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 436 %val.shifted = lshr i8 %val, %iv 437 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 438 %iv.next = add i8 %iv, 1 439 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 %loop 443 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.res 453} 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 also 459define 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:%.*]] = lshr i7 [[VAL:%.*]], [[NBITS]] 467; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i7 [[VAL_SHIFTED]], 0 468; NOLZCNT-NEXT: [[IV_NEXT]] = add i7 [[IV]], 1 469; 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.ctlz.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]], 1 489; 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]], 1 493; 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:%.*]] = lshr i7 [[VAL]], [[NBITS]] 497; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i7 [[IV]], 1 498; 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 %loop 511 512loop: 513 %iv = phi i7 [ %start, %entry ], [ %iv.next, %loop ] 514 %nbits = add nsw i7 %iv, %extraoffset 515 %val.shifted = lshr i7 %val, %nbits 516 %val.shifted.iszero = icmp eq i7 %val.shifted, 0 517 %iv.next = add i7 %iv, 1 518 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 %loop 522 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.res 533} 534 535; Step must be 1 536define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 544; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 545; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 2 546; 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 %loop 559 560loop: 561 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 562 %nbits = add nsw i8 %iv, %extraoffset 563 %val.shifted = lshr i8 %val, %nbits 564 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 565 %iv.next = add i8 %iv, 2 ; not 1 566 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 %loop 570 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.res 581} 582 583; Cmp-br are commutable 584define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 592; NOLZCNT-NEXT: [[VAL_SHIFTED_ISNOTZERO:%.*]] = icmp ne i8 [[VAL_SHIFTED]], 0 593; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 594; 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.ctlz.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]], 1 614; 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]], 1 618; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]] 619; LZCNT-NEXT: [[VAL_SHIFTED_ISNOTZERO:%.*]] = xor i1 [[LOOP_IVCHECK]], true 620; LZCNT-NEXT: [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]] 621; LZCNT-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]] 622; LZCNT-NEXT: [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]] 623; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 624; 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 %loop 637 638loop: 639 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 640 %nbits = add nsw i8 %iv, %extraoffset 641 %val.shifted = lshr i8 %val, %nbits 642 %val.shifted.isnotzero = icmp ne i8 %val.shifted, 0 643 %iv.next = add i8 %iv, 1 644 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 %end 648 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.res 659} 660 661; We want to exit once it becomes zero 662define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 670; CHECK-NEXT: [[VAL_SHIFTED_ISNOTZERO:%.*]] = icmp ne i8 [[VAL_SHIFTED]], 0 671; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 672; 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 %loop 685 686loop: 687 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 688 %nbits = add nsw i8 %iv, %extraoffset 689 %val.shifted = lshr i8 %val, %nbits 690 %val.shifted.isnotzero = icmp ne i8 %val.shifted, 0 ; not eq 691 %iv.next = add i8 %iv, 1 692 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 %loop 696 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.res 707} 708 709; Once it compares zero, we want to exit, not exit when it compares non-zero 710define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 718; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 719; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 720; 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 %loop 733 734loop: 735 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 736 %nbits = add nsw i8 %iv, %extraoffset 737 %val.shifted = lshr i8 %val, %nbits 738 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 739 %iv.next = add i8 %iv, 1 740 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 destinations 744 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.res 755} 756 757; We must be comparing with 0 758define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 766; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 1 767; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 768; 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 %loop 781 782loop: 783 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 784 %nbits = add nsw i8 %iv, %extraoffset 785 %val.shifted = lshr i8 %val, %nbits 786 %val.shifted.iszero = icmp eq i8 %val.shifted, 1 ; not 0 787 %iv.next = add i8 %iv, 1 788 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 %loop 792 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.res 803} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 816; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 817; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 818; 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 %loop 831 832loop: 833 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop.end ] 834 br label %loop.end 835 836loop.end: 837 %nbits = add nsw i8 %iv, %extraoffset 838 %val.shifted = lshr i8 %val, %nbits 839 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 840 %iv.next = add i8 %iv, 1 841 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 %loop 845 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.res 856} 857 858; The comparison must have an equality predicate 859define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 867; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp ult i8 [[VAL_SHIFTED]], 1 868; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 869; 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 %loop 882 883loop: 884 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 885 %nbits = add nsw i8 %iv, %extraoffset 886 %val.shifted = lshr i8 %val, %nbits 887 %val.shifted.iszero = icmp ult i8 %val.shifted, 1 ; not `==0` 888 %iv.next = add i8 %iv, 1 889 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 %loop 893 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.res 904} 905 906; offset computation can be commuted 907define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 915; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 916; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 917; 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.ctlz.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]], 1 937; 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]], 1 941; 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:%.*]] = lshr i8 [[VAL]], [[NBITS]] 945; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 946; 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 %loop 959 960loop: 961 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 962 %nbits = add nsw i8 %extraoffset, %iv ; swapped order 963 %val.shifted = lshr i8 %val, %nbits 964 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 965 %iv.next = add i8 %iv, 1 966 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 %loop 970 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.res 981} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 992; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 993; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 994; 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 %loop 1007 1008loop: 1009 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 1010 %nbits = sub nsw i8 %extraoffset, %iv 1011 %val.shifted = lshr i8 %val, %nbits 1012 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1013 %iv.next = add i8 %iv, 1 1014 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 %loop 1018 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.res 1029} 1030 1031; The offset must be loop-invariant 1032define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 1041; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1042; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 1043; 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 %loop 1056 1057loop: 1058 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 1059 %extraoffset = call i8 @gen.i8() 1060 %nbits = add nsw i8 %iv, %extraoffset 1061 %val.shifted = lshr i8 %val, %nbits 1062 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1063 %iv.next = add i8 %iv, 1 1064 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 %loop 1068 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.res 1079} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 1091; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1092; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 1093; 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 %loop 1106 1107loop: 1108 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 1109 %extraoffset = call i8 @gen.i8() 1110 %nbits = sub nsw i8 %iv, %extraoffset 1111 %val.shifted = lshr i8 %val, %nbits 1112 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1113 %iv.next = add i8 %iv, 1 1114 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 %loop 1118 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.res 1129} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 1143; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1144; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 1145; 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.preheader 1158 1159loop.preheader: 1160 %notiv = phi i8 [ 0, %entry ] 1161 br label %loop 1162 1163loop: 1164 %iv = phi i8 [ %start, %loop.preheader ], [ %iv.next, %loop ] 1165 %nbits = add nsw i8 %notiv, %extraoffset ; uses %notiv instead of %iv 1166 %val.shifted = lshr i8 %val, %nbits 1167 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1168 %iv.next = add i8 %iv, 1 1169 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 %loop 1173 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.res 1184} 1185 1186; IV must really be a PHI 1187define 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, 0 1193; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]] 1194; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 1195; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1196; CHECK-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 1197; 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 %loop 1210 1211loop: 1212 %iv = add i8 0, 0 ; again not IV 1213 %nbits = add nsw i8 %iv, %extraoffset 1214 %val.shifted = lshr i8 %val, %nbits 1215 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1216 %iv.next = add i8 %iv, 1 1217 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 %loop 1221 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.res 1232} 1233 1234; The induction should be actually increasing IV 1235define 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 1243; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1244; CHECK-NEXT: [[IV_NEXT]] = add i8 0, 1 1245; 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 %loop 1258 1259loop: 1260 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 1261 %nbits = add nsw i8 %iv, %extraoffset 1262 %val.shifted = lshr i8 %val, %nbits 1263 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1264 %iv.next = add i8 0, 1 ; should be adding to IV 1265 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 %loop 1269 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.res 1280} 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:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]] 1291; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1292; NOLZCNT-NEXT: [[NOT_IV_NEXT:%.*]] = add i8 [[IV]], 1 1293; NOLZCNT-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 1294; NOLZCNT-NEXT: [[ALSO_IV_NEXT:%.*]] = add i8 [[IV]], 1 1295; 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.ctlz.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]], 1 1315; 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]], 1 1319; 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:%.*]] = lshr i8 [[VAL]], [[NBITS]] 1323; LZCNT-NEXT: [[NOT_IV_NEXT:%.*]] = add i8 [[IV]], 1 1324; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i8 [[IV]], 1 1325; LZCNT-NEXT: [[ALSO_IV_NEXT:%.*]] = add i8 [[IV]], 1 1326; 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 %loop 1339 1340loop: 1341 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 1342 %nbits = add nsw i8 %iv, %extraoffset 1343 %val.shifted = lshr i8 %val, %nbits 1344 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1345 %not.iv.next = add i8 %iv, 1 ; not used by %iv 1346 %iv.next = add i8 %iv, 1 1347 %also.iv.next = add i8 %iv, 1 ; not used by %iv 1348 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 %loop 1352 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.res 1363} 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:%.*]] = lshr i8 [[VAL]], [[NBITS]] 1374; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0 1375; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 1376; 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 %loop 1389 1390loop: 1391 %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ] 1392 %nbits = add nsw i8 %iv, %extraoffset 1393 %val = call i8 @gen.i8() 1394 %val.shifted = lshr i8 %val, %nbits 1395 %val.shifted.iszero = icmp eq i8 %val.shifted, 0 1396 %iv.next = add i8 %iv, 1 1397 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 %loop 1401 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.res 1412} 1413 1414; Tests with some small bit widths 1415declare 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:%.*]] = lshr i1 [[VAL:%.*]], [[IV]] 1429; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false 1430; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true 1431; 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.ctlz.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]], false 1446; 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]], true 1449; 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]], true 1453; 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:%.*]] = lshr i1 [[VAL]], [[IV]] 1456; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true 1457; 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 %loop 1469 1470loop: 1471 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ] 1472 %val.shifted = lshr i1 %val, %iv 1473 %val.shifted.iszero = icmp eq i1 %val.shifted, 0 1474 %iv.next = add i1 %iv, 1 1475 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 %loop 1479 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.res 1489} 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:%.*]] = lshr i2 [[VAL:%.*]], [[IV]] 1497; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0 1498; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 1 1499; 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.ctlz.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]], 0 1514; 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]], 1 1517; 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]], 1 1521; 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:%.*]] = lshr i2 [[VAL]], [[IV]] 1524; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 1 1525; 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 %loop 1537 1538loop: 1539 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ] 1540 %val.shifted = lshr i2 %val, %iv 1541 %val.shifted.iszero = icmp eq i2 %val.shifted, 0 1542 %iv.next = add i2 %iv, 1 1543 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 %loop 1547 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.res 1557} 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:%.*]] = lshr i3 [[VAL:%.*]], [[IV]] 1565; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0 1566; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 1 1567; 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.ctlz.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]], 0 1582; 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]], 1 1585; 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]], 1 1589; 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:%.*]] = lshr i3 [[VAL]], [[IV]] 1592; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 1 1593; 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 %loop 1605 1606loop: 1607 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ] 1608 %val.shifted = lshr i3 %val, %iv 1609 %val.shifted.iszero = icmp eq i3 %val.shifted, 0 1610 %iv.next = add i3 %iv, 1 1611 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 %loop 1615 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.res 1625} 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:%.*]] = lshr i1 [[VAL:%.*]], [[NBITS]] 1635; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false 1636; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true 1637; 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.ctlz.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]], true 1656; 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]], true 1660; 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:%.*]] = lshr i1 [[VAL]], [[NBITS]] 1664; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true 1665; 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 %loop 1678 1679loop: 1680 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ] 1681 %nbits = add nsw i1 %iv, %extraoffset 1682 %val.shifted = lshr i1 %val, %nbits 1683 %val.shifted.iszero = icmp eq i1 %val.shifted, 0 1684 %iv.next = add i1 %iv, 1 1685 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 %loop 1689 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.res 1700} 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:%.*]] = lshr i2 [[VAL:%.*]], [[NBITS]] 1709; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0 1710; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 1 1711; 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.ctlz.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]], 1 1731; 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]], 1 1735; 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:%.*]] = lshr i2 [[VAL]], [[NBITS]] 1739; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 1 1740; 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 %loop 1753 1754loop: 1755 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ] 1756 %nbits = add nsw i2 %iv, %extraoffset 1757 %val.shifted = lshr i2 %val, %nbits 1758 %val.shifted.iszero = icmp eq i2 %val.shifted, 0 1759 %iv.next = add i2 %iv, 1 1760 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 %loop 1764 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.res 1775} 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:%.*]] = lshr i3 [[VAL:%.*]], [[NBITS]] 1784; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0 1785; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 1 1786; 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.ctlz.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]], 1 1806; 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]], 1 1810; 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:%.*]] = lshr i3 [[VAL]], [[NBITS]] 1814; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 1 1815; 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 %loop 1828 1829loop: 1830 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ] 1831 %nbits = add nsw i3 %iv, %extraoffset 1832 %val.shifted = lshr i3 %val, %nbits 1833 %val.shifted.iszero = icmp eq i3 %val.shifted, 0 1834 %iv.next = add i3 %iv, 1 1835 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 %loop 1839 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.res 1850} 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:%.*]] = lshr i1 [[VAL:%.*]], [[NBITS]] 1860; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false 1861; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true 1862; 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.ctlz.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]], true 1881; 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]], true 1885; 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:%.*]] = lshr i1 [[VAL]], [[NBITS]] 1889; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true 1890; 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 %loop 1903 1904loop: 1905 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ] 1906 %nbits = add nuw i1 %iv, %extraoffset 1907 %val.shifted = lshr i1 %val, %nbits 1908 %val.shifted.iszero = icmp eq i1 %val.shifted, 0 1909 %iv.next = add i1 %iv, 1 1910 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 %loop 1914 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.res 1925} 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:%.*]] = lshr i2 [[VAL:%.*]], [[NBITS]] 1934; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0 1935; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 1 1936; 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.ctlz.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]], 1 1956; 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]], 1 1960; 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:%.*]] = lshr i2 [[VAL]], [[NBITS]] 1964; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 1 1965; 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 %loop 1978 1979loop: 1980 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ] 1981 %nbits = add nuw i2 %iv, %extraoffset 1982 %val.shifted = lshr i2 %val, %nbits 1983 %val.shifted.iszero = icmp eq i2 %val.shifted, 0 1984 %iv.next = add i2 %iv, 1 1985 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 %loop 1989 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.res 2000} 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:%.*]] = lshr i3 [[VAL:%.*]], [[NBITS]] 2009; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0 2010; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 1 2011; 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.ctlz.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]], 1 2031; 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]], 1 2035; 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:%.*]] = lshr i3 [[VAL]], [[NBITS]] 2039; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 1 2040; 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 %loop 2053 2054loop: 2055 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ] 2056 %nbits = add nuw i3 %iv, %extraoffset 2057 %val.shifted = lshr i3 %val, %nbits 2058 %val.shifted.iszero = icmp eq i3 %val.shifted, 0 2059 %iv.next = add i3 %iv, 1 2060 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 %loop 2064 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.res 2075} 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:%.*]] = lshr i1 [[VAL:%.*]], [[NBITS]] 2086; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false 2087; NOLZCNT-NEXT: [[IV_NEXT]] = add i1 [[IV]], true 2088; 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.ctlz.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]], true 2107; 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]], true 2111; 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:%.*]] = lshr i1 [[VAL]], [[NBITS]] 2115; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i1 [[IV]], true 2116; 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 %loop 2129 2130loop: 2131 %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ] 2132 %nbits = sub nsw i1 %iv, %extraoffset 2133 %val.shifted = lshr i1 %val, %nbits 2134 %val.shifted.iszero = icmp eq i1 %val.shifted, 0 2135 %iv.next = add i1 %iv, 1 2136 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 %loop 2140 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.res 2151} 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:%.*]] = lshr i2 [[VAL:%.*]], [[NBITS]] 2160; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0 2161; NOLZCNT-NEXT: [[IV_NEXT]] = add i2 [[IV]], 1 2162; 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.ctlz.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]], 1 2181; 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]], 1 2185; 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:%.*]] = lshr i2 [[VAL]], [[NBITS]] 2189; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i2 [[IV]], 1 2190; 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 %loop 2203 2204loop: 2205 %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ] 2206 %nbits = sub nsw i2 %iv, %extraoffset 2207 %val.shifted = lshr i2 %val, %nbits 2208 %val.shifted.iszero = icmp eq i2 %val.shifted, 0 2209 %iv.next = add i2 %iv, 1 2210 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 %loop 2214 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.res 2225} 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:%.*]] = lshr i3 [[VAL:%.*]], [[NBITS]] 2234; NOLZCNT-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0 2235; NOLZCNT-NEXT: [[IV_NEXT]] = add i3 [[IV]], 1 2236; 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.ctlz.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]], 1 2255; 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]], 1 2259; 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:%.*]] = lshr i3 [[VAL]], [[NBITS]] 2263; LZCNT-NEXT: [[IV_NEXT:%.*]] = add i3 [[IV]], 1 2264; 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 %loop 2277 2278loop: 2279 %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ] 2280 %nbits = sub nsw i3 %iv, %extraoffset 2281 %val.shifted = lshr i3 %val, %nbits 2282 %val.shifted.iszero = icmp eq i3 %val.shifted, 0 2283 %iv.next = add i3 %iv, 1 2284 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 %loop 2288 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.res 2299} 2300