From 77bd5ae3d9b7735109ff4d5593a0417ad18f68f2 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Fri, 19 Sep 2014 08:49:02 +0000 Subject: [PATCH] [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 --- polly/lib/CodeGen/IslExprBuilder.cpp | 25 ++++++--- .../aliasing_different_pointer_types.ll | 51 +++++++++++++++++++ 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll diff --git a/polly/lib/CodeGen/IslExprBuilder.cpp b/polly/lib/CodeGen/IslExprBuilder.cpp index 18ba170dab9e..f8bf4b7553e6 100644 --- a/polly/lib/CodeGen/IslExprBuilder.cpp +++ b/polly/lib/CodeGen/IslExprBuilder.cpp @@ -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); diff --git a/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll b/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll new file mode 100644 index 000000000000..90e8d2b6eb02 --- /dev/null +++ b/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll @@ -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 +}