Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LAA] Try to prove non-wrapping of pointers if SCEV cannot
Summary: Scalar evolution does not propagate the non-wrapping flags to values that are derived from a non-wrapping induction variable because the non-wrapping property could be flow-sensitive. This change is a first attempt to establish the non-wrapping property in some simple cases. The main idea is to look through the operations defining the pointer. As long as we arrive to a non-wrapping AddRec via a small chain of non-wrapping instruction, the pointer should not wrap either. I believe that this essentially is what Andy described in http://article.gmane.org/gmane.comp.compilers.llvm.cvs/220731 as the way forward. Reviewers: aschwaighofer, nadav, sanjoy, atrick Reviewed By: atrick Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10472 llvm-svn: 240798
- Loading branch information
Showing
2 changed files
with
90 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
llvm/test/Analysis/LoopAccessAnalysis/non-wrapping-pointer.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s | ||
|
||
; For this loop: | ||
; for (int i = 0; i < n; i++) | ||
; A[2 * i] = A[2 * i] + B[i]; | ||
; | ||
; , SCEV is unable to prove that A[2 * i] does not overflow. However, | ||
; analyzing the IR helps us to conclude it and in turn allow dependence | ||
; analysis. | ||
|
||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" | ||
|
||
; CHECK: Memory dependences are safe{{$}} | ||
|
||
define void @f(i16* noalias %a, | ||
i16* noalias %b, i64 %N) { | ||
entry: | ||
br label %for.body | ||
|
||
for.body: ; preds = %for.body, %entry | ||
%ind = phi i64 [ 0, %entry ], [ %inc, %for.body ] | ||
|
||
%mul = mul nuw nsw i64 %ind, 2 | ||
|
||
%arrayidxA = getelementptr inbounds i16, i16* %a, i64 %mul | ||
%loadA = load i16, i16* %arrayidxA, align 2 | ||
|
||
%arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind | ||
%loadB = load i16, i16* %arrayidxB, align 2 | ||
|
||
%add = mul i16 %loadA, %loadB | ||
|
||
store i16 %add, i16* %arrayidxA, align 2 | ||
|
||
%inc = add nuw nsw i64 %ind, 1 | ||
%exitcond = icmp eq i64 %inc, %N | ||
br i1 %exitcond, label %for.end, label %for.body | ||
|
||
for.end: ; preds = %for.body | ||
ret void | ||
} |