OSDN Git Service

am a10bdf76: Merge "Update aosp/master LLVM for rebase to r239765"
[android-x86/external-llvm.git] / test / Analysis / LoopAccessAnalysis / underlying-objects-2.ll
1 ; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s
2
3 ; This loop:
4 ;
5 ;   int **A;
6 ;   for (i)
7 ;     for (j) {
8 ;        A[i][j] = A[i-1][j] * B[j]
9 ;        B[j+1] = 2       // backward dep between this and the previous
10 ;     }
11 ;
12 ; is transformed by Load-PRE to stash away A[i] for the next iteration of the
13 ; outer loop:
14 ;
15 ;   Curr = A[0];          // Prev_0
16 ;   for (i: 1..N) {
17 ;     Prev = Curr;        // Prev = PHI (Prev_0, Curr)
18 ;     Curr = A[i];
19 ;     for (j: 0..N) {
20 ;        Curr[j] = Prev[j] * B[j]
21 ;        B[j+1] = 2       // backward dep between this and the previous
22 ;     }
23 ;   }
24 ;
25 ; Since A[i] and A[i-1] are likely to be independent, getUnderlyingObjects
26 ; should not assume that Curr and Prev share the same underlying object.
27 ;
28 ; If it did we would try to dependence-analyze Curr and Prev and the analysis
29 ; would fail with non-constant distance.
30 ;
31 ; To illustrate one of the negative consequences of this, if the loop has a
32 ; backward dependence we won't detect this but instead fully fall back on
33 ; memchecks (that is what LAA does after encountering a case of non-constant
34 ; distance).
35
36 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
37 target triple = "x86_64-apple-macosx10.10.0"
38
39 ; CHECK: for_j.body:
40 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop
41 ; CHECK-NEXT: Interesting Dependences:
42 ; CHECK-NEXT: Backward:
43 ; CHECK-NEXT: %loadB = load i8, i8* %gepB, align 1 ->
44 ; CHECK-NEXT: store i8 2, i8* %gepB_plus_one, align 1
45
46 define void @f(i8** noalias %A, i8* noalias %B, i64 %N) {
47 for_i.preheader:
48   %prev_0 = load i8*, i8** %A, align 8
49   br label %for_i.body
50
51 for_i.body:
52   %i = phi i64 [1, %for_i.preheader], [%i.1, %for_j.end]
53   %prev = phi i8* [%prev_0, %for_i.preheader], [%curr, %for_j.end]
54   %gep = getelementptr inbounds i8*, i8** %A, i64 %i
55   %curr = load i8*, i8** %gep, align 8
56   br label %for_j.preheader
57
58 for_j.preheader:
59   br label %for_j.body
60
61 for_j.body:
62   %j = phi i64 [0, %for_j.preheader], [%j.1, %for_j.body]
63
64   %gepPrev = getelementptr inbounds i8, i8* %prev, i64 %j
65   %gepCurr = getelementptr inbounds i8, i8* %curr, i64 %j
66   %gepB = getelementptr inbounds i8, i8* %B, i64 %j
67
68   %loadPrev = load i8, i8* %gepPrev, align 1
69   %loadB = load i8, i8* %gepB, align 1
70
71   %mul = mul i8 %loadPrev, %loadB
72
73   store i8 %mul, i8* %gepCurr, align 1
74
75   %gepB_plus_one = getelementptr inbounds i8, i8* %gepB, i64 1
76   store i8 2, i8* %gepB_plus_one, align 1
77
78   %j.1 = add nuw i64 %j, 1
79   %exitcondj = icmp eq i64 %j.1, %N
80   br i1 %exitcondj, label %for_j.end, label %for_j.body
81
82 for_j.end:
83
84   %i.1 = add nuw i64 %i, 1
85   %exitcond = icmp eq i64 %i.1, %N
86   br i1 %exitcond, label %for_i.end, label %for_i.body
87
88 for_i.end:
89   ret void
90 }