llvm-project/llvm/test/Transforms/LoopInterchange/interchange-no-deps.ll

96 lines
3.5 KiB
LLVM
Raw Normal View History

; REQUIRES: asserts
; RUN: opt < %s -loop-interchange -simplifycfg -pass-remarks-output=%t \
; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange -stats -S 2>&1 \
; RUN: | FileCheck -check-prefix=STATS %s
; RUN: FileCheck -input-file %t %s
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
; no_deps_interchange just accesses a single nested array and can be interchange.
; CHECK: Name: Interchanged
; CHECK-NEXT: Function: no_deps_interchange
define i32 @no_deps_interchange([1024 x i32]* nocapture %Arr) local_unnamed_addr #0 {
entry:
br label %for1.header
for1.header: ; preds = %entry, %for1.inc
%indvars.iv19 = phi i64 [ 0, %entry ], [ %indvars.iv.next20, %for1.inc ]
br label %for2
for2: ; preds = %for1.header, %for2
%indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next, %for2 ]
%arrayidx6 = getelementptr inbounds [1024 x i32], [1024 x i32]* %Arr, i64 %indvars.iv, i64 %indvars.iv19
store i32 0, i32* %arrayidx6, align 4
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond = icmp ne i64 %indvars.iv.next, 1024
br i1 %exitcond, label %for2, label %for1.inc
for1.inc:
%indvars.iv.next20 = add nuw nsw i64 %indvars.iv19, 1
%exitcond21 = icmp ne i64 %indvars.iv.next20, 1024
br i1 %exitcond21, label %for1.header, label %exit
exit: ; preds = %for1.inc
ret i32 0
}
; Only the inner loop induction variable is used for memory accesses.
; Interchanging is not beneficial.
; CHECK: Name: InterchangeNotProfitable
; CHECK-NEXT: Function: no_bad_order
define i32 @no_bad_order(i32* %Arr) {
entry:
br label %for1.header
for1.header: ; preds = %entry, %for1.inc
%indvars.iv19 = phi i64 [ 0, %entry ], [ %indvars.iv.next20, %for1.inc ]
br label %for2
for2: ; preds = %for1.header, %for2
%indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next, %for2 ]
%arrayidx6 = getelementptr inbounds i32, i32* %Arr, i64 %indvars.iv
store i32 0, i32* %arrayidx6, align 4
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond = icmp ne i64 %indvars.iv.next, 1024
br i1 %exitcond, label %for2, label %for1.inc
for1.inc:
%indvars.iv.next20 = add nuw nsw i64 %indvars.iv19, 1
%exitcond21 = icmp ne i64 %indvars.iv.next20, 1024
br i1 %exitcond21, label %for1.header, label %exit
exit: ; preds = %for1.inc
ret i32 0
}
; No memory access using any induction variables, interchanging not beneficial.
; CHECK: Name: InterchangeNotProfitable
; CHECK-NEXT: Function: no_mem_instrs
define i32 @no_mem_instrs(i64* %ptr) {
entry:
br label %for1.header
for1.header: ; preds = %entry, %for1.inc
%indvars.iv19 = phi i64 [ 0, %entry ], [ %indvars.iv.next20, %for1.inc ]
br label %for2
for2: ; preds = %for1.header, %for2
%indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next, %for2 ]
store i64 %indvars.iv, i64* %ptr, align 4
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond = icmp ne i64 %indvars.iv.next, 1024
br i1 %exitcond, label %for2, label %for1.inc
for1.inc:
%indvars.iv.next20 = add nuw nsw i64 %indvars.iv19, 1
%exitcond21 = icmp ne i64 %indvars.iv.next20, 1024
br i1 %exitcond21, label %for1.header, label %exit
exit: ; preds = %for1.inc
ret i32 0
}
; Check stats, we interchanged 1 out of 3 loops.
; STATS: 1 loop-interchange - Number of loops interchanged