[Fix] Allow pointer types as access elements and compare them correctly

This fixes two problems which are usualy caused together:
    1) The elements of an isl AST access expression could be pointers
       not only integers, floats and vectores thereof.
    2) The runtime alias checks need to compare pointers but if they
       are of a different type we need to cast them into a "max" type
       similar to the non pointer case.

llvm-svn: 218113
This commit is contained in:
Johannes Doerfert 2014-09-19 08:49:02 +00:00
parent 2e275142cd
commit 77bd5ae3d9
2 changed files with 68 additions and 8 deletions

View File

@ -130,7 +130,8 @@ Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) {
}
Indices.push_back(IndexOp);
assert((PtrElTy->isIntOrIntVectorTy() || PtrElTy->isFPOrFPVectorTy()) &&
assert((PtrElTy->isIntOrIntVectorTy() || PtrElTy->isFPOrFPVectorTy() ||
PtrElTy->isPtrOrPtrVectorTy()) &&
"We do not yet change the type of the access base during code "
"generation.");
@ -274,15 +275,23 @@ Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
assert((!IsPtrType || RHS->getType()->isPointerTy()) &&
"Both ICmp operators should be pointer types or none of them");
if (!IsPtrType) {
Type *MaxType = LHS->getType();
MaxType = getWidestType(MaxType, RHS->getType());
if (LHS->getType() != RHS->getType()) {
if (IsPtrType) {
Type *I8PtrTy = Builder.getInt8PtrTy();
if (LHS->getType() != I8PtrTy)
LHS = Builder.CreateBitCast(LHS, I8PtrTy);
if (RHS->getType() != I8PtrTy)
RHS = Builder.CreateBitCast(RHS, I8PtrTy);
} else {
Type *MaxType = LHS->getType();
MaxType = getWidestType(MaxType, RHS->getType());
if (MaxType != RHS->getType())
RHS = Builder.CreateSExt(RHS, MaxType);
if (MaxType != RHS->getType())
RHS = Builder.CreateSExt(RHS, MaxType);
if (MaxType != LHS->getType())
LHS = Builder.CreateSExt(LHS, MaxType);
if (MaxType != LHS->getType())
LHS = Builder.CreateSExt(LHS, MaxType);
}
}
isl_ast_op_type OpType = isl_ast_expr_get_op_type(Expr);

View File

@ -0,0 +1,51 @@
; RUN: opt %loadPolly -polly-code-generator=isl -polly-codegen-isl -S < %s | FileCheck %s
;
; Check that we cast the different pointer types correctly before we compare
; them in the RTC's. We use i8* as max pointer type.
;
; CHECK: entry:
; CHECK: %polly.access.B = getelementptr float** %B, i64 1024
; CHECK: %polly.access.A = getelementptr double** %A, i64 0
; CHECK: %[[paBb:[._a-zA-Z0-9]]] = bitcast float** %polly.access.B to i8*
; CHECK: %[[paAb:[._a-zA-Z0-9]]] = bitcast double** %polly.access.A to i8*
; CHECK: %[[ALeB:[._a-zA-Z0-9]]] = icmp ule i8* %[[paBb]], %[[paAb]]
; CHECK: %polly.access.A1 = getelementptr double** %A, i64 1024
; CHECK: %polly.access.B2 = getelementptr float** %B, i64 0
; CHECK: %[[paA1b:[._a-zA-Z0-9]]] = bitcast double** %polly.access.A1 to i8*
; CHECK: %[[paB2b:[._a-zA-Z0-9]]] = bitcast float** %polly.access.B2 to i8*
; CHECK: %[[A1LeB2:[._a-zA-Z0-9]]] = icmp ule i8* %[[paA1b]], %[[paB2b]]
; CHECK: %[[le1OrLe2:[._a-zA-Z0-9]]] = or i1 %[[ALeB]], %[[A1LeB2]]
; CHECK: %[[orAndTrue:[._a-zA-Z0-9]]] = and i1 true, %[[le1OrLe2]]
; CHECK: br label %polly.split_new_and_old
;
; void jd(double **A, float **B) {
; for (int i = 0; i < 1024; i++)
; A[i] = (double *)B[i];
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @jd(double** %A, float** %B) {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %for.body, label %for.end
for.body: ; preds = %for.cond
%arrayidx = getelementptr inbounds float** %B, i64 %indvars.iv
%tmp = load float** %arrayidx, align 8
%tmp1 = bitcast float* %tmp to double*
%arrayidx2 = getelementptr inbounds double** %A, i64 %indvars.iv
store double* %tmp1, double** %arrayidx2, align 8
br label %for.inc
for.inc: ; preds = %for.body
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}