1; RUN: opt -loop-accesses -analyze < %s | FileCheck %s 2; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" 5 6; Following cases are no dependence. 7 8; void nodep_Read_Write(int *A) { 9; int *B = A + 1; 10; for (unsigned i = 0; i < 1024; i+=3) 11; B[i] = A[i] + 1; 12; } 13 14; CHECK: function 'nodep_Read_Write': 15; CHECK-NEXT: for.body: 16; CHECK-NEXT: Memory dependences are safe 17; CHECK-NEXT: Dependences: 18; CHECK-NEXT: Run-time memory checks: 19 20define void @nodep_Read_Write(i32* nocapture %A) { 21entry: 22 %add.ptr = getelementptr inbounds i32, i32* %A, i64 1 23 br label %for.body 24 25for.cond.cleanup: ; preds = %for.body 26 ret void 27 28for.body: ; preds = %entry, %for.body 29 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 30 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 31 %0 = load i32, i32* %arrayidx, align 4 32 %add = add nsw i32 %0, 1 33 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv 34 store i32 %add, i32* %arrayidx2, align 4 35 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3 36 %cmp = icmp ult i64 %indvars.iv.next, 1024 37 br i1 %cmp, label %for.body, label %for.cond.cleanup 38} 39 40; int nodep_Write_Read(int *A) { 41; int sum = 0; 42; for (unsigned i = 0; i < 1024; i+=4) { 43; A[i] = i; 44; sum += A[i+3]; 45; } 46; 47; return sum; 48; } 49 50; CHECK: function 'nodep_Write_Read': 51; CHECK-NEXT: for.body: 52; CHECK-NEXT: Memory dependences are safe 53; CHECK-NEXT: Dependences: 54; CHECK-NEXT: Run-time memory checks: 55 56define i32 @nodep_Write_Read(i32* nocapture %A) { 57entry: 58 br label %for.body 59 60for.cond.cleanup: ; preds = %for.body 61 ret i32 %add3 62 63for.body: ; preds = %entry, %for.body 64 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 65 %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ] 66 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 67 %0 = trunc i64 %indvars.iv to i32 68 store i32 %0, i32* %arrayidx, align 4 69 %1 = or i64 %indvars.iv, 3 70 %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %1 71 %2 = load i32, i32* %arrayidx2, align 4 72 %add3 = add nsw i32 %2, %sum.013 73 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4 74 %cmp = icmp ult i64 %indvars.iv.next, 1024 75 br i1 %cmp, label %for.body, label %for.cond.cleanup 76} 77 78; void nodep_Write_Write(int *A) { 79; for (unsigned i = 0; i < 1024; i+=2) { 80; A[i] = i; 81; A[i+1] = i+1; 82; } 83; } 84 85; CHECK: function 'nodep_Write_Write': 86; CHECK-NEXT: for.body: 87; CHECK-NEXT: Memory dependences are safe 88; CHECK-NEXT: Dependences: 89; CHECK-NEXT: Run-time memory checks: 90 91define void @nodep_Write_Write(i32* nocapture %A) { 92entry: 93 br label %for.body 94 95for.cond.cleanup: ; preds = %for.body 96 ret void 97 98for.body: ; preds = %entry, %for.body 99 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 100 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 101 %0 = trunc i64 %indvars.iv to i32 102 store i32 %0, i32* %arrayidx, align 4 103 %1 = or i64 %indvars.iv, 1 104 %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %1 105 %2 = trunc i64 %1 to i32 106 store i32 %2, i32* %arrayidx3, align 4 107 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 108 %cmp = icmp ult i64 %indvars.iv.next, 1024 109 br i1 %cmp, label %for.body, label %for.cond.cleanup 110} 111 112; Following cases are unsafe depdences and are not vectorizable. 113 114; void unsafe_Read_Write(int *A) { 115; for (unsigned i = 0; i < 1024; i+=3) 116; A[i+3] = A[i] + 1; 117; } 118 119; CHECK: function 'unsafe_Read_Write': 120; CHECK-NEXT: for.body: 121; CHECK-NEXT: Report: unsafe dependent memory operations in loop 122; CHECK-NEXT: Dependences: 123; CHECK-NEXT: Backward: 124; CHECK-NEXT: %0 = load i32, i32* %arrayidx, align 4 -> 125; CHECK-NEXT: store i32 %add, i32* %arrayidx3, align 4 126 127define void @unsafe_Read_Write(i32* nocapture %A) { 128entry: 129 br label %for.body 130 131for.cond.cleanup: ; preds = %for.body 132 ret void 133 134for.body: ; preds = %entry, %for.body 135 %i.010 = phi i32 [ 0, %entry ], [ %add1, %for.body ] 136 %idxprom = zext i32 %i.010 to i64 137 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom 138 %0 = load i32, i32* %arrayidx, align 4 139 %add = add nsw i32 %0, 1 140 %add1 = add i32 %i.010, 3 141 %idxprom2 = zext i32 %add1 to i64 142 %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %idxprom2 143 store i32 %add, i32* %arrayidx3, align 4 144 %cmp = icmp ult i32 %add1, 1024 145 br i1 %cmp, label %for.body, label %for.cond.cleanup 146} 147 148; int unsafe_Write_Read(int *A) { 149; int sum = 0; 150; for (unsigned i = 0; i < 1024; i+=4) { 151; A[i] = i; 152; sum += A[i+4]; 153; } 154; 155; return sum; 156; } 157 158; CHECK: function 'unsafe_Write_Read': 159; CHECK-NEXT: for.body: 160; CHECK-NEXT: Report: unsafe dependent memory operations in loop 161; CHECK-NEXT: Dependences: 162; CHECK-NEXT: Backward: 163; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 -> 164; CHECK-NEXT: %1 = load i32, i32* %arrayidx2, align 4 165 166define i32 @unsafe_Write_Read(i32* nocapture %A) { 167entry: 168 br label %for.body 169 170for.cond.cleanup: ; preds = %for.body 171 ret i32 %add3 172 173for.body: ; preds = %entry, %for.body 174 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 175 %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ] 176 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 177 %0 = trunc i64 %indvars.iv to i32 178 store i32 %0, i32* %arrayidx, align 4 179 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4 180 %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next 181 %1 = load i32, i32* %arrayidx2, align 4 182 %add3 = add nsw i32 %1, %sum.013 183 %cmp = icmp ult i64 %indvars.iv.next, 1024 184 br i1 %cmp, label %for.body, label %for.cond.cleanup 185} 186 187; void unsafe_Write_Write(int *A) { 188; for (unsigned i = 0; i < 1024; i+=2) { 189; A[i] = i; 190; A[i+2] = i+1; 191; } 192; } 193 194; CHECK: function 'unsafe_Write_Write': 195; CHECK-NEXT: for.body: 196; CHECK-NEXT: Report: unsafe dependent memory operations in loop 197; CHECK-NEXT: Dependences: 198; CHECK-NEXT: Backward: 199; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 -> 200; CHECK-NEXT: store i32 %2, i32* %arrayidx3, align 4 201 202define void @unsafe_Write_Write(i32* nocapture %A) { 203entry: 204 br label %for.body 205 206for.cond.cleanup: ; preds = %for.body 207 ret void 208 209for.body: ; preds = %entry, %for.body 210 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 211 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 212 %0 = trunc i64 %indvars.iv to i32 213 store i32 %0, i32* %arrayidx, align 4 214 %1 = or i64 %indvars.iv, 1 215 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 216 %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next 217 %2 = trunc i64 %1 to i32 218 store i32 %2, i32* %arrayidx3, align 4 219 %cmp = icmp ult i64 %indvars.iv.next, 1024 220 br i1 %cmp, label %for.body, label %for.cond.cleanup 221} 222 223; Following cases check that strided accesses can be vectorized. 224 225; void vectorizable_Read_Write(int *A) { 226; int *B = A + 4; 227; for (unsigned i = 0; i < 1024; i+=2) 228; B[i] = A[i] + 1; 229; } 230 231; CHECK: function 'vectorizable_Read_Write': 232; CHECK-NEXT: for.body: 233; CHECK-NEXT: Memory dependences are safe 234; CHECK-NEXT: Dependences: 235; CHECK-NEXT: BackwardVectorizable: 236; CHECK-NEXT: %0 = load i32, i32* %arrayidx, align 4 -> 237; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4 238 239define void @vectorizable_Read_Write(i32* nocapture %A) { 240entry: 241 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4 242 br label %for.body 243 244for.cond.cleanup: ; preds = %for.body 245 ret void 246 247for.body: ; preds = %entry, %for.body 248 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 249 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 250 %0 = load i32, i32* %arrayidx, align 4 251 %add = add nsw i32 %0, 1 252 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv 253 store i32 %add, i32* %arrayidx2, align 4 254 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 255 %cmp = icmp ult i64 %indvars.iv.next, 1024 256 br i1 %cmp, label %for.body, label %for.cond.cleanup 257} 258 259; int vectorizable_Write_Read(int *A) { 260; int *B = A + 4; 261; int sum = 0; 262; for (unsigned i = 0; i < 1024; i+=2) { 263; A[i] = i; 264; sum += B[i]; 265; } 266; 267; return sum; 268; } 269 270; CHECK: function 'vectorizable_Write_Read': 271; CHECK-NEXT: for.body: 272; CHECK-NEXT: Memory dependences are safe 273; CHECK-NEXT: Dependences: 274; CHECK-NEXT: BackwardVectorizable: 275; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 -> 276; CHECK-NEXT: %1 = load i32, i32* %arrayidx2, align 4 277 278define i32 @vectorizable_Write_Read(i32* nocapture %A) { 279entry: 280 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4 281 br label %for.body 282 283for.cond.cleanup: ; preds = %for.body 284 ret i32 %add 285 286for.body: ; preds = %entry, %for.body 287 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 288 %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ] 289 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 290 %0 = trunc i64 %indvars.iv to i32 291 store i32 %0, i32* %arrayidx, align 4 292 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv 293 %1 = load i32, i32* %arrayidx2, align 4 294 %add = add nsw i32 %1, %sum.013 295 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 296 %cmp = icmp ult i64 %indvars.iv.next, 1024 297 br i1 %cmp, label %for.body, label %for.cond.cleanup 298} 299 300; void vectorizable_Write_Write(int *A) { 301; int *B = A + 4; 302; for (unsigned i = 0; i < 1024; i+=2) { 303; A[i] = i; 304; B[i] = i+1; 305; } 306; } 307 308; CHECK: function 'vectorizable_Write_Write': 309; CHECK-NEXT: for.body: 310; CHECK-NEXT: Memory dependences are safe 311; CHECK-NEXT: Dependences: 312; CHECK-NEXT: BackwardVectorizable: 313; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 -> 314; CHECK-NEXT: store i32 %2, i32* %arrayidx2, align 4 315 316define void @vectorizable_Write_Write(i32* nocapture %A) { 317entry: 318 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4 319 br label %for.body 320 321for.cond.cleanup: ; preds = %for.body 322 ret void 323 324for.body: ; preds = %entry, %for.body 325 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 326 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 327 %0 = trunc i64 %indvars.iv to i32 328 store i32 %0, i32* %arrayidx, align 4 329 %1 = or i64 %indvars.iv, 1 330 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv 331 %2 = trunc i64 %1 to i32 332 store i32 %2, i32* %arrayidx2, align 4 333 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 334 %cmp = icmp ult i64 %indvars.iv.next, 1024 335 br i1 %cmp, label %for.body, label %for.cond.cleanup 336} 337 338; void vectorizable_unscaled_Read_Write(int *A) { 339; int *B = (int *)((char *)A + 14); 340; for (unsigned i = 0; i < 1024; i+=2) 341; B[i] = A[i] + 1; 342; } 343 344; FIXME: This case looks like previous case @vectorizable_Read_Write. It sould 345; be vectorizable. 346 347; CHECK: function 'vectorizable_unscaled_Read_Write': 348; CHECK-NEXT: for.body: 349; CHECK-NEXT: Report: unsafe dependent memory operations in loop 350; CHECK-NEXT: Dependences: 351; CHECK-NEXT: BackwardVectorizableButPreventsForwarding: 352; CHECK-NEXT: %2 = load i32, i32* %arrayidx, align 4 -> 353; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4 354 355define void @vectorizable_unscaled_Read_Write(i32* nocapture %A) { 356entry: 357 %0 = bitcast i32* %A to i8* 358 %add.ptr = getelementptr inbounds i8, i8* %0, i64 14 359 %1 = bitcast i8* %add.ptr to i32* 360 br label %for.body 361 362for.cond.cleanup: ; preds = %for.body 363 ret void 364 365for.body: ; preds = %entry, %for.body 366 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 367 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 368 %2 = load i32, i32* %arrayidx, align 4 369 %add = add nsw i32 %2, 1 370 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv 371 store i32 %add, i32* %arrayidx2, align 4 372 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 373 %cmp = icmp ult i64 %indvars.iv.next, 1024 374 br i1 %cmp, label %for.body, label %for.cond.cleanup 375} 376 377; int vectorizable_unscaled_Write_Read(int *A) { 378; int *B = (int *)((char *)A + 17); 379; int sum = 0; 380; for (unsigned i = 0; i < 1024; i+=2) { 381; A[i] = i; 382; sum += B[i]; 383; } 384; 385; return sum; 386; } 387 388; CHECK: function 'vectorizable_unscaled_Write_Read': 389; CHECK-NEXT: for.body: 390; CHECK-NEXT: Memory dependences are safe 391; CHECK-NEXT: Dependences: 392; CHECK-NEXT: BackwardVectorizable: 393; CHECK-NEXT: store i32 %2, i32* %arrayidx, align 4 -> 394; CHECK-NEXT: %3 = load i32, i32* %arrayidx2, align 4 395 396define i32 @vectorizable_unscaled_Write_Read(i32* nocapture %A) { 397entry: 398 %0 = bitcast i32* %A to i8* 399 %add.ptr = getelementptr inbounds i8, i8* %0, i64 17 400 %1 = bitcast i8* %add.ptr to i32* 401 br label %for.body 402 403for.cond.cleanup: ; preds = %for.body 404 ret i32 %add 405 406for.body: ; preds = %entry, %for.body 407 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 408 %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ] 409 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 410 %2 = trunc i64 %indvars.iv to i32 411 store i32 %2, i32* %arrayidx, align 4 412 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv 413 %3 = load i32, i32* %arrayidx2, align 4 414 %add = add nsw i32 %3, %sum.013 415 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 416 %cmp = icmp ult i64 %indvars.iv.next, 1024 417 br i1 %cmp, label %for.body, label %for.cond.cleanup 418} 419 420; void unsafe_unscaled_Read_Write(int *A) { 421; int *B = (int *)((char *)A + 11); 422; for (unsigned i = 0; i < 1024; i+=2) 423; B[i] = A[i] + 1; 424; } 425 426; CHECK: function 'unsafe_unscaled_Read_Write': 427; CHECK-NEXT: for.body: 428; CHECK-NEXT: Report: unsafe dependent memory operations in loop 429; CHECK-NEXT: Dependences: 430; CHECK-NEXT: Backward: 431; CHECK-NEXT: %2 = load i32, i32* %arrayidx, align 4 -> 432; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4 433 434define void @unsafe_unscaled_Read_Write(i32* nocapture %A) { 435entry: 436 %0 = bitcast i32* %A to i8* 437 %add.ptr = getelementptr inbounds i8, i8* %0, i64 11 438 %1 = bitcast i8* %add.ptr to i32* 439 br label %for.body 440 441for.cond.cleanup: ; preds = %for.body 442 ret void 443 444for.body: ; preds = %entry, %for.body 445 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 446 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 447 %2 = load i32, i32* %arrayidx, align 4 448 %add = add nsw i32 %2, 1 449 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv 450 store i32 %add, i32* %arrayidx2, align 4 451 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 452 %cmp = icmp ult i64 %indvars.iv.next, 1024 453 br i1 %cmp, label %for.body, label %for.cond.cleanup 454} 455 456; CHECK: function 'unsafe_unscaled_Read_Write2': 457; CHECK-NEXT: for.body: 458; CHECK-NEXT: Report: unsafe dependent memory operations in loop 459; CHECK-NEXT: Dependences: 460; CHECK-NEXT: Backward: 461; CHECK-NEXT: %2 = load i32, i32* %arrayidx, align 4 -> 462; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4 463 464; void unsafe_unscaled_Read_Write2(int *A) { 465; int *B = (int *)((char *)A + 1); 466; for (unsigned i = 0; i < 1024; i+=2) 467; B[i] = A[i] + 1; 468; } 469 470define void @unsafe_unscaled_Read_Write2(i32* nocapture %A) { 471entry: 472 %0 = bitcast i32* %A to i8* 473 %add.ptr = getelementptr inbounds i8, i8* %0, i64 1 474 %1 = bitcast i8* %add.ptr to i32* 475 br label %for.body 476 477for.cond.cleanup: ; preds = %for.body 478 ret void 479 480for.body: ; preds = %entry, %for.body 481 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 482 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv 483 %2 = load i32, i32* %arrayidx, align 4 484 %add = add nsw i32 %2, 1 485 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv 486 store i32 %add, i32* %arrayidx2, align 4 487 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 488 %cmp = icmp ult i64 %indvars.iv.next, 1024 489 br i1 %cmp, label %for.body, label %for.cond.cleanup 490} 491 492; Following case checks that interleaved stores have dependences with another 493; store and can not pass dependence check. 494 495; void interleaved_stores(int *A) { 496; int *B = (int *) ((char *)A + 1); 497; for(int i = 0; i < 1024; i+=2) { 498; B[i] = i; // (1) 499; A[i+1] = i + 1; // (2) 500; B[i+1] = i + 1; // (3) 501; } 502; } 503; 504; The access (2) has overlaps with (1) and (3). 505 506; CHECK: function 'interleaved_stores': 507; CHECK-NEXT: for.body: 508; CHECK-NEXT: Report: unsafe dependent memory operations in loop 509; CHECK-NEXT: Dependences: 510; CHECK-NEXT: Backward: 511; CHECK-NEXT: store i32 %4, i32* %arrayidx5, align 4 -> 512; CHECK-NEXT: store i32 %4, i32* %arrayidx9, align 4 513; CHECK: Backward: 514; CHECK-NEXT: store i32 %2, i32* %arrayidx2, align 4 -> 515; CHECK-NEXT: store i32 %4, i32* %arrayidx5, align 4 516 517define void @interleaved_stores(i32* nocapture %A) { 518entry: 519 %0 = bitcast i32* %A to i8* 520 %incdec.ptr = getelementptr inbounds i8, i8* %0, i64 1 521 %1 = bitcast i8* %incdec.ptr to i32* 522 br label %for.body 523 524for.cond.cleanup: ; preds = %for.body 525 ret void 526 527for.body: ; preds = %entry, %for.body 528 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 529 %2 = trunc i64 %indvars.iv to i32 530 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv 531 store i32 %2, i32* %arrayidx2, align 4 532 %3 = or i64 %indvars.iv, 1 533 %arrayidx5 = getelementptr inbounds i32, i32* %A, i64 %3 534 %4 = trunc i64 %3 to i32 535 store i32 %4, i32* %arrayidx5, align 4 536 %arrayidx9 = getelementptr inbounds i32, i32* %1, i64 %3 537 store i32 %4, i32* %arrayidx9, align 4 538 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 539 %cmp = icmp slt i64 %indvars.iv.next, 1024 540 br i1 %cmp, label %for.body, label %for.cond.cleanup 541} 542