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 4 target 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 20 define void @nodep_Read_Write(i32* nocapture %A) { 21 entry: 22 %add.ptr = getelementptr inbounds i32, i32* %A, i64 1 23 br label %for.body 24 25 for.cond.cleanup: ; preds = %for.body 26 ret void 27 28 for.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 56 define i32 @nodep_Write_Read(i32* nocapture %A) { 57 entry: 58 br label %for.body 59 60 for.cond.cleanup: ; preds = %for.body 61 ret i32 %add3 62 63 for.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 91 define void @nodep_Write_Write(i32* nocapture %A) { 92 entry: 93 br label %for.body 94 95 for.cond.cleanup: ; preds = %for.body 96 ret void 97 98 for.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 127 define void @unsafe_Read_Write(i32* nocapture %A) { 128 entry: 129 br label %for.body 130 131 for.cond.cleanup: ; preds = %for.body 132 ret void 133 134 for.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 166 define i32 @unsafe_Write_Read(i32* nocapture %A) { 167 entry: 168 br label %for.body 169 170 for.cond.cleanup: ; preds = %for.body 171 ret i32 %add3 172 173 for.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 202 define void @unsafe_Write_Write(i32* nocapture %A) { 203 entry: 204 br label %for.body 205 206 for.cond.cleanup: ; preds = %for.body 207 ret void 208 209 for.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 239 define void @vectorizable_Read_Write(i32* nocapture %A) { 240 entry: 241 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4 242 br label %for.body 243 244 for.cond.cleanup: ; preds = %for.body 245 ret void 246 247 for.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 278 define i32 @vectorizable_Write_Read(i32* nocapture %A) { 279 entry: 280 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4 281 br label %for.body 282 283 for.cond.cleanup: ; preds = %for.body 284 ret i32 %add 285 286 for.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 316 define void @vectorizable_Write_Write(i32* nocapture %A) { 317 entry: 318 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4 319 br label %for.body 320 321 for.cond.cleanup: ; preds = %for.body 322 ret void 323 324 for.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 355 define void @vectorizable_unscaled_Read_Write(i32* nocapture %A) { 356 entry: 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 362 for.cond.cleanup: ; preds = %for.body 363 ret void 364 365 for.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 396 define i32 @vectorizable_unscaled_Write_Read(i32* nocapture %A) { 397 entry: 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 403 for.cond.cleanup: ; preds = %for.body 404 ret i32 %add 405 406 for.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 434 define void @unsafe_unscaled_Read_Write(i32* nocapture %A) { 435 entry: 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 441 for.cond.cleanup: ; preds = %for.body 442 ret void 443 444 for.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 470 define void @unsafe_unscaled_Read_Write2(i32* nocapture %A) { 471 entry: 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 477 for.cond.cleanup: ; preds = %for.body 478 ret void 479 480 for.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 517 define void @interleaved_stores(i32* nocapture %A) { 518 entry: 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 524 for.cond.cleanup: ; preds = %for.body 525 ret void 526 527 for.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