From 5a5ac124e1efaf208671f01c46edb15f29ed2a0b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 27 May 2015 18:44:32 +0000 Subject: Vendor import of llvm trunk r238337: https://llvm.org/svn/llvm-project/llvm/trunk@238337 --- .../LoopAccessAnalysis/underlying-objects-2.ll | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll (limited to 'test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll') diff --git a/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll b/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll new file mode 100644 index 0000000000000..d0bed68188dbc --- /dev/null +++ b/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll @@ -0,0 +1,90 @@ +; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s + +; This loop: +; +; int **A; +; for (i) +; for (j) { +; A[i][j] = A[i-1][j] * B[j] +; B[j+1] = 2 // backward dep between this and the previous +; } +; +; is transformed by Load-PRE to stash away A[i] for the next iteration of the +; outer loop: +; +; Curr = A[0]; // Prev_0 +; for (i: 1..N) { +; Prev = Curr; // Prev = PHI (Prev_0, Curr) +; Curr = A[i]; +; for (j: 0..N) { +; Curr[j] = Prev[j] * B[j] +; B[j+1] = 2 // backward dep between this and the previous +; } +; } +; +; Since A[i] and A[i-1] are likely to be independent, getUnderlyingObjects +; should not assume that Curr and Prev share the same underlying object. +; +; If it did we would try to dependence-analyze Curr and Prev and the analysis +; would fail with non-constant distance. +; +; To illustrate one of the negative consequences of this, if the loop has a +; backward dependence we won't detect this but instead fully fall back on +; memchecks (that is what LAA does after encountering a case of non-constant +; distance). + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.10.0" + +; CHECK: for_j.body: +; CHECK-NEXT: Report: unsafe dependent memory operations in loop +; CHECK-NEXT: Interesting Dependences: +; CHECK-NEXT: Backward: +; CHECK-NEXT: %loadB = load i8, i8* %gepB, align 1 -> +; CHECK-NEXT: store i8 2, i8* %gepB_plus_one, align 1 + +define void @f(i8** noalias %A, i8* noalias %B, i64 %N) { +for_i.preheader: + %prev_0 = load i8*, i8** %A, align 8 + br label %for_i.body + +for_i.body: + %i = phi i64 [1, %for_i.preheader], [%i.1, %for_j.end] + %prev = phi i8* [%prev_0, %for_i.preheader], [%curr, %for_j.end] + %gep = getelementptr inbounds i8*, i8** %A, i64 %i + %curr = load i8*, i8** %gep, align 8 + br label %for_j.preheader + +for_j.preheader: + br label %for_j.body + +for_j.body: + %j = phi i64 [0, %for_j.preheader], [%j.1, %for_j.body] + + %gepPrev = getelementptr inbounds i8, i8* %prev, i64 %j + %gepCurr = getelementptr inbounds i8, i8* %curr, i64 %j + %gepB = getelementptr inbounds i8, i8* %B, i64 %j + + %loadPrev = load i8, i8* %gepPrev, align 1 + %loadB = load i8, i8* %gepB, align 1 + + %mul = mul i8 %loadPrev, %loadB + + store i8 %mul, i8* %gepCurr, align 1 + + %gepB_plus_one = getelementptr inbounds i8, i8* %gepB, i64 1 + store i8 2, i8* %gepB_plus_one, align 1 + + %j.1 = add nuw i64 %j, 1 + %exitcondj = icmp eq i64 %j.1, %N + br i1 %exitcondj, label %for_j.end, label %for_j.body + +for_j.end: + + %i.1 = add nuw i64 %i, 1 + %exitcond = icmp eq i64 %i.1, %N + br i1 %exitcond, label %for_i.end, label %for_i.body + +for_i.end: + ret void +} -- cgit v1.2.3