2019-01-08 22:06:58 +08:00
|
|
|
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
|
|
|
|
; RUN: | FileCheck %s -check-prefix=DELIN
|
2020-06-27 11:41:37 +08:00
|
|
|
; RUN: opt < %s -analyze -basic-aa -da | FileCheck %s -check-prefix=DELIN
|
[DependenceAnalysis] Allow subscripts of different types
Summary:
Several places in DependenceAnalysis assumes both SCEVs in a subscript pair
share the same integer type. For instance, isKnownPredicate calls
SE->getMinusSCEV(X, Y) which asserts X and Y share the same type. However,
DependenceAnalysis fails to ensure this assumption when producing a subscript
pair, causing tests such as NonCanonicalizedSubscript to crash. With this
patch, DependenceAnalysis runs unifySubscriptType before producing any
subscript pair, ensuring the assumption.
Test Plan:
Added NonCanonicalizedSubscript.ll on which DependenceAnalysis before the fix
crashed because subscripts have different types.
Reviewers: spop, sebpop, jingyue
Reviewed By: jingyue
Subscribers: eliben, meheff, llvm-commits
Differential Revision: http://reviews.llvm.org/D6289
llvm-svn: 222100
2014-11-17 00:52:44 +08:00
|
|
|
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
|
|
|
target triple = "x86_64-apple-macosx10.6.0"
|
|
|
|
|
|
|
|
; for (int i = 0; i < 100; ++i) {
|
|
|
|
; int t0 = a[i][i];
|
|
|
|
; int t1 = t0 + 1;
|
|
|
|
; a[i][5] = t1;
|
|
|
|
; }
|
|
|
|
; The subscript 5 in a[i][5] is deliberately an i32, mismatching the types of
|
|
|
|
; other subscript. DependenceAnalysis before the fix crashed due to this
|
|
|
|
; mismatch.
|
|
|
|
define void @i32_subscript([100 x [100 x i32]]* %a, i32* %b) {
|
|
|
|
; DELIN-LABEL: 'Dependence Analysis' for function 'i32_subscript'
|
|
|
|
entry:
|
|
|
|
br label %for.body
|
|
|
|
|
|
|
|
for.body:
|
|
|
|
; DELIN: da analyze - none!
|
|
|
|
; DELIN: da analyze - anti [=|<]!
|
|
|
|
; DELIN: da analyze - none!
|
|
|
|
%i = phi i64 [ 0, %entry ], [ %i.inc, %for.body ]
|
[opaque pointer type] Add textual IR support for explicit type parameter to getelementptr instruction
One of several parallel first steps to remove the target type of pointers,
replacing them with a single opaque pointer type.
This adds an explicit type parameter to the gep instruction so that when the
first parameter becomes an opaque pointer type, the type to gep through is
still available to the instructions.
* This doesn't modify gep operators, only instructions (operators will be
handled separately)
* Textual IR changes only. Bitcode (including upgrade) and changing the
in-memory representation will be in separate changes.
* geps of vectors are transformed as:
getelementptr <4 x float*> %x, ...
->getelementptr float, <4 x float*> %x, ...
Then, once the opaque pointer type is introduced, this will ultimately look
like:
getelementptr float, <4 x ptr> %x
with the unambiguous interpretation that it is a vector of pointers to float.
* address spaces remain on the pointer, not the type:
getelementptr float addrspace(1)* %x
->getelementptr float, float addrspace(1)* %x
Then, eventually:
getelementptr float, ptr addrspace(1) %x
Importantly, the massive amount of test case churn has been automated by
same crappy python code. I had to manually update a few test cases that
wouldn't fit the script's model (r228970,r229196,r229197,r229198). The
python script just massages stdin and writes the result to stdout, I
then wrapped that in a shell script to handle replacing files, then
using the usual find+xargs to migrate all the files.
update.py:
import fileinput
import sys
import re
ibrep = re.compile(r"(^.*?[^%\w]getelementptr inbounds )(((?:<\d* x )?)(.*?)(| addrspace\(\d\)) *\*(|>)(?:$| *(?:%|@|null|undef|blockaddress|getelementptr|addrspacecast|bitcast|inttoptr|\[\[[a-zA-Z]|\{\{).*$))")
normrep = re.compile( r"(^.*?[^%\w]getelementptr )(((?:<\d* x )?)(.*?)(| addrspace\(\d\)) *\*(|>)(?:$| *(?:%|@|null|undef|blockaddress|getelementptr|addrspacecast|bitcast|inttoptr|\[\[[a-zA-Z]|\{\{).*$))")
def conv(match, line):
if not match:
return line
line = match.groups()[0]
if len(match.groups()[5]) == 0:
line += match.groups()[2]
line += match.groups()[3]
line += ", "
line += match.groups()[1]
line += "\n"
return line
for line in sys.stdin:
if line.find("getelementptr ") == line.find("getelementptr inbounds"):
if line.find("getelementptr inbounds") != line.find("getelementptr inbounds ("):
line = conv(re.match(ibrep, line), line)
elif line.find("getelementptr ") != line.find("getelementptr ("):
line = conv(re.match(normrep, line), line)
sys.stdout.write(line)
apply.sh:
for name in "$@"
do
python3 `dirname "$0"`/update.py < "$name" > "$name.tmp" && mv "$name.tmp" "$name"
rm -f "$name.tmp"
done
The actual commands:
From llvm/src:
find test/ -name *.ll | xargs ./apply.sh
From llvm/src/tools/clang:
find test/ -name *.mm -o -name *.m -o -name *.cpp -o -name *.c | xargs -I '{}' ../../apply.sh "{}"
From llvm/src/tools/polly:
find test/ -name *.ll | xargs ./apply.sh
After that, check-all (with llvm, clang, clang-tools-extra, lld,
compiler-rt, and polly all checked out).
The extra 'rm' in the apply.sh script is due to a few files in clang's test
suite using interesting unicode stuff that my python script was throwing
exceptions on. None of those files needed to be migrated, so it seemed
sufficient to ignore those cases.
Reviewers: rafael, dexonsmith, grosser
Differential Revision: http://reviews.llvm.org/D7636
llvm-svn: 230786
2015-02-28 03:29:02 +08:00
|
|
|
%a.addr = getelementptr [100 x [100 x i32]], [100 x [100 x i32]]* %a, i64 0, i64 %i, i64 %i
|
|
|
|
%a.addr.2 = getelementptr [100 x [100 x i32]], [100 x [100 x i32]]* %a, i64 0, i64 %i, i32 5
|
2015-02-28 05:17:42 +08:00
|
|
|
%0 = load i32, i32* %a.addr, align 4
|
[DependenceAnalysis] Allow subscripts of different types
Summary:
Several places in DependenceAnalysis assumes both SCEVs in a subscript pair
share the same integer type. For instance, isKnownPredicate calls
SE->getMinusSCEV(X, Y) which asserts X and Y share the same type. However,
DependenceAnalysis fails to ensure this assumption when producing a subscript
pair, causing tests such as NonCanonicalizedSubscript to crash. With this
patch, DependenceAnalysis runs unifySubscriptType before producing any
subscript pair, ensuring the assumption.
Test Plan:
Added NonCanonicalizedSubscript.ll on which DependenceAnalysis before the fix
crashed because subscripts have different types.
Reviewers: spop, sebpop, jingyue
Reviewed By: jingyue
Subscribers: eliben, meheff, llvm-commits
Differential Revision: http://reviews.llvm.org/D6289
llvm-svn: 222100
2014-11-17 00:52:44 +08:00
|
|
|
%1 = add i32 %0, 1
|
|
|
|
store i32 %1, i32* %a.addr.2, align 4
|
|
|
|
%i.inc = add nsw i64 %i, 1
|
|
|
|
%exitcond = icmp ne i64 %i.inc, 100
|
|
|
|
br i1 %exitcond, label %for.body, label %for.end
|
|
|
|
|
|
|
|
for.end:
|
|
|
|
ret void
|
|
|
|
}
|
2015-05-30 00:58:08 +08:00
|
|
|
|
|
|
|
; unsigned i, j;
|
|
|
|
; for (i = 1; i < SIZE; i++) {
|
|
|
|
; for (j = i; j < SIZE; j++) {
|
|
|
|
; a[i][j] = a[i+1][j-1] + 2;
|
|
|
|
; }
|
|
|
|
; }
|
|
|
|
; Extends the previous example to coupled MIV subscripts.
|
|
|
|
|
|
|
|
|
|
|
|
@a = global [10004 x [10004 x i32]] zeroinitializer, align 16
|
|
|
|
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
|
|
define void @coupled_miv_type_mismatch(i32 %n) #0 {
|
|
|
|
; DELIN-LABEL: 'Dependence Analysis' for function 'coupled_miv_type_mismatch'
|
|
|
|
entry:
|
|
|
|
br label %for.cond
|
|
|
|
|
DA: remove uses of GEP, only ask SCEV
It's been quite some time the Dependence Analysis (DA) is broken,
as it uses the GEP representation to "identify" multi-dimensional arrays.
It even wrongly detects multi-dimensional arrays in single nested loops:
from test/Analysis/DependenceAnalysis/Coupled.ll, example @couple6
;; for (long int i = 0; i < 50; i++) {
;; A[i][3*i - 6] = i;
;; *B++ = A[i][i];
DA used to detect two subscripts, which makes no sense in the LLVM IR
or in C/C++ semantics, as there are no guarantees as in Fortran of
subscripts not overlapping into a next array dimension:
maximum nesting levels = 1
SrcPtrSCEV = %A
DstPtrSCEV = %A
using GEPs
subscript 0
src = {0,+,1}<nuw><nsw><%for.body>
dst = {0,+,1}<nuw><nsw><%for.body>
class = 1
loops = {1}
subscript 1
src = {-6,+,3}<nsw><%for.body>
dst = {0,+,1}<nuw><nsw><%for.body>
class = 1
loops = {1}
Separable = {}
Coupled = {1}
With the current patch, DA will correctly work on only one dimension:
maximum nesting levels = 1
SrcSCEV = {(-2424 + %A)<nsw>,+,1212}<%for.body>
DstSCEV = {%A,+,404}<%for.body>
subscript 0
src = {(-2424 + %A)<nsw>,+,1212}<%for.body>
dst = {%A,+,404}<%for.body>
class = 1
loops = {1}
Separable = {0}
Coupled = {}
This change removes all uses of GEP from DA, and we now only rely
on the SCEV representation.
The patch does not turn on -da-delinearize by default, and so the DA analysis
will be more conservative in the case of multi-dimensional memory accesses in
nested loops.
I disabled some interchange tests, as the DA is not able to disambiguate
the dependence anymore. To make DA stronger, we may need to
compute a bound on the number of iterations based on the access functions
and array dimensions.
The patch cleans up all the CHECKs in test/Transforms/LoopInterchange/*.ll to
avoid checking for snippets of LLVM IR: this form of checking is very hard to
maintain. Instead, we now check for output of the pass that are more meaningful
than dozens of lines of LLVM IR. Some tests now require -debug messages and thus
only enabled with asserts.
Patch written by Sebastian Pop and Aditya Kumar.
Differential Revision: https://reviews.llvm.org/D35430
llvm-svn: 326837
2018-03-07 05:55:59 +08:00
|
|
|
; DELIN: da analyze - input [* *]!
|
|
|
|
; DELIN: da analyze - anti [* *|<]!
|
2015-05-30 00:58:08 +08:00
|
|
|
; DELIN: da analyze - none!
|
|
|
|
for.cond: ; preds = %for.inc11, %entry
|
|
|
|
%indvars.iv11 = phi i64 [ %indvars.iv.next12, %for.inc11 ], [ 1, %entry ]
|
|
|
|
%exitcond14 = icmp ne i64 %indvars.iv11, 10000
|
|
|
|
br i1 %exitcond14, label %for.cond1.preheader, label %for.end13
|
|
|
|
|
|
|
|
for.cond1.preheader: ; preds = %for.cond
|
|
|
|
%0 = trunc i64 %indvars.iv11 to i32
|
|
|
|
br label %for.cond1
|
|
|
|
|
|
|
|
for.cond1: ; preds = %for.cond1.preheader, %for.body3
|
|
|
|
%indvars.iv8 = phi i64 [ %indvars.iv11, %for.cond1.preheader ], [ %indvars.iv.next9, %for.body3 ]
|
|
|
|
%j.0 = phi i32 [ %inc, %for.body3 ], [ %0, %for.cond1.preheader ]
|
|
|
|
%lftr.wideiv = trunc i64 %indvars.iv8 to i32
|
|
|
|
%exitcond = icmp ne i32 %lftr.wideiv, 10000
|
|
|
|
br i1 %exitcond, label %for.body3, label %for.inc11
|
|
|
|
|
|
|
|
for.body3: ; preds = %for.cond1
|
|
|
|
%sub = add nsw i32 %j.0, -1
|
|
|
|
%idxprom = zext i32 %sub to i64
|
|
|
|
%1 = add nuw nsw i64 %indvars.iv11, 1
|
|
|
|
%arrayidx5 = getelementptr inbounds [10004 x [10004 x i32]], [10004 x [10004 x i32]]* @a, i64 0, i64 %1, i64 %idxprom
|
|
|
|
%2 = load i32, i32* %arrayidx5, align 4
|
|
|
|
%add6 = add nsw i32 %2, 2
|
|
|
|
%arrayidx10 = getelementptr inbounds [10004 x [10004 x i32]], [10004 x [10004 x i32]]* @a, i64 0, i64 %indvars.iv11, i64 %indvars.iv8
|
|
|
|
store i32 %add6, i32* %arrayidx10, align 4
|
|
|
|
%indvars.iv.next9 = add nuw nsw i64 %indvars.iv8, 1
|
|
|
|
%inc = add nuw nsw i32 %j.0, 1
|
|
|
|
br label %for.cond1
|
|
|
|
|
|
|
|
for.inc11: ; preds = %for.cond1
|
|
|
|
%indvars.iv.next12 = add nuw nsw i64 %indvars.iv11, 1
|
|
|
|
br label %for.cond
|
|
|
|
|
|
|
|
for.end13: ; preds = %for.cond
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2019-12-25 07:52:21 +08:00
|
|
|
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
2015-05-30 00:58:08 +08:00
|
|
|
|
|
|
|
!llvm.ident = !{!0}
|
|
|
|
|
2019-01-16 00:18:52 +08:00
|
|
|
!0 = !{!"clang version 3.7.0"}
|