Home | History | Annotate | Download | only in LoopAccessAnalysis
      1 ; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
      2 
      3 ; Check that loop-indepedent forward dependences are discovered properly.
      4 ;
      5 ; FIXME: This does not actually always work which is pretty confusing.  Right
      6 ; now there is hack in LAA that tries to figure out loop-indepedent forward
      7 ; dependeces *outside* of the MemoryDepChecker logic (i.e. proper dependence
      8 ; analysis).
      9 ;
     10 ; Therefore if there is only loop-independent dependences for an array
     11 ; (i.e. the same index is used), we don't discover the forward dependence.
     12 ; So, at ***, we add another non-I-based access of A to trigger
     13 ; MemoryDepChecker analysis for accesses of A.
     14 ;
     15 ;   for (unsigned i = 0; i < 100; i++) {
     16 ;     A[i + 1] = B[i] + 1;   // ***
     17 ;     A[i] = B[i] + 2;
     18 ;     C[i] = A[i] * 2;
     19 ;   }
     20 
     21 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
     22 
     23 define void @f(i32* noalias %A, i32* noalias %B, i32* noalias %C, i64 %N) {
     24 
     25 ; CHECK: Dependences:
     26 ; CHECK-NEXT:   Forward:
     27 ; CHECK-NEXT:       store i32 %b_p1, i32* %Aidx, align 4 ->
     28 ; CHECK-NEXT:       %a = load i32, i32* %Aidx, align 4
     29 ; CHECK:        ForwardButPreventsForwarding:
     30 ; CHECK-NEXT:       store i32 %b_p2, i32* %Aidx_next, align 4 ->
     31 ; CHECK-NEXT:       %a = load i32, i32* %Aidx, align 4
     32 ; CHECK:        Forward:
     33 ; CHECK-NEXT:       store i32 %b_p2, i32* %Aidx_next, align 4 ->
     34 ; CHECK-NEXT:       store i32 %b_p1, i32* %Aidx, align 4
     35 
     36 entry:
     37   br label %for.body
     38 
     39 for.body:                                         ; preds = %for.body, %entry
     40   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
     41   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     42 
     43   %Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
     44   %Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
     45   %Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
     46   %Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
     47 
     48   %b = load i32, i32* %Bidx, align 4
     49   %b_p2 = add i32 %b, 1
     50   store i32 %b_p2, i32* %Aidx_next, align 4
     51 
     52   %b_p1 = add i32 %b, 2
     53   store i32 %b_p1, i32* %Aidx, align 4
     54 
     55   %a = load i32, i32* %Aidx, align 4
     56   %c = mul i32 %a, 2
     57   store i32 %c, i32* %Cidx, align 4
     58 
     59   %exitcond = icmp eq i64 %indvars.iv.next, %N
     60   br i1 %exitcond, label %for.end, label %for.body
     61 
     62 for.end:                                          ; preds = %for.body
     63   ret void
     64 }
     65