llvm.org GIT mirror llvm / f2a1839
[DependenceAnalysis] Make sure base objects are the same when comparing GEPs The dependence analysis was returning incorrect information when using the GEPs to compute dependences. The analysis uses the GEP indices under certain conditions, but was doing it incorrectly when the base objects of the GEP are aliases, but pointing to different locations in the same array. This patch adds another check for the base objects. If the base pointer SCEVs are not equal, then the dependence analysis should fall back on the path that uses the whole SCEV for the dependence check. This fixes PR33567. Differential Revision: https://reviews.llvm.org/D34702 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307203 91177308-0d34-0410-b5e6-96231b3b80d8 Brendon Cahoon 2 years ago
2 changed file(s) with 82 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
33413341
33423342 UsefulGEP = isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
33433343 isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent())) &&
3344 (SrcGEP->getNumOperands() == DstGEP->getNumOperands());
3344 (SrcGEP->getNumOperands() == DstGEP->getNumOperands()) &&
3345 isKnownPredicate(CmpInst::ICMP_EQ, SrcPtrSCEV, DstPtrSCEV);
33453346 }
33463347 unsigned Pairs = UsefulGEP ? SrcGEP->idx_end() - SrcGEP->idx_begin() : 1;
33473348 SmallVector Pair(Pairs);
0 ; RUN: opt < %s -analyze -basicaa -da | FileCheck %s
1
2 ; Test that the dependence analysis generates the correct results when using
3 ; an aliased object that points to a different element in the same array.
4 ; PR33567 - https://bugs.llvm.org/show_bug.cgi?id=33567
5
6 ; void test1(int *A, int *B, int N) {
7 ; int *top = A;
8 ; int *bot = A + N/2;
9 ; for (int i = 0; i < N; i++)
10 ; B[i] = top[i] + bot[i];
11 ; }
12
13 ; CHECK-LABEL: test1
14 ; CHECK: da analyze - input [*|<]!
15
16 define void @test1(i32* nocapture %A, i32* nocapture %B, i32 %N) #0 {
17 entry:
18 %cmp9 = icmp sgt i32 %N, 0
19 br i1 %cmp9, label %for.body.lr.ph, label %for.end
20
21 for.body.lr.ph:
22 %div = sdiv i32 %N, 2
23 %bot.gep = getelementptr i32, i32* %A, i32 %div
24 br label %for.body
25
26 for.body:
27 %i = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
28 %gep.0 = getelementptr i32, i32* %A, i32 %i
29 %gep.1 = getelementptr i32, i32* %bot.gep, i32 %i
30 %gep.B = getelementptr i32, i32* %B, i32 %i
31 %0 = load i32, i32* %gep.0, align 4
32 %1 = load i32, i32* %gep.1, align 4
33 %add = add nsw i32 %1, %0
34 store i32 %add, i32* %gep.B, align 4
35 %inc = add nsw i32 %i, 1
36 %exitcond = icmp eq i32 %inc, %N
37 br i1 %exitcond, label %for.end, label %for.body
38
39 for.end:
40 ret void
41 }
42
43
44 ; void test2(int *A, unsigned n) {
45 ; int *B = A + 1;
46 ; for (unsigned i = 0; i < n; ++i) {
47 ; A[i] = B[i];
48 ; }
49 ; }
50
51 ; CHECK-LABEL: test2
52 ; CHECK: da analyze - consistent anti [1]!
53
54 define void @test2(i32*, i32) #3 {
55 %3 = getelementptr inbounds i32, i32* %0, i64 1
56 br label %4
57
58 ;
59 %.0 = phi i32 [ 0, %2 ], [ %14, %13 ]
60 %5 = sub i32 %1, 1
61 %6 = icmp ult i32 %.0, %5
62 br i1 %6, label %7, label %15
63
64 ;
65 %8 = zext i32 %.0 to i64
66 %9 = getelementptr inbounds i32, i32* %3, i64 %8
67 %10 = load i32, i32* %9, align 4
68 %11 = zext i32 %.0 to i64
69 %12 = getelementptr inbounds i32, i32* %0, i64 %11
70 store i32 %10, i32* %12, align 4
71 br label %13
72
73 ;
74 %14 = add i32 %.0, 1
75 br label %4
76
77 ;
78 ret void
79 }