2018-02-03 14:59:47 +08:00
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-mse -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-mse -pass-remarks-analysis="polly-mse" -analyze < %s 2>&1| FileCheck %s --check-prefix=MSE
[Polly][Bug fix] Wrong dependences filtering during Fully Indexed expansion
Summary:
When trying to expand memory accesses, the current version of Polly uses statement Level dependences. The actual implementation is not working in case of multiple dependences per statement. For example in the following source code :
```
void mse(double A[Ni], double B[Nj], double C[Nj], double D[Nj]) {
int i,j;
for (j = 0; j < Ni; j++) {
for (int i = 0; i<Nj; i++)
S: B[i] = i;
for (int i = 0; i<Nj; i++)
T: D[i] = i;
U: A[j] = B[j];
C[j] = D[j];
}
}
```
The statement U has two dependences with S and T. The current version of polly fails during expansion.
This patch aims to fix this bug. For that, we use Reference Level dependences to be able to filter dependences according to statement and memory ref. The principle of expansion remains the same as before.
We also noticed that we need to bail out if load come after store (at the same position) in same statement. So a check was added to isExpandable.
Contributed by: Nicholas Bonfante <nicolas.bonfante@insa-lyon.fr>
Reviewers: Meinersbur, simbuerg, bollu
Reviewed By: Meinersbur, simbuerg
Subscribers: pollydev, llvm-commits
Differential Revision: https://reviews.llvm.org/D36791
llvm-svn: 311165
2017-08-18 23:01:18 +08:00
;
; Verify that the expansion of an array with load after store in a same statement is not done.
;
; Original source code :
;
; #define Ni 2000
; #define Nj 3000
;
; void mse(double A[Ni], double B[Nj], double C[Nj], double D[Nj]) {
; int i,j;
; for (i = 0; i < Ni; i++) {
; for (int j = 0; j<Nj; j++) {
; B[j] = j;
; C[j] = B[j];
; }
; }
; }
;
; Check that C is expanded
;
; CHECK: i64 MemRef_C_Stmt_for_body4_expanded[10000][10000]; // Element size 8
; CHECK: new: { Stmt_for_body4[i0, i1] -> MemRef_C_Stmt_for_body4_expanded[i0, i1] };
;
; Check that B is not expanded
;
; CHECK-NOT: double MemRef_B_Stmt_for_body4_expanded[10000][10000]; // Element size 8
; MSE: MemRef_B has read after write to the same element in same statement. The dependences found during analysis may be wrong because Polly is not able to handle such case for now.
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @mse ( double * %A , double * %B , double * %C , double * %D ) {
entry:
br label %entry.split
entry.split: ; preds = %entry
br label %for.body
for.body: ; preds = %entry.split, %for.inc9
%i.02 = phi i32 [ 0 , %entry.split ] , [ %inc10 , %for.inc9 ]
br label %for.body4
for.body4: ; preds = %for.body, %for.body4
%indvars.iv = phi i64 [ 0 , %for.body ] , [ %indvars.iv.next , %for.body4 ]
%0 = trunc i64 %indvars.iv to i32
%conv = sitofp i32 %0 to double
%arrayidx = getelementptr inbounds double , double * %B , i64 %indvars.iv
store double %conv , double * %arrayidx , align 8
%arrayidx6 = getelementptr inbounds double , double * %B , i64 %indvars.iv
%1 = bitcast double * %arrayidx6 to i64 *
%2 = load i64 , i64 * %1 , align 8
%arrayidx8 = getelementptr inbounds double , double * %C , i64 %indvars.iv
%3 = bitcast double * %arrayidx8 to i64 *
store i64 %2 , i64 * %3 , align 8
%indvars.iv.next = add nuw nsw i64 %indvars.iv , 1
%exitcond = icmp ne i64 %indvars.iv.next , 10000
br i1 %exitcond , label %for.body4 , label %for.inc9
for.inc9: ; preds = %for.body4
%inc10 = add nuw nsw i32 %i.02 , 1
%exitcond3 = icmp ne i32 %inc10 , 10000
br i1 %exitcond3 , label %for.body , label %for.end11
for.end11: ; preds = %for.inc9
ret void
}