Use types of matching size when generating multi-dimensional address expressions

This change ensures that the values that represent the array size of a
multi-dimensional access are correctly sign-extended when used to compute a
memory address used in the run-time alias check.

To make the test case more readable, we name the instructions that we generate.

llvm-svn: 225818
This commit is contained in:
Tobias Grosser 2015-01-13 19:37:59 +00:00
parent 5d23224f21
commit c642e95402
2 changed files with 54 additions and 3 deletions

View File

@ -127,7 +127,8 @@ Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) {
if (!IndexOp)
IndexOp = NextIndex;
else
IndexOp = Builder.CreateAdd(IndexOp, NextIndex);
IndexOp =
Builder.CreateAdd(IndexOp, NextIndex, "polly.access.add." + BaseName);
// For every but the last dimension multiply the size, for the last
// dimension we can exit the loop.
@ -135,9 +136,17 @@ Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) {
break;
const SCEV *DimSCEV = SAI->getDimensionSize(u - 1);
Value *DimSize = Expander.expandCodeFor(DimSCEV, IndexOp->getType(),
Value *DimSize = Expander.expandCodeFor(DimSCEV, DimSCEV->getType(),
Builder.GetInsertPoint());
IndexOp = Builder.CreateMul(IndexOp, DimSize);
Type *Ty = getWidestType(DimSize->getType(), IndexOp->getType());
if (Ty != IndexOp->getType())
IndexOp = Builder.CreateSExtOrTrunc(IndexOp, Ty,
"polly.access.sext." + BaseName);
IndexOp =
Builder.CreateMul(IndexOp, DimSize, "polly.access.mul." + BaseName);
}
Access = Builder.CreateGEP(Base, IndexOp, "polly.access." + BaseName);

View File

@ -0,0 +1,42 @@
; RUN: opt %loadPolly -polly-codegen-isl -polly-delinearize < %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK: %polly.access.sext.A = sext i32 %n to i64
; CHECK: %polly.access.mul.A = mul i64 %polly.access.sext.A, %0
; CHECK: %polly.access.add.A = add i64 %polly.access.mul.A, 1
; CHECK: %polly.access.A = getelementptr double* %A, i64 %polly.access.add.A
; CHECK: %polly.access.y = getelementptr double* %y, i64 0
; CHECK: icmp ule double* %polly.access.A, %polly.access.y
define void @init_array(i32 %n, double* %A, double* %y) {
entry:
%add3 = add nsw i32 %n, 1
%tmp = zext i32 %add3 to i64
br label %for.body
for.body:
%i.04 = phi i32 [ %inc39, %for.cond.loopexit ], [ 0, %entry ]
%arrayidx16 = getelementptr inbounds double* %y, i64 0
store double 1.0, double* %arrayidx16
%cmp251 = icmp slt i32 %n, 0
%inc39 = add nsw i32 %i.04, 1
br i1 %cmp251, label %for.cond.loopexit, label %for.body27
for.body27:
%idxprom35 = sext i32 %i.04 to i64
%tmp1 = mul nsw i64 %idxprom35, %tmp
%arrayidx36.sum = add i64 0, %tmp1
%arrayidx37 = getelementptr inbounds double* %A, i64 %arrayidx36.sum
store double 1.0, double* %arrayidx37
br label %for.cond.loopexit
for.cond.loopexit:
%cmp = icmp slt i32 %i.04, %n
br i1 %cmp, label %for.body, label %for.end40
for.end40:
ret void
}