1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -passes='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 14define void @nodep_Read_Write(ptr nocapture %A) { 15; CHECK-LABEL: 'nodep_Read_Write' 16; CHECK-NEXT: for.body: 17; CHECK-NEXT: Memory dependences are safe 18; CHECK-NEXT: Dependences: 19; CHECK-NEXT: Run-time memory checks: 20; CHECK-NEXT: Grouped accesses: 21; CHECK-EMPTY: 22; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 23; CHECK-NEXT: SCEV assumptions: 24; CHECK-EMPTY: 25; CHECK-NEXT: Expressions re-written: 26; 27entry: 28 %add.ptr = getelementptr inbounds i32, ptr %A, i64 1 29 br label %for.body 30 31for.cond.cleanup: ; preds = %for.body 32 ret void 33 34for.body: ; preds = %entry, %for.body 35 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 36 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 37 %0 = load i32, ptr %arrayidx, align 4 38 %add = add nsw i32 %0, 1 39 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 40 store i32 %add, ptr %arrayidx2, align 4 41 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3 42 %cmp = icmp ult i64 %indvars.iv.next, 1024 43 br i1 %cmp, label %for.body, label %for.cond.cleanup 44} 45 46; int nodep_Write_Read(int *A) { 47; int sum = 0; 48; for (unsigned i = 0; i < 1024; i+=4) { 49; A[i] = i; 50; sum += A[i+3]; 51; } 52; 53; return sum; 54; } 55 56define i32 @nodep_Write_Read(ptr nocapture %A) { 57; CHECK-LABEL: 'nodep_Write_Read' 58; CHECK-NEXT: for.body: 59; CHECK-NEXT: Memory dependences are safe 60; CHECK-NEXT: Dependences: 61; CHECK-NEXT: Run-time memory checks: 62; CHECK-NEXT: Grouped accesses: 63; CHECK-EMPTY: 64; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 65; CHECK-NEXT: SCEV assumptions: 66; CHECK-EMPTY: 67; CHECK-NEXT: Expressions re-written: 68; 69entry: 70 br label %for.body 71 72for.cond.cleanup: ; preds = %for.body 73 ret i32 %add3 74 75for.body: ; preds = %entry, %for.body 76 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 77 %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ] 78 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 79 %0 = trunc i64 %indvars.iv to i32 80 store i32 %0, ptr %arrayidx, align 4 81 %1 = or disjoint i64 %indvars.iv, 3 82 %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %1 83 %2 = load i32, ptr %arrayidx2, align 4 84 %add3 = add nsw i32 %2, %sum.013 85 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4 86 %cmp = icmp ult i64 %indvars.iv.next, 1024 87 br i1 %cmp, label %for.body, label %for.cond.cleanup 88} 89 90; void nodep_Write_Write(int *A) { 91; for (unsigned i = 0; i < 1024; i+=2) { 92; A[i] = i; 93; A[i+1] = i+1; 94; } 95; } 96 97define void @nodep_Write_Write(ptr nocapture %A) { 98; CHECK-LABEL: 'nodep_Write_Write' 99; CHECK-NEXT: for.body: 100; CHECK-NEXT: Memory dependences are safe 101; CHECK-NEXT: Dependences: 102; CHECK-NEXT: Run-time memory checks: 103; CHECK-NEXT: Grouped accesses: 104; CHECK-EMPTY: 105; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 106; CHECK-NEXT: SCEV assumptions: 107; CHECK-EMPTY: 108; CHECK-NEXT: Expressions re-written: 109; 110entry: 111 br label %for.body 112 113for.cond.cleanup: ; preds = %for.body 114 ret void 115 116for.body: ; preds = %entry, %for.body 117 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 118 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 119 %0 = trunc i64 %indvars.iv to i32 120 store i32 %0, ptr %arrayidx, align 4 121 %1 = or disjoint i64 %indvars.iv, 1 122 %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %1 123 %2 = trunc i64 %1 to i32 124 store i32 %2, ptr %arrayidx3, align 4 125 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 126 %cmp = icmp ult i64 %indvars.iv.next, 1024 127 br i1 %cmp, label %for.body, label %for.cond.cleanup 128} 129 130; Following cases are unsafe depdences and are not vectorizable. 131 132; void unsafe_Read_Write(int *A) { 133; for (unsigned i = 0; i < 1024; i+=3) 134; A[i+3] = A[i] + 1; 135; } 136 137define void @unsafe_Read_Write(ptr nocapture %A) { 138; CHECK-LABEL: 'unsafe_Read_Write' 139; CHECK-NEXT: for.body: 140; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 141; CHECK-NEXT: Backward loop carried data dependence. 142; CHECK-NEXT: Dependences: 143; CHECK-NEXT: Backward: 144; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 -> 145; CHECK-NEXT: store i32 %add, ptr %arrayidx3, align 4 146; CHECK-EMPTY: 147; CHECK-NEXT: Run-time memory checks: 148; CHECK-NEXT: Grouped accesses: 149; CHECK-EMPTY: 150; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 151; CHECK-NEXT: SCEV assumptions: 152; CHECK-EMPTY: 153; CHECK-NEXT: Expressions re-written: 154; 155entry: 156 br label %for.body 157 158for.cond.cleanup: ; preds = %for.body 159 ret void 160 161for.body: ; preds = %entry, %for.body 162 %i.010 = phi i32 [ 0, %entry ], [ %add1, %for.body ] 163 %idxprom = zext i32 %i.010 to i64 164 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom 165 %0 = load i32, ptr %arrayidx, align 4 166 %add = add nsw i32 %0, 1 167 %add1 = add i32 %i.010, 3 168 %idxprom2 = zext i32 %add1 to i64 169 %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %idxprom2 170 store i32 %add, ptr %arrayidx3, align 4 171 %cmp = icmp ult i32 %add1, 1024 172 br i1 %cmp, label %for.body, label %for.cond.cleanup 173} 174 175; int unsafe_Write_Read(int *A) { 176; int sum = 0; 177; for (unsigned i = 0; i < 1024; i+=4) { 178; A[i] = i; 179; sum += A[i+4]; 180; } 181; 182; return sum; 183; } 184 185define i32 @unsafe_Write_Read(ptr nocapture %A) { 186; CHECK-LABEL: 'unsafe_Write_Read' 187; CHECK-NEXT: for.body: 188; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 189; CHECK-NEXT: Backward loop carried data dependence. 190; CHECK-NEXT: Dependences: 191; CHECK-NEXT: Backward: 192; CHECK-NEXT: store i32 %0, ptr %arrayidx, align 4 -> 193; CHECK-NEXT: %1 = load i32, ptr %arrayidx2, align 4 194; CHECK-EMPTY: 195; CHECK-NEXT: Run-time memory checks: 196; CHECK-NEXT: Grouped accesses: 197; CHECK-EMPTY: 198; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 199; CHECK-NEXT: SCEV assumptions: 200; CHECK-EMPTY: 201; CHECK-NEXT: Expressions re-written: 202; 203entry: 204 br label %for.body 205 206for.cond.cleanup: ; preds = %for.body 207 ret i32 %add3 208 209for.body: ; preds = %entry, %for.body 210 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 211 %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ] 212 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 213 %0 = trunc i64 %indvars.iv to i32 214 store i32 %0, ptr %arrayidx, align 4 215 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4 216 %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %indvars.iv.next 217 %1 = load i32, ptr %arrayidx2, align 4 218 %add3 = add nsw i32 %1, %sum.013 219 %cmp = icmp ult i64 %indvars.iv.next, 1024 220 br i1 %cmp, label %for.body, label %for.cond.cleanup 221} 222 223; void unsafe_Write_Write(int *A) { 224; for (unsigned i = 0; i < 1024; i+=2) { 225; A[i] = i; 226; A[i+2] = i+1; 227; } 228; } 229 230define void @unsafe_Write_Write(ptr nocapture %A) { 231; CHECK-LABEL: 'unsafe_Write_Write' 232; CHECK-NEXT: for.body: 233; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 234; CHECK-NEXT: Backward loop carried data dependence. 235; CHECK-NEXT: Dependences: 236; CHECK-NEXT: Backward: 237; CHECK-NEXT: store i32 %0, ptr %arrayidx, align 4 -> 238; CHECK-NEXT: store i32 %2, ptr %arrayidx3, align 4 239; CHECK-EMPTY: 240; CHECK-NEXT: Run-time memory checks: 241; CHECK-NEXT: Grouped accesses: 242; CHECK-EMPTY: 243; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 244; CHECK-NEXT: SCEV assumptions: 245; CHECK-EMPTY: 246; CHECK-NEXT: Expressions re-written: 247; 248entry: 249 br label %for.body 250 251for.cond.cleanup: ; preds = %for.body 252 ret void 253 254for.body: ; preds = %entry, %for.body 255 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 256 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 257 %0 = trunc i64 %indvars.iv to i32 258 store i32 %0, ptr %arrayidx, align 4 259 %1 = or disjoint i64 %indvars.iv, 1 260 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 261 %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %indvars.iv.next 262 %2 = trunc i64 %1 to i32 263 store i32 %2, ptr %arrayidx3, align 4 264 %cmp = icmp ult i64 %indvars.iv.next, 1024 265 br i1 %cmp, label %for.body, label %for.cond.cleanup 266} 267 268; Following cases check that strided accesses can be vectorized. 269 270; void vectorizable_Read_Write(int *A) { 271; int *B = A + 4; 272; for (unsigned i = 0; i < 1024; i+=2) 273; B[i] = A[i] + 1; 274; } 275 276define void @vectorizable_Read_Write(ptr nocapture %A) { 277; CHECK-LABEL: 'vectorizable_Read_Write' 278; CHECK-NEXT: for.body: 279; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 64 bits 280; CHECK-NEXT: Dependences: 281; CHECK-NEXT: BackwardVectorizable: 282; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 -> 283; CHECK-NEXT: store i32 %add, ptr %arrayidx2, align 4 284; CHECK-EMPTY: 285; CHECK-NEXT: Run-time memory checks: 286; CHECK-NEXT: Grouped accesses: 287; CHECK-EMPTY: 288; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 289; CHECK-NEXT: SCEV assumptions: 290; CHECK-EMPTY: 291; CHECK-NEXT: Expressions re-written: 292; 293entry: 294 %add.ptr = getelementptr inbounds i32, ptr %A, i64 4 295 br label %for.body 296 297for.cond.cleanup: ; preds = %for.body 298 ret void 299 300for.body: ; preds = %entry, %for.body 301 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 302 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 303 %0 = load i32, ptr %arrayidx, align 4 304 %add = add nsw i32 %0, 1 305 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 306 store i32 %add, ptr %arrayidx2, align 4 307 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 308 %cmp = icmp ult i64 %indvars.iv.next, 1024 309 br i1 %cmp, label %for.body, label %for.cond.cleanup 310} 311 312; int vectorizable_Write_Read(int *A) { 313; int *B = A + 4; 314; int sum = 0; 315; for (unsigned i = 0; i < 1024; i+=2) { 316; A[i] = i; 317; sum += B[i]; 318; } 319; 320; return sum; 321; } 322 323define i32 @vectorizable_Write_Read(ptr nocapture %A) { 324; CHECK-LABEL: 'vectorizable_Write_Read' 325; CHECK-NEXT: for.body: 326; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 64 bits 327; CHECK-NEXT: Dependences: 328; CHECK-NEXT: BackwardVectorizable: 329; CHECK-NEXT: store i32 %0, ptr %arrayidx, align 4 -> 330; CHECK-NEXT: %1 = load i32, ptr %arrayidx2, align 4 331; CHECK-EMPTY: 332; CHECK-NEXT: Run-time memory checks: 333; CHECK-NEXT: Grouped accesses: 334; CHECK-EMPTY: 335; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 336; CHECK-NEXT: SCEV assumptions: 337; CHECK-EMPTY: 338; CHECK-NEXT: Expressions re-written: 339; 340entry: 341 %add.ptr = getelementptr inbounds i32, ptr %A, i64 4 342 br label %for.body 343 344for.cond.cleanup: ; preds = %for.body 345 ret i32 %add 346 347for.body: ; preds = %entry, %for.body 348 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 349 %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ] 350 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 351 %0 = trunc i64 %indvars.iv to i32 352 store i32 %0, ptr %arrayidx, align 4 353 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 354 %1 = load i32, ptr %arrayidx2, align 4 355 %add = add nsw i32 %1, %sum.013 356 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 357 %cmp = icmp ult i64 %indvars.iv.next, 1024 358 br i1 %cmp, label %for.body, label %for.cond.cleanup 359} 360 361; void vectorizable_Write_Write(int *A) { 362; int *B = A + 4; 363; for (unsigned i = 0; i < 1024; i+=2) { 364; A[i] = i; 365; B[i] = i+1; 366; } 367; } 368 369define void @vectorizable_Write_Write(ptr nocapture %A) { 370; CHECK-LABEL: 'vectorizable_Write_Write' 371; CHECK-NEXT: for.body: 372; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 64 bits 373; CHECK-NEXT: Dependences: 374; CHECK-NEXT: BackwardVectorizable: 375; CHECK-NEXT: store i32 %0, ptr %arrayidx, align 4 -> 376; CHECK-NEXT: store i32 %2, ptr %arrayidx2, align 4 377; CHECK-EMPTY: 378; CHECK-NEXT: Run-time memory checks: 379; CHECK-NEXT: Grouped accesses: 380; CHECK-EMPTY: 381; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 382; CHECK-NEXT: SCEV assumptions: 383; CHECK-EMPTY: 384; CHECK-NEXT: Expressions re-written: 385; 386entry: 387 %add.ptr = getelementptr inbounds i32, ptr %A, i64 4 388 br label %for.body 389 390for.cond.cleanup: ; preds = %for.body 391 ret void 392 393for.body: ; preds = %entry, %for.body 394 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 395 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 396 %0 = trunc i64 %indvars.iv to i32 397 store i32 %0, ptr %arrayidx, align 4 398 %1 = or disjoint i64 %indvars.iv, 1 399 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 400 %2 = trunc i64 %1 to i32 401 store i32 %2, ptr %arrayidx2, align 4 402 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 403 %cmp = icmp ult i64 %indvars.iv.next, 1024 404 br i1 %cmp, label %for.body, label %for.cond.cleanup 405} 406 407; void vectorizable_unscaled_Read_Write(int *A) { 408; int *B = (int *)((char *)A + 14); 409; for (unsigned i = 0; i < 1024; i+=2) 410; B[i] = A[i] + 1; 411; } 412 413; FIXME: This case looks like previous case @vectorizable_Read_Write. It sould 414; be vectorizable. 415 416define void @vectorizable_unscaled_Read_Write(ptr nocapture %A) { 417; CHECK-LABEL: 'vectorizable_unscaled_Read_Write' 418; CHECK-NEXT: for.body: 419; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 420; CHECK-NEXT: Backward loop carried data dependence that prevents store-to-load forwarding. 421; CHECK-NEXT: Dependences: 422; CHECK-NEXT: BackwardVectorizableButPreventsForwarding: 423; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 -> 424; CHECK-NEXT: store i32 %add, ptr %arrayidx2, align 4 425; CHECK-EMPTY: 426; CHECK-NEXT: Run-time memory checks: 427; CHECK-NEXT: Grouped accesses: 428; CHECK-EMPTY: 429; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 430; CHECK-NEXT: SCEV assumptions: 431; CHECK-EMPTY: 432; CHECK-NEXT: Expressions re-written: 433; 434entry: 435 %add.ptr = getelementptr inbounds i8, ptr %A, i64 14 436 br label %for.body 437 438for.cond.cleanup: ; preds = %for.body 439 ret void 440 441for.body: ; preds = %entry, %for.body 442 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 443 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 444 %0 = load i32, ptr %arrayidx, align 4 445 %add = add nsw i32 %0, 1 446 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 447 store i32 %add, ptr %arrayidx2, align 4 448 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 449 %cmp = icmp ult i64 %indvars.iv.next, 1024 450 br i1 %cmp, label %for.body, label %for.cond.cleanup 451} 452 453; int vectorizable_unscaled_Write_Read(int *A) { 454; int *B = (int *)((char *)A + 17); 455; int sum = 0; 456; for (unsigned i = 0; i < 1024; i+=2) { 457; A[i] = i; 458; sum += B[i]; 459; } 460; 461; return sum; 462; } 463 464define i32 @vectorizable_unscaled_Write_Read(ptr nocapture %A) { 465; CHECK-LABEL: 'vectorizable_unscaled_Write_Read' 466; CHECK-NEXT: for.body: 467; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 64 bits 468; CHECK-NEXT: Dependences: 469; CHECK-NEXT: BackwardVectorizable: 470; CHECK-NEXT: store i32 %0, ptr %arrayidx, align 4 -> 471; CHECK-NEXT: %1 = load i32, ptr %arrayidx2, align 4 472; CHECK-EMPTY: 473; CHECK-NEXT: Run-time memory checks: 474; CHECK-NEXT: Grouped accesses: 475; CHECK-EMPTY: 476; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 477; CHECK-NEXT: SCEV assumptions: 478; CHECK-EMPTY: 479; CHECK-NEXT: Expressions re-written: 480; 481entry: 482 %add.ptr = getelementptr inbounds i8, ptr %A, i64 17 483 br label %for.body 484 485for.cond.cleanup: ; preds = %for.body 486 ret i32 %add 487 488for.body: ; preds = %entry, %for.body 489 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 490 %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ] 491 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 492 %0 = trunc i64 %indvars.iv to i32 493 store i32 %0, ptr %arrayidx, align 4 494 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 495 %1 = load i32, ptr %arrayidx2, align 4 496 %add = add nsw i32 %1, %sum.013 497 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 498 %cmp = icmp ult i64 %indvars.iv.next, 1024 499 br i1 %cmp, label %for.body, label %for.cond.cleanup 500} 501 502; void unsafe_unscaled_Read_Write(int *A) { 503; int *B = (int *)((char *)A + 11); 504; for (unsigned i = 0; i < 1024; i+=2) 505; B[i] = A[i] + 1; 506; } 507 508define void @unsafe_unscaled_Read_Write(ptr nocapture %A) { 509; CHECK-LABEL: 'unsafe_unscaled_Read_Write' 510; CHECK-NEXT: for.body: 511; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 512; CHECK-NEXT: Backward loop carried data dependence. 513; CHECK-NEXT: Dependences: 514; CHECK-NEXT: Backward: 515; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 -> 516; CHECK-NEXT: store i32 %add, ptr %arrayidx2, align 4 517; CHECK-EMPTY: 518; CHECK-NEXT: Run-time memory checks: 519; CHECK-NEXT: Grouped accesses: 520; CHECK-EMPTY: 521; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 522; CHECK-NEXT: SCEV assumptions: 523; CHECK-EMPTY: 524; CHECK-NEXT: Expressions re-written: 525; 526entry: 527 %add.ptr = getelementptr inbounds i8, ptr %A, i64 11 528 br label %for.body 529 530for.cond.cleanup: ; preds = %for.body 531 ret void 532 533for.body: ; preds = %entry, %for.body 534 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 535 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 536 %0 = load i32, ptr %arrayidx, align 4 537 %add = add nsw i32 %0, 1 538 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 539 store i32 %add, ptr %arrayidx2, align 4 540 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 541 %cmp = icmp ult i64 %indvars.iv.next, 1024 542 br i1 %cmp, label %for.body, label %for.cond.cleanup 543} 544 545; void unsafe_unscaled_Read_Write2(int *A) { 546; int *B = (int *)((char *)A + 1); 547; for (unsigned i = 0; i < 1024; i+=2) 548; B[i] = A[i] + 1; 549; } 550 551define void @unsafe_unscaled_Read_Write2(ptr nocapture %A) { 552; CHECK-LABEL: 'unsafe_unscaled_Read_Write2' 553; CHECK-NEXT: for.body: 554; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 555; CHECK-NEXT: Backward loop carried data dependence. 556; CHECK-NEXT: Dependences: 557; CHECK-NEXT: Backward: 558; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 -> 559; CHECK-NEXT: store i32 %add, ptr %arrayidx2, align 4 560; CHECK-EMPTY: 561; CHECK-NEXT: Run-time memory checks: 562; CHECK-NEXT: Grouped accesses: 563; CHECK-EMPTY: 564; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 565; CHECK-NEXT: SCEV assumptions: 566; CHECK-EMPTY: 567; CHECK-NEXT: Expressions re-written: 568; 569entry: 570 %add.ptr = getelementptr inbounds i8, ptr %A, i64 1 571 br label %for.body 572 573for.cond.cleanup: ; preds = %for.body 574 ret void 575 576for.body: ; preds = %entry, %for.body 577 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 578 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv 579 %0 = load i32, ptr %arrayidx, align 4 580 %add = add nsw i32 %0, 1 581 %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv 582 store i32 %add, ptr %arrayidx2, align 4 583 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 584 %cmp = icmp ult i64 %indvars.iv.next, 1024 585 br i1 %cmp, label %for.body, label %for.cond.cleanup 586} 587 588; Following case checks that interleaved stores have dependences with another 589; store and can not pass dependence check. 590 591; void interleaved_stores(int *A) { 592; int *B = (int *) ((char *)A + 1); 593; for(int i = 0; i < 1024; i+=2) { 594; B[i] = i; // (1) 595; A[i+1] = i + 1; // (2) 596; B[i+1] = i + 1; // (3) 597; } 598; } 599; 600; The access (2) has overlaps with (1) and (3). 601 602define void @interleaved_stores(ptr nocapture %A) { 603; CHECK-LABEL: 'interleaved_stores' 604; CHECK-NEXT: for.body: 605; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 606; CHECK-NEXT: Backward loop carried data dependence. 607; CHECK-NEXT: Dependences: 608; CHECK-NEXT: Backward: 609; CHECK-NEXT: store i32 %2, ptr %arrayidx5, align 4 -> 610; CHECK-NEXT: store i32 %2, ptr %arrayidx9, align 4 611; CHECK-EMPTY: 612; CHECK-NEXT: Backward: 613; CHECK-NEXT: store i32 %0, ptr %arrayidx2, align 4 -> 614; CHECK-NEXT: store i32 %2, ptr %arrayidx5, align 4 615; CHECK-EMPTY: 616; CHECK-NEXT: Run-time memory checks: 617; CHECK-NEXT: Grouped accesses: 618; CHECK-EMPTY: 619; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 620; CHECK-NEXT: SCEV assumptions: 621; CHECK-EMPTY: 622; CHECK-NEXT: Expressions re-written: 623; 624entry: 625 %incdec.ptr = getelementptr inbounds i8, ptr %A, i64 1 626 br label %for.body 627 628for.cond.cleanup: ; preds = %for.body 629 ret void 630 631for.body: ; preds = %entry, %for.body 632 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 633 %0 = trunc i64 %indvars.iv to i32 634 %arrayidx2 = getelementptr inbounds i32, ptr %incdec.ptr, i64 %indvars.iv 635 store i32 %0, ptr %arrayidx2, align 4 636 %1 = or disjoint i64 %indvars.iv, 1 637 %arrayidx5 = getelementptr inbounds i32, ptr %A, i64 %1 638 %2 = trunc i64 %1 to i32 639 store i32 %2, ptr %arrayidx5, align 4 640 %arrayidx9 = getelementptr inbounds i32, ptr %incdec.ptr, i64 %1 641 store i32 %2, ptr %arrayidx9, align 4 642 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2 643 %cmp = icmp slt i64 %indvars.iv.next, 1024 644 br i1 %cmp, label %for.body, label %for.cond.cleanup 645} 646