[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Analysis / LoopAccessAnalysis / underlying-objects-2.ll
bloba067dc2f0c0c07e5380e914761dbf099eacf45d4
1 ; RUN: opt -basic-aa -loop-accesses -analyze -enable-new-pm=0 < %s | FileCheck %s
2 ; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output  < %s 2>&1 | FileCheck %s
4 ; This loop:
6 ;   int **A;
7 ;   for (i)
8 ;     for (j) {
9 ;        A[i][j] = A[i-1][j] * B[j]
10 ;        B[j+1] = 2       // backward dep between this and the previous
11 ;     }
13 ; is transformed by Load-PRE to stash away A[i] for the next iteration of the
14 ; outer loop:
16 ;   Curr = A[0];          // Prev_0
17 ;   for (i: 1..N) {
18 ;     Prev = Curr;        // Prev = PHI (Prev_0, Curr)
19 ;     Curr = A[i];
20 ;     for (j: 0..N) {
21 ;        Curr[j] = Prev[j] * B[j]
22 ;        B[j+1] = 2       // backward dep between this and the previous
23 ;     }
24 ;   }
26 ; Since A[i] and A[i-1] are likely to be independent, getUnderlyingObjects
27 ; should not assume that Curr and Prev share the same underlying object.
29 ; If it did we would try to dependence-analyze Curr and Prev and the analysis
30 ; would fail with non-constant distance.
32 ; To illustrate one of the negative consequences of this, if the loop has a
33 ; backward dependence we won't detect this but instead fully fall back on
34 ; memchecks (that is what LAA does after encountering a case of non-constant
35 ; distance).
37 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
38 target triple = "x86_64-apple-macosx10.10.0"
40 ; CHECK-LABEL: function 'f'
41 ; CHECK: for_j.body:
42 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop
43 ; CHECK-NEXT: Dependences:
44 ; CHECK-NEXT: Backward:
45 ; CHECK-NEXT: %loadB = load i8, i8* %gepB, align 1 ->
46 ; CHECK-NEXT: store i8 2, i8* %gepB_plus_one, align 1
48 define void @f(i8** noalias %A, i8* noalias %B, i64 %N) {
49 for_i.preheader:
50   %prev_0 = load i8*, i8** %A, align 8
51   br label %for_i.body
53 for_i.body:
54   %i = phi i64 [1, %for_i.preheader], [%i.1, %for_j.end]
55   %prev = phi i8* [%prev_0, %for_i.preheader], [%curr, %for_j.end]
56   %gep = getelementptr inbounds i8*, i8** %A, i64 %i
57   %curr = load i8*, i8** %gep, align 8
58   br label %for_j.preheader
60 for_j.preheader:
61   br label %for_j.body
63 for_j.body:
64   %j = phi i64 [0, %for_j.preheader], [%j.1, %for_j.body]
66   %gepPrev = getelementptr inbounds i8, i8* %prev, i64 %j
67   %gepCurr = getelementptr inbounds i8, i8* %curr, i64 %j
68   %gepB = getelementptr inbounds i8, i8* %B, i64 %j
70   %loadPrev = load i8, i8* %gepPrev, align 1
71   %loadB = load i8, i8* %gepB, align 1
73   %mul = mul i8 %loadPrev, %loadB
75   store i8 %mul, i8* %gepCurr, align 1
77   %gepB_plus_one = getelementptr inbounds i8, i8* %gepB, i64 1
78   store i8 2, i8* %gepB_plus_one, align 1
80   %j.1 = add nuw i64 %j, 1
81   %exitcondj = icmp eq i64 %j.1, %N
82   br i1 %exitcondj, label %for_j.end, label %for_j.body
84 for_j.end:
86   %i.1 = add nuw i64 %i, 1
87   %exitcond = icmp eq i64 %i.1, %N
88   br i1 %exitcond, label %for_i.end, label %for_i.body
90 for_i.end:
91   ret void
94 ; CHECK-LABEL: function 'f_deep'
95 ; CHECK: for_j.body:
96 ; FIXME: This is incorrect and is going to be fixed with D86669.
97 ; CHECK-NEXT: Memory dependences are safe with run-time checks
98 ; CHECK-NEXT: Dependences:
100 define void @f_deep(i8** noalias %A, i8* noalias %B, i64 %N) {
101 for_i.preheader:
102   %prev_0 = load i8*, i8** %A, align 8
103   br label %for_i.body
105 for_i.body:
106   %i = phi i64 [1, %for_i.preheader], [%i.1, %for_j.end]
107   %prev = phi i8* [%prev_0, %for_i.preheader], [%curr, %for_j.end]
108   %gep = getelementptr inbounds i8*, i8** %A, i64 %i
109   %curr = load i8*, i8** %gep, align 8
110   br label %for_j.preheader
112 for_j.preheader:
113   br label %for_j.body
115 for_j.body:
116   %j = phi i64 [0, %for_j.preheader], [%j.1, %for_j.body]
118   %gepPrev = getelementptr inbounds i8, i8* %prev, i64 %j
119   %gepCurr = getelementptr inbounds i8, i8* %curr, i64 %j
120   %gepB = getelementptr inbounds i8, i8* %B, i64 %j
121   %gepB1 = getelementptr inbounds i8, i8* %gepB, i64 %j
122   %gepB2 = getelementptr inbounds i8, i8* %gepB1, i64 0
123   %gepB3 = getelementptr inbounds i8, i8* %gepB2, i64 0
124   %gepB4 = getelementptr inbounds i8, i8* %gepB3, i64 0
125   %gepB5 = getelementptr inbounds i8, i8* %gepB4, i64 0
126   %gepB6 = getelementptr inbounds i8, i8* %gepB5, i64 0
127   %gepB7 = getelementptr inbounds i8, i8* %gepB6, i64 0
128   %gepB8 = getelementptr inbounds i8, i8* %gepB7, i64 0
129   %gepB9 = getelementptr inbounds i8, i8* %gepB8, i64 0
131   %loadPrev = load i8, i8* %gepPrev, align 1
132   %loadB = load i8, i8* %gepB9, align 1
134   %mul = mul i8 %loadPrev, %loadB
136   store i8 %mul, i8* %gepCurr, align 1
138   %gepB_plus_one = getelementptr inbounds i8, i8* %gepB, i64 1
139   store i8 2, i8* %gepB_plus_one, align 1
141   %j.1 = add nuw i64 %j, 1
142   %exitcondj = icmp eq i64 %j.1, %N
143   br i1 %exitcondj, label %for_j.end, label %for_j.body
145 for_j.end:
147   %i.1 = add nuw i64 %i, 1
148   %exitcond = icmp eq i64 %i.1, %N
149   br i1 %exitcond, label %for_i.end, label %for_i.body
151 for_i.end:
152   ret void