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:
parent
5d23224f21
commit
c642e95402
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue