572 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 62; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \3; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s4 5; for (int i = 0; i < n; i++)6; a[i] = 0;7;8define void @single_loop_nsw(ptr %a, i64 %n) {9; CHECK-LABEL: 'single_loop_nsw'10; CHECK-NEXT: Monotonicity check:11; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 112; CHECK-NEXT: Expr: {0,+,1}<nuw><nsw><%loop>13; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic14; CHECK-EMPTY:15; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 116; CHECK-NEXT: da analyze - none!17;18entry:19 %guard = icmp sgt i64 %n, 020 br i1 %guard, label %loop, label %exit21 22loop:23 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ]24 %idx = getelementptr inbounds i8, ptr %a, i64 %i25 store i8 0, ptr %idx26 %i.inc = add nsw i64 %i, 127 %exitcond = icmp eq i64 %i.inc, %n28 br i1 %exitcond, label %exit, label %loop29 30exit:31 ret void32}33 34; The purpose of the variable `begin` is to avoid violating the size limitation35; of the allocated object in LLVM IR, which would cause UB.36;37; for (unsigned long long i = begin; i < end; i++)38; a[i] = 0;39;40define void @single_loop_nuw(ptr %a, i64 %begin, i64 %end) {41; CHECK-LABEL: 'single_loop_nuw'42; CHECK-NEXT: Monotonicity check:43; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 144; CHECK-NEXT: Expr: {%begin,+,1}<nuw><%loop>45; CHECK-NEXT: Monotonicity: Unknown46; CHECK-NEXT: Reason: {%begin,+,1}<nuw><%loop>47; CHECK-EMPTY:48; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 149; CHECK-NEXT: da analyze - confused!50;51entry:52 %guard = icmp ult i64 %begin, %end53 br i1 %guard, label %loop, label %exit54 55loop:56 %i = phi i64 [ %begin, %entry ], [ %i.inc, %loop ]57 %idx = getelementptr i8, ptr %a, i64 %i58 store i8 0, ptr %idx59 %i.inc = add nuw i64 %i, 160 %exitcond = icmp eq i64 %i.inc, %end61 br i1 %exitcond, label %exit, label %loop62 63exit:64 ret void65}66 67; for (int i = 0; i < n; i++)68; for (int j = 0; j < m; j++)69; a[i + j] = 0;70;71define void @nested_loop_nsw0(ptr %a, i64 %n, i64 %m) {72; CHECK-LABEL: 'nested_loop_nsw0'73; CHECK-NEXT: Monotonicity check:74; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 175; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>76; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic77; CHECK-EMPTY:78; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 179; CHECK-NEXT: da analyze - output [* *]!80;81entry:82 %guard.i = icmp sgt i64 %n, 083 br i1 %guard.i, label %loop.i.header, label %exit84 85loop.i.header:86 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]87 br label %loop.j.preheader88 89loop.j.preheader:90 %gurard.j = icmp sgt i64 %m, 091 br i1 %gurard.j, label %loop.j, label %loop.i.latch92 93loop.j:94 %j = phi i64 [ 0, %loop.j.preheader ], [ %j.inc, %loop.j ]95 %offset = add nsw i64 %i, %j96 %idx = getelementptr inbounds i8, ptr %a, i64 %offset97 store i8 0, ptr %idx98 %j.inc = add nsw i64 %j, 199 %exitcond.j = icmp eq i64 %j.inc, %m100 br i1 %exitcond.j, label %loop.i.latch, label %loop.j101 102loop.i.latch:103 %i.inc = add nsw i64 %i, 1104 %exitcond.i = icmp eq i64 %i.inc, %n105 br i1 %exitcond.i, label %exit, label %loop.i.header106 107exit:108 ret void109}110 111; for (int i = n - 1; i >= 0; i--)112; for (int j = 0; j < m; j++)113; a[i + j] = 0;114;115define void @nested_loop_nsw1(ptr %a, i64 %n, i64 %m) {116; CHECK-LABEL: 'nested_loop_nsw1'117; CHECK-NEXT: Monotonicity check:118; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1119; CHECK-NEXT: Expr: {{\{\{}}(-1 + %n),+,-1}<nsw><%loop.i.header>,+,1}<nsw><%loop.j>120; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic121; CHECK-EMPTY:122; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1123; CHECK-NEXT: da analyze - output [* *]!124;125entry:126 %guard.i = icmp sgt i64 %n, 0127 br i1 %guard.i, label %loop.i.header, label %exit128 129loop.i.header:130 %i = phi i64 [ %n, %entry ], [ %i.dec, %loop.i.latch ]131 %i.dec = add nsw i64 %i, -1132 br label %loop.j.preheader133 134loop.j.preheader:135 %gurard.j = icmp sgt i64 %m, 0136 br i1 %gurard.j, label %loop.j, label %loop.i.latch137 138loop.j:139 %j = phi i64 [ 0, %loop.j.preheader ], [ %j.inc, %loop.j ]140 %offset = add nsw i64 %i.dec, %j141 %idx = getelementptr inbounds i8, ptr %a, i64 %offset142 store i8 0, ptr %idx143 %j.inc = add nsw i64 %j, 1144 %exitcond.j = icmp eq i64 %j.inc, %m145 br i1 %exitcond.j, label %loop.i.latch, label %loop.j146 147loop.i.latch:148 %exitcond.i = icmp eq i64 %i.dec, 0149 br i1 %exitcond.i, label %exit, label %loop.i.header150 151exit:152 ret void153}154 155; for (int i = 0; i < n; i--)156; for (int j = 0; j < m; j++)157; a[i - j] = 0;158;159define void @nested_loop_nsw2(ptr %a, i64 %n, i64 %m) {160; CHECK-LABEL: 'nested_loop_nsw2'161; CHECK-NEXT: Monotonicity check:162; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1163; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,-1}<nsw><%loop.j>164; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic165; CHECK-EMPTY:166; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1167; CHECK-NEXT: da analyze - output [* *]!168;169entry:170 %guard.i = icmp sgt i64 %n, 0171 br i1 %guard.i, label %loop.i.header, label %exit172 173loop.i.header:174 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]175 br label %loop.j.preheader176 177loop.j.preheader:178 %gurard.j = icmp sgt i64 %m, 0179 br i1 %gurard.j, label %loop.j, label %loop.i.latch180 181loop.j:182 %j = phi i64 [ 0, %loop.j.preheader ], [ %j.inc, %loop.j ]183 %offset = sub nsw i64 %i, %j184 %idx = getelementptr inbounds i8, ptr %a, i64 %offset185 store i8 0, ptr %idx186 %j.inc = add nsw i64 %j, 1187 %exitcond.j = icmp eq i64 %j.inc, %m188 br i1 %exitcond.j, label %loop.i.latch, label %loop.j189 190loop.i.latch:191 %i.inc = add nsw i64 %i, 1192 %exitcond.i = icmp eq i64 %i.inc, %n193 br i1 %exitcond.i, label %exit, label %loop.i.header194 195exit:196 ret void197}198 199; for (int i = begin0; i < end0; i++)200; for (int j = begin1; j < end1; j++) {201; unsigned long long offset = (unsigned long long)i + (unsigned long long)j;202; a[offset] = 0;203; }204;205define void @nested_loop_nuw(ptr %a, i64 %begin0, i64 %end0, i64 %begin1, i64 %end1) {206; CHECK-LABEL: 'nested_loop_nuw'207; CHECK-NEXT: Monotonicity check:208; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1209; CHECK-NEXT: Expr: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>210; CHECK-NEXT: Monotonicity: Unknown211; CHECK-NEXT: Reason: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>212; CHECK-EMPTY:213; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1214; CHECK-NEXT: da analyze - confused!215;216entry:217 %guard.i.0 = icmp slt i64 0, %begin0218 %guard.i.1 = icmp slt i64 %begin0, %end0219 %guard.i.2 = icmp slt i64 0, %end0220 %and.i.0 = and i1 %guard.i.0, %guard.i.1221 %and.i.1 = and i1 %and.i.0, %guard.i.2222 br i1 %and.i.1, label %loop.i.header, label %exit223 224loop.i.header:225 %i = phi i64 [ %begin0, %entry ], [ %i.inc, %loop.i.latch ]226 br label %loop.j.preheader227 228loop.j.preheader:229 %guard.j.0 = icmp slt i64 0, %begin1230 %guard.j.1 = icmp slt i64 %begin1, %end1231 %guard.j.2 = icmp slt i64 0, %end1232 %and.j.0 = and i1 %guard.j.0, %guard.j.1233 %and.j.1 = and i1 %and.j.0, %guard.j.2234 br i1 %and.j.1, label %loop.j, label %loop.i.latch235 236loop.j:237 %j = phi i64 [ %begin1, %loop.j.preheader ], [ %j.inc, %loop.j ]238 %offset = add nuw i64 %i, %j239 %idx = getelementptr i8, ptr %a, i64 %offset240 store i8 0, ptr %idx241 %j.inc = add nsw i64 %j, 1242 %exitcond.j = icmp eq i64 %j.inc, %end1243 br i1 %exitcond.j, label %loop.i.latch, label %loop.j244 245loop.i.latch:246 %i.inc = add nsw i64 %i, 1247 %exitcond.i = icmp eq i64 %i.inc, %end0248 br i1 %exitcond.i, label %exit, label %loop.i.header249 250exit:251 ret void252}253 254; for (int i = 0; i < n; i++)255; for (int j = 0; j < m; j++)256; a[i + step*j] = 0;257;258define void @nested_loop_step(ptr %a, i64 %n, i64 %m, i64 %step) {259; CHECK-LABEL: 'nested_loop_step'260; CHECK-NEXT: Monotonicity check:261; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1262; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,%step}<nsw><%loop.j>263; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic264; CHECK-EMPTY:265; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1266; CHECK-NEXT: da analyze - output [* *]!267;268entry:269 %guard.i = icmp sgt i64 %n, 0270 br i1 %guard.i, label %loop.i.header, label %exit271 272loop.i.header:273 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]274 br label %loop.j.preheader275 276loop.j.preheader:277 %gurard.j = icmp sgt i64 %m, 0278 br i1 %gurard.j, label %loop.j, label %loop.i.latch279 280loop.j:281 %j = phi i64 [ 0, %loop.j.preheader ], [ %j.inc, %loop.j ]282 %offset.j = phi i64 [ 0, %loop.j.preheader ], [ %offset.j.next, %loop.j ]283 %offset = add nsw i64 %i, %offset.j284 %idx = getelementptr inbounds i8, ptr %a, i64 %offset285 store i8 0, ptr %idx286 %j.inc = add nsw i64 %j, 1287 %offset.j.next = add nsw i64 %offset.j, %step288 %exitcond.j = icmp eq i64 %j.inc, %m289 br i1 %exitcond.j, label %loop.i.latch, label %loop.j290 291loop.i.latch:292 %i.inc = add nsw i64 %i, 1293 %exitcond.i = icmp eq i64 %i.inc, %n294 br i1 %exitcond.i, label %exit, label %loop.i.header295 296exit:297 ret void298}299 300; The value of step reccurence is not invariant with respect to the outer most301; loop (the i-loop). It is theoretically multivariate monotonic by definition,302; but we cannot handle non-affine addrec for now.303;304; offset_i = 0;305; for (int i = 0; i < 100; i++) {306; for (int j = 0; j < 100; j++)307; a[offset_i + j] = 0;308; offset_i += (i % 2 == 0) ? 0 : 3;309; }310;311define void @step_is_variant(ptr %a) {312; CHECK-LABEL: 'step_is_variant'313; CHECK-NEXT: Monotonicity check:314; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1315; CHECK-NEXT: Expr: {%offset.i,+,1}<nuw><nsw><%loop.j>316; CHECK-NEXT: Monotonicity: Unknown317; CHECK-NEXT: Reason: %offset.i318; CHECK-EMPTY:319; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1320; CHECK-NEXT: da analyze - confused!321;322entry:323 br label %loop.i.header324 325loop.i.header:326 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]327 %offset.i = phi i64 [ 0, %entry ], [ %offset.i.next, %loop.i.latch ]328 %step.i.0 = phi i64 [ 0, %entry ], [ %step.i.1, %loop.i.latch ]329 %step.i.1 = phi i64 [ 3, %entry ], [ %step.i.0, %loop.i.latch ]330 br label %loop.j331 332loop.j:333 %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ]334 %offset = add nsw i64 %offset.i, %j335 %idx = getelementptr inbounds i8, ptr %a, i64 %offset336 store i8 0, ptr %idx337 %j.inc = add nsw i64 %j, 1338 %exitcond.j = icmp eq i64 %j.inc, 100339 br i1 %exitcond.j, label %loop.i.latch, label %loop.j340 341loop.i.latch:342 %i.inc = add nsw i64 %i, 1343 %offset.i.next = add nsw i64 %offset.i, %step.i.0344 %exitcond.i = icmp eq i64 %i.inc, 100345 br i1 %exitcond.i, label %exit, label %loop.i.header346 347exit:348 ret void349}350 351; The value of step reccurence is not invariant with respect to the outer most352; loop (the i-loop). Actually, `offset_i` is not monotonic.353;354; offset_i = 0;355; for (int i = 0; i < 100; i++) {356; for (int j = 0; j < 100; j++)357; a[offset_i + j] = 0;358; offset_i += (i % 2 == 0) ? -1 : 3;359; }360;361define void @step_is_variant2(ptr %a) {362; CHECK-LABEL: 'step_is_variant2'363; CHECK-NEXT: Monotonicity check:364; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1365; CHECK-NEXT: Expr: {%offset.i,+,1}<nsw><%loop.j>366; CHECK-NEXT: Monotonicity: Unknown367; CHECK-NEXT: Reason: %offset.i368; CHECK-EMPTY:369; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1370; CHECK-NEXT: da analyze - confused!371;372entry:373 br label %loop.i.header374 375loop.i.header:376 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]377 %offset.i = phi i64 [ 0, %entry ], [ %offset.i.next, %loop.i.latch ]378 %step.i.0 = phi i64 [ -1, %entry ], [ %step.i.1, %loop.i.latch ]379 %step.i.1 = phi i64 [ 3, %entry ], [ %step.i.0, %loop.i.latch ]380 br label %loop.j381 382loop.j:383 %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ]384 %offset = add nsw i64 %offset.i, %j385 %idx = getelementptr inbounds i8, ptr %a, i64 %offset386 store i8 0, ptr %idx387 %j.inc = add nsw i64 %j, 1388 %exitcond.j = icmp eq i64 %j.inc, 100389 br i1 %exitcond.j, label %loop.i.latch, label %loop.j390 391loop.i.latch:392 %i.inc = add nsw i64 %i, 1393 %offset.i.next = add nsw i64 %offset.i, %step.i.0394 %exitcond.i = icmp eq i64 %i.inc, 100395 br i1 %exitcond.i, label %exit, label %loop.i.header396 397exit:398 ret void399}400 401; The AddRec doesn't have nsw flag for the j-loop, since the store may not be402; executed.403;404; for (int i = 0; i < n; i++)405; for (int j = 0; j < m; j++)406; if (cond)407; a[i + j] = 0;408;409define void @conditional_store0(ptr %a, i64 %n, i64 %m) {410; CHECK-LABEL: 'conditional_store0'411; CHECK-NEXT: Monotonicity check:412; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1413; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>414; CHECK-NEXT: Monotonicity: Unknown415; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>416; CHECK-EMPTY:417; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1418; CHECK-NEXT: da analyze - confused!419;420entry:421 %guard.i = icmp sgt i64 %n, 0422 br i1 %guard.i, label %loop.i.header, label %exit423 424loop.i.header:425 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]426 br label %loop.j.preheader427 428loop.j.preheader:429 %gurard.j = icmp sgt i64 %m, 0430 br i1 %gurard.j, label %loop.j.header, label %loop.i.latch431 432loop.j.header:433 %j = phi i64 [ 0, %loop.j.preheader ], [ %j.inc, %loop.j.latch ]434 %offset = add nsw i64 %i, %j435 %cond = freeze i1 poison436 br i1 %cond, label %if.then, label %loop.j.latch437 438if.then:439 %idx = getelementptr inbounds i8, ptr %a, i64 %offset440 store i8 0, ptr %idx441 br label %loop.j.latch442 443loop.j.latch:444 %j.inc = add nsw i64 %j, 1445 %exitcond.j = icmp eq i64 %j.inc, %m446 br i1 %exitcond.j, label %loop.i.latch, label %loop.j.header447 448loop.i.latch:449 %i.inc = add nsw i64 %i, 1450 %exitcond.i = icmp eq i64 %i.inc, %n451 br i1 %exitcond.i, label %exit, label %loop.i.header452 453exit:454 ret void455}456 457; Similar to the @conditional_store0, but the definition of the `%offset` is458; different from it and we can infer `nsw` in this case.459;460; for (int i = 0; i < n; i++)461; for (int j = 0; j < m; j++)462; if (cond)463; a[i + j] = 0;464;465define void @conditional_store1(ptr %a, i64 %n, i64 %m) {466; CHECK-LABEL: 'conditional_store1'467; CHECK-NEXT: Monotonicity check:468; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1469; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j.header>470; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic471; CHECK-EMPTY:472; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1473; CHECK-NEXT: da analyze - output [* *]!474;475entry:476 %guard.i = icmp sgt i64 %n, 0477 br i1 %guard.i, label %loop.i.header, label %exit478 479loop.i.header:480 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]481 br label %loop.j.preheader482 483loop.j.preheader:484 %gurard.j = icmp sgt i64 %m, 0485 br i1 %gurard.j, label %loop.j.header, label %loop.i.latch486 487loop.j.header:488 %j = phi i64 [ 0, %loop.j.preheader ], [ %j.inc, %loop.j.latch ]489 %offset = phi i64 [ %i, %loop.j.preheader ], [ %offset.next, %loop.j.latch ]490 %cond = freeze i1 poison491 br i1 %cond, label %if.then, label %loop.j.latch492 493if.then:494 %idx = getelementptr inbounds i8, ptr %a, i64 %offset495 store i8 0, ptr %idx496 br label %loop.j.latch497 498loop.j.latch:499 %j.inc = add nsw i64 %j, 1500 %offset.next = add nsw i64 %offset, 1501 %exitcond.j = icmp eq i64 %j.inc, %m502 br i1 %exitcond.j, label %loop.i.latch, label %loop.j.header503 504loop.i.latch:505 %i.inc = add nsw i64 %i, 1506 %exitcond.i = icmp eq i64 %i.inc, %n507 br i1 %exitcond.i, label %exit, label %loop.i.header508 509exit:510 ret void511}512 513; In the following case, the computation `offset = offset_i + j` will not wrap,514; but `offset_i += 1024` will wrap both in a signed sense and an unsigned515; sense. We cannot prove the monotonicity in this case.516;517; offset_i = (1ULL << 63) - 256;518; for (i = 0; i < (1ULL << 62); i++, offset_i += 1024)519; for (j = 0; j < 32; j++) {520; offset = offset_i + j;521;522; // The value of `offset` is positive in a signed sense.523; if (offset < (1ULL << 63))524; a[offset] = 0;525; }526;527define void @outer_loop_may_wrap(ptr %a) {528; CHECK-LABEL: 'outer_loop_may_wrap'529; CHECK-NEXT: Monotonicity check:530; CHECK-NEXT: Inst: store i8 0, ptr %gep, align 1531; CHECK-NEXT: Expr: {{\{\{}}9223372036854775552,+,1024}<%loop.i.header>,+,1}<nuw><nsw><%loop.j.header>532; CHECK-NEXT: Monotonicity: Unknown533; CHECK-NEXT: Reason: {9223372036854775552,+,1024}<%loop.i.header>534; CHECK-EMPTY:535; CHECK-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1536; CHECK-NEXT: da analyze - confused!537;538entry:539 br label %loop.i.header540 541loop.i.header:542 %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]543 %subscript.i = phi i64 [ 9223372036854775552, %entry ], [ %subscript.i.next, %loop.i.latch ] ; The initial value is 2^63 - 256544 br label %loop.j.header545 546loop.j.header:547 %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j.latch ]548 %subscript = phi i64 [ %subscript.i, %loop.i.header ], [ %subscript.next, %loop.j.latch ]549 %cond = icmp sge i64 %subscript, 0550 br i1 %cond, label %if.then, label %loop.j.latch551 552if.then:553 %gep = getelementptr inbounds i8, ptr %a, i64 %subscript554 store i8 0, ptr %gep555 br label %loop.j.latch556 557loop.j.latch:558 %j.inc = add nuw nsw i64 %j, 1559 %subscript.next = add nuw nsw i64 %subscript, 1560 %ec.j = icmp eq i64 %j.inc, 32561 br i1 %ec.j, label %loop.i.latch, label %loop.j.header562 563loop.i.latch:564 %i.inc = add nuw nsw i64 %i, 1565 %subscript.i.next = add i64 %subscript.i, 1024566 %ec.i = icmp eq i64 %i.inc, 4611686018427387904 ; 2^62567 br i1 %ec.i, label %exit, label %loop.i.header568 569exit:570 ret void571}572