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