From 561d36b32011407383ad9f439fe1144101e05092 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Sun, 10 Apr 2016 09:50:10 +0000 Subject: [PATCH] Allow pointer expressions in SCEVs again. In r247147 we disabled pointer expressions because the IslExprBuilder did not fully support them. This patch reintroduces them by simply treating them as integers. The only special handling for pointers that is left detects the comparison of two address_of operands and uses an unsigned compare. llvm-svn: 265894 --- polly/lib/Analysis/ScopDetection.cpp | 6 - polly/lib/CodeGen/IslExprBuilder.cpp | 116 +++++------------- polly/lib/Support/SCEVValidator.cpp | 12 +- .../test/Isl/CodeGen/20120316-InvalidCast.ll | 5 - .../Isl/CodeGen/MemAccess/different_types.ll | 9 +- .../Isl/CodeGen/MemAccess/multiple_types.ll | 16 +-- .../aliasing_different_pointer_types.ll | 12 +- .../CodeGen/aliasing_parametric_simple_1.ll | 8 +- .../CodeGen/aliasing_parametric_simple_2.ll | 8 +- .../Isl/CodeGen/pointer-type-expressions-2.ll | 15 +-- .../Isl/CodeGen/pointer-type-expressions.ll | 14 +-- .../pointer-type-pointer-type-comparison.ll | 21 ++-- .../ScopInfo/pointer-comparison-no-nsw.ll | 39 ++++++ polly/test/ScopInfo/pointer-comparison.ll | 38 ++++++ .../test/ScopInfo/pointer-type-expressions.ll | 19 +-- 15 files changed, 172 insertions(+), 166 deletions(-) create mode 100644 polly/test/ScopInfo/pointer-comparison-no-nsw.ll create mode 100644 polly/test/ScopInfo/pointer-comparison.ll diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 8fe33db1c38c..e5914df44f12 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -399,12 +399,6 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI, isa(ICmp->getOperand(1))) return invalid(Context, /*Assert=*/true, &BB, ICmp); - // TODO: FIXME: IslExprBuilder is not capable of producing valid code - // for arbitrary pointer expressions at the moment. Until - // this is fixed we disallow pointer expressions completely. - if (ICmp->getOperand(0)->getType()->isPointerTy()) - return false; - Loop *L = LI->getLoopFor(ICmp->getParent()); const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L); const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L); diff --git a/polly/lib/CodeGen/IslExprBuilder.cpp b/polly/lib/CodeGen/IslExprBuilder.cpp index e1f9b8563e4e..912eb3984b6b 100644 --- a/polly/lib/CodeGen/IslExprBuilder.cpp +++ b/polly/lib/CodeGen/IslExprBuilder.cpp @@ -186,7 +186,6 @@ Value *IslExprBuilder::createOpAccess(isl_ast_expr *Expr) { Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) { Value *LHS, *RHS, *Res; Type *MaxType; - isl_ast_expr *LOp, *ROp; isl_ast_op_type OpType; assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op && @@ -196,68 +195,12 @@ Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) { OpType = isl_ast_expr_get_op_type(Expr); - LOp = isl_ast_expr_get_op_arg(Expr, 0); - ROp = isl_ast_expr_get_op_arg(Expr, 1); - - // Catch the special case ((-) + ) which is for - // isl the same as ( - ). We have to treat it here because - // there is no valid semantics for the (-) expression, hence in - // createOpUnary such an expression will trigger a crash. - // FIXME: The same problem can now be triggered by a subexpression of the LHS, - // however it is much less likely. - if (OpType == isl_ast_op_add && - isl_ast_expr_get_type(LOp) == isl_ast_expr_op && - isl_ast_expr_get_op_type(LOp) == isl_ast_op_minus) { - // Change the binary addition to a substraction. - OpType = isl_ast_op_sub; - - // Extract the unary operand of the LHS. - auto *LOpOp = isl_ast_expr_get_op_arg(LOp, 0); - isl_ast_expr_free(LOp); - - // Swap the unary operand of the LHS and the RHS. - LOp = ROp; - ROp = LOpOp; - } - - LHS = create(LOp); - RHS = create(ROp); + LHS = create(isl_ast_expr_get_op_arg(Expr, 0)); + RHS = create(isl_ast_expr_get_op_arg(Expr, 1)); Type *LHSType = LHS->getType(); Type *RHSType = RHS->getType(); - // Handle - - if (LHSType->isPointerTy() && RHSType->isPointerTy()) { - isl_ast_expr_free(Expr); - assert(OpType == isl_ast_op_sub && "Substraction is the only valid binary " - "pointer <-> pointer operation."); - - return Builder.CreatePtrDiff(LHS, RHS); - } - - // Handle +/- and +/- - if (LHSType->isPointerTy() || RHSType->isPointerTy()) { - isl_ast_expr_free(Expr); - - assert((LHSType->isIntegerTy() || RHSType->isIntegerTy()) && - "Arithmetic operations might only performed on one but not two " - "pointer types."); - - if (LHSType->isIntegerTy()) - std::swap(LHS, RHS); - - switch (OpType) { - default: - llvm_unreachable( - "Only additive binary operations are allowed on pointer types."); - case isl_ast_op_sub: - RHS = Builder.CreateNeg(RHS); - // Fall through - case isl_ast_op_add: - return Builder.CreateGEP(LHS, RHS); - } - } - MaxType = getWidestType(LHSType, RHSType); // Take the result into account when calculating the widest type. @@ -380,33 +323,37 @@ Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) { Value *LHS, *RHS, *Res; - LHS = create(isl_ast_expr_get_op_arg(Expr, 0)); - RHS = create(isl_ast_expr_get_op_arg(Expr, 1)); + auto *Op0 = isl_ast_expr_get_op_arg(Expr, 0); + auto *Op1 = isl_ast_expr_get_op_arg(Expr, 1); + bool HasNonAddressOfOperand = + isl_ast_expr_get_type(Op0) != isl_ast_expr_op || + isl_ast_expr_get_type(Op1) != isl_ast_expr_op || + isl_ast_expr_get_op_type(Op0) != isl_ast_op_address_of || + isl_ast_expr_get_op_type(Op1) != isl_ast_op_address_of; - bool IsPtrType = - LHS->getType()->isPointerTy() || RHS->getType()->isPointerTy(); + LHS = create(Op0); + RHS = create(Op1); + + auto *LHSTy = LHS->getType(); + auto *RHSTy = RHS->getType(); + bool IsPtrType = LHSTy->isPointerTy() || RHSTy->isPointerTy(); + bool UseUnsignedCmp = IsPtrType && !HasNonAddressOfOperand; + + auto *PtrAsIntTy = Builder.getIntNTy(DL.getPointerSizeInBits()); + if (LHSTy->isPointerTy()) + LHS = Builder.CreatePtrToInt(LHS, PtrAsIntTy); + if (RHSTy->isPointerTy()) + RHS = Builder.CreatePtrToInt(RHS, PtrAsIntTy); if (LHS->getType() != RHS->getType()) { - if (IsPtrType) { - Type *I8PtrTy = Builder.getInt8PtrTy(); - if (!LHS->getType()->isPointerTy()) - LHS = Builder.CreateIntToPtr(LHS, I8PtrTy); - if (!RHS->getType()->isPointerTy()) - RHS = Builder.CreateIntToPtr(RHS, I8PtrTy); - 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()); + 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); @@ -423,8 +370,8 @@ Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) { {CmpInst::ICMP_SGT, CmpInst::ICMP_UGT}, }; - Res = Builder.CreateICmp(Predicates[OpType - isl_ast_op_eq][IsPtrType], LHS, - RHS); + Res = Builder.CreateICmp(Predicates[OpType - isl_ast_op_eq][UseUnsignedCmp], + LHS, RHS); isl_ast_expr_free(Expr); return Res; @@ -615,6 +562,9 @@ Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) { if (!V) V = UndefValue::get(getType(Expr)); + if (V->getType()->isPointerTy()) + V = Builder.CreatePtrToInt(V, Builder.getIntNTy(DL.getPointerSizeInBits())); + assert(V && "Unknown parameter id found"); isl_id_free(Id); diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp index 48782217dad4..dc2886efaef8 100644 --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -386,16 +386,8 @@ public: ValidatorResult visitUnknown(const SCEVUnknown *Expr) { Value *V = Expr->getValue(); - // TODO: FIXME: IslExprBuilder is not capable of producing valid code - // for arbitrary pointer expressions at the moment. Until - // this is fixed we disallow pointer expressions completely. - if (Expr->getType()->isPointerTy()) { - DEBUG(dbgs() << "INVALID: UnknownExpr is a pointer type [FIXME]"); - return ValidatorResult(SCEVType::INVALID); - } - - if (!Expr->getType()->isIntegerTy()) { - DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer"); + if (!Expr->getType()->isIntegerTy() && !Expr->getType()->isPointerTy()) { + DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer or pointer"); return ValidatorResult(SCEVType::INVALID); } diff --git a/polly/test/Isl/CodeGen/20120316-InvalidCast.ll b/polly/test/Isl/CodeGen/20120316-InvalidCast.ll index 2d4343fb88e9..165b9102f04f 100644 --- a/polly/test/Isl/CodeGen/20120316-InvalidCast.ll +++ b/polly/test/Isl/CodeGen/20120316-InvalidCast.ll @@ -1,10 +1,5 @@ ; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s -; TODO: FIXME: IslExprBuilder is not capable of producing valid code -; for arbitrary pointer expressions at the moment. Until -; this is fixed we disallow pointer expressions completely. -; XFAIL: * - ; CHECK: polly.start target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32" diff --git a/polly/test/Isl/CodeGen/MemAccess/different_types.ll b/polly/test/Isl/CodeGen/MemAccess/different_types.ll index ec1e109ba65b..527c6ceaa00f 100644 --- a/polly/test/Isl/CodeGen/MemAccess/different_types.ll +++ b/polly/test/Isl/CodeGen/MemAccess/different_types.ll @@ -10,10 +10,11 @@ ; } ; CHECK: %polly.access.cast.A14 = bitcast float* %A to i32* -; CHECK: %5 = sub nsw i64 99, %polly.indvar11 -; CHECK: %polly.access.A15 = getelementptr i32, i32* %polly.access.cast.A14, i64 %5 -; CHECK: %6 = bitcast i32* %polly.access.A15 to float* -; CHECK: %tmp14_p_scalar_ = load float, float* %6, align 4, !alias.scope !3, !noalias !4 +; CHECK: %[[R1:[._0-9]*]] = sub nsw i64 0, %polly.indvar11 +; CHECK: %[[R2:[._0-9]*]] = add nsw i64 %[[R1]], 99 +; CHECK: %polly.access.A15 = getelementptr i32, i32* %polly.access.cast.A14, i64 %[[R2]] +; CHECK: %[[R3:[._0-9]*]] = bitcast i32* %polly.access.A15 to float* +; CHECK: %tmp14_p_scalar_ = load float, float* %[[R3]], align 4, !alias.scope !3, !noalias !4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll b/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll index 816ff2281376..9a97e3f73858 100644 --- a/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll +++ b/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll @@ -13,19 +13,19 @@ ; Short[0] ; CHECK: %polly.access.Short10 = getelementptr i8, i8* %Short, i64 0 -; CHECK: %12 = bitcast i8* %polly.access.Short10 to i16* -; CHECK: %tmp5_p_scalar_ = load i16, i16* %12 +; CHECK: %24 = bitcast i8* %polly.access.Short10 to i16* +; CHECK: %tmp5_p_scalar_ = load i16, i16* %24 ; Float[8 * i] -; CHECK: %13 = mul nsw i64 8, %polly.indvar -; CHECK: %polly.access.Float11 = getelementptr i8, i8* %Float, i64 %13 -; CHECK: %14 = bitcast i8* %polly.access.Float11 to float* -; CHECK: %tmp11_p_scalar_ = load float, float* %14 +; CHECK: %25 = mul nsw i64 8, %polly.indvar +; CHECK: %polly.access.Float11 = getelementptr i8, i8* %Float, i64 %25 +; CHECK: %26 = bitcast i8* %polly.access.Float11 to float* +; CHECK: %tmp11_p_scalar_ = load float, float* %26 ; Double[8] ; CHECK: %polly.access.Double13 = getelementptr i8, i8* %Double, i64 8 -; CHECK: %15 = bitcast i8* %polly.access.Double13 to double* -; CHECK: %tmp17_p_scalar_ = load double, double* %15 +; CHECK: %27 = bitcast i8* %polly.access.Double13 to double* +; CHECK: %tmp17_p_scalar_ = load double, double* %27 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll b/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll index 910f64223408..43a06bf090eb 100644 --- a/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll +++ b/polly/test/Isl/CodeGen/aliasing_different_pointer_types.ll @@ -6,14 +6,14 @@ ; CHECK: polly.split_new_and_old: ; CHECK: %polly.access.B = getelementptr float*, float** %B, i64 1024 ; CHECK: %polly.access.A = getelementptr double*, 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: %[[paBb:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B to i64 +; CHECK: %[[paAb:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A to i64 +; CHECK: %[[ALeB:[._a-zA-Z0-9]]] = icmp ule i64 %[[paBb]], %[[paAb]] ; CHECK: %polly.access.A1 = getelementptr double*, double** %A, i64 1024 ; CHECK: %polly.access.B2 = getelementptr float*, 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: %[[paA1b:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A1 to i64 +; CHECK: %[[paB2b:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B2 to i64 +; CHECK: %[[A1LeB2:[._a-zA-Z0-9]]] = icmp ule i64 %[[paA1b]], %[[paB2b]] ; CHECK: %[[le1OrLe2:[._a-zA-Z0-9]]] = or i1 %[[ALeB]], %[[A1LeB2]] ; CHECK: %[[orAndTrue:[._a-zA-Z0-9]]] = and i1 true, %[[le1OrLe2]] ; diff --git a/polly/test/Isl/CodeGen/aliasing_parametric_simple_1.ll b/polly/test/Isl/CodeGen/aliasing_parametric_simple_1.ll index 0de39f52fa42..1d5ad9a0f17a 100644 --- a/polly/test/Isl/CodeGen/aliasing_parametric_simple_1.ll +++ b/polly/test/Isl/CodeGen/aliasing_parametric_simple_1.ll @@ -9,10 +9,14 @@ ; CHECK: %[[Cp1:[._a-zA-Z0-9]*]] = add nsw i64 %[[Cext]], 1 ; CHECK: %[[BMax:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %B, i64 %[[Cp1]] ; CHECK: %[[AMin:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %A, i64 0 -; CHECK: %[[BltA:[._a-zA-Z0-9]*]] = icmp ule i32* %[[BMax]], %[[AMin]] +; CHECK: %[[BMaxI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[BMax]] to i64 +; CHECK: %[[AMinI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[AMin]] to i64 +; CHECK: %[[BltA:[._a-zA-Z0-9]*]] = icmp ule i64 %[[BMaxI]], %[[AMinI]] ; CHECK: %[[AMax:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %A, i64 1024 ; CHECK: %[[BMin:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %B, i32 %c -; CHECK: %[[AltB:[._a-zA-Z0-9]*]] = icmp ule i32* %[[AMax]], %[[BMin]] +; CHECK: %[[AMaxI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[AMax]] to i64 +; CHECK: %[[BMinI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[BMin]] to i64 +; CHECK: %[[AltB:[._a-zA-Z0-9]*]] = icmp ule i64 %[[AMaxI]], %[[BMinI]] ; CHECK: %[[NoAlias:[._a-zA-Z0-9]*]] = or i1 %[[BltA]], %[[AltB]] ; CHECK: %[[RTC:[._a-zA-Z0-9]*]] = and i1 true, %[[NoAlias]] ; CHECK: br i1 %[[RTC]], label %polly.start, label %for.cond diff --git a/polly/test/Isl/CodeGen/aliasing_parametric_simple_2.ll b/polly/test/Isl/CodeGen/aliasing_parametric_simple_2.ll index 9fa11c5c84eb..7fe8b0f7d058 100644 --- a/polly/test/Isl/CodeGen/aliasing_parametric_simple_2.ll +++ b/polly/test/Isl/CodeGen/aliasing_parametric_simple_2.ll @@ -15,7 +15,9 @@ ; CHECK: %[[M4:[._a-zA-Z0-9]*]] = select i1 %[[M1]], i64 6, i64 %[[M3]] ; CHECK: %[[BMax:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %B, i64 %[[M4]] ; CHECK: %[[AMin:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %A, i64 0 -; CHECK: %[[BltA:[._a-zA-Z0-9]*]] = icmp ule i32* %[[BMax]], %[[AMin]] +; CHECK: %[[BMaxI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[BMax]] to i64 +; CHECK: %[[AMinI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[AMin]] to i64 +; CHECK: %[[BltA:[._a-zA-Z0-9]*]] = icmp ule i64 %[[BMaxI]], %[[AMinI]] ; CHECK: %[[AMax:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %A, i64 1024 ; CHECK: %[[m0:[._a-zA-Z0-9]*]] = sext i32 %c to i64 ; CHECK: %[[m1:[._a-zA-Z0-9]*]] = icmp sge i64 %[[m0]], 15 @@ -23,7 +25,9 @@ ; CHECK: %[[m3:[._a-zA-Z0-9]*]] = sub nsw i64 %[[m2]], 10 ; CHECK: %[[m4:[._a-zA-Z0-9]*]] = select i1 %[[m1]], i64 5, i64 %[[m3]] ; CHECK: %[[BMin:[._a-zA-Z0-9]*]] = getelementptr i32, i32* %B, i64 %[[m4]] -; CHECK: %[[AltB:[._a-zA-Z0-9]*]] = icmp ule i32* %[[AMax]], %[[BMin]] +; CHECK: %[[AMaxI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[AMax]] to i64 +; CHECK: %[[BMinI:[._a-zA-Z0-9]*]] = ptrtoint i32* %[[BMin]] to i64 +; CHECK: %[[AltB:[._a-zA-Z0-9]*]] = icmp ule i64 %[[AMaxI]], %[[BMinI]] ; CHECK: %[[NoAlias:[._a-zA-Z0-9]*]] = or i1 %[[BltA]], %[[AltB]] ; CHECK: %[[RTC:[._a-zA-Z0-9]*]] = and i1 %[[Ctx]], %[[NoAlias]] ; CHECK: br i1 %[[RTC]], label %polly.start, label %for.cond diff --git a/polly/test/Isl/CodeGen/pointer-type-expressions-2.ll b/polly/test/Isl/CodeGen/pointer-type-expressions-2.ll index 37862e447a38..4e2780077e5b 100644 --- a/polly/test/Isl/CodeGen/pointer-type-expressions-2.ll +++ b/polly/test/Isl/CodeGen/pointer-type-expressions-2.ll @@ -2,11 +2,6 @@ ; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s -check-prefix=CODEGEN target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -; TODO: FIXME: IslExprBuilder is not capable of producing valid code -; for arbitrary pointer expressions at the moment. Until -; this is fixed we disallow pointer expressions completely. -; XFAIL: * - define void @foo(i8* %start, i8* %end) { entry: %A = alloca i32 @@ -26,9 +21,9 @@ exit: ; CHECK: for (int c0 = 0; c0 < -start + end; c0 += 1) ; CHECK: Stmt_body(c0); -; Check that we transform this into a pointer difference. - -; CODEGEN: %[[r0:[._a-zA-Z0-9]]] = ptrtoint i8* %end to i64 -; CODEGEN: %[[r1:[._a-zA-Z0-9]]] = ptrtoint i8* %start to i64 -; CODEGEN: %[[r2:[._a-zA-Z0-9]]] = sub i64 %[[r0]], %[[r1]] +; CODEGEN-LABEL: polly.start: +; CODEGEN-NEXT: %[[r0:[._a-zA-Z0-9]*]] = ptrtoint i8* %start to i64 +; CODEGEN-NEXT: %[[r1:[._a-zA-Z0-9]*]] = sub nsw i64 0, %[[r0]] +; CODEGEN-NEXT: %[[r2:[._a-zA-Z0-9]*]] = ptrtoint i8* %end to i64 +; CODEGEN-NEXT: %[[r4:[._a-zA-Z0-9]*]] = add nsw i64 %[[r1]], %[[r2]] diff --git a/polly/test/Isl/CodeGen/pointer-type-expressions.ll b/polly/test/Isl/CodeGen/pointer-type-expressions.ll index 42fc2db3d906..eb6702755f99 100644 --- a/polly/test/Isl/CodeGen/pointer-type-expressions.ll +++ b/polly/test/Isl/CodeGen/pointer-type-expressions.ll @@ -1,11 +1,6 @@ ; RUN: opt %loadPolly -polly-ast -analyze < %s | FileCheck %s ; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s -check-prefix=CODEGEN -; TODO: FIXME: IslExprBuilder is not capable of producing valid code -; for arbitrary pointer expressions at the moment. Until -; this is fixed we disallow pointer expressions completely. -; XFAIL: * - ; void f(int a[], int N, float *P) { ; int i; ; for (i = 0; i < N; ++i) @@ -46,7 +41,10 @@ return: ; CHECK: Stmt_store(c0); ; CHECK: } -; CODEGEN: %[[R0:[0-9]*]] = bitcast float* %P to i8* -; CODEGEN: %[[R1:[0-9]*]] = bitcast float* %P to i8* -; CODEGEN-NEXT: icmp ule i8* %[[R1]], inttoptr (i64 -1 to i8*) +; CODEGEN-LABEL: polly.cond: +; CODEGEN-NEXT: %[[R1:[0-9]*]] = ptrtoint float* %P to i64 +; CODEGEN-NEXT: %[[R2:[0-9]*]] = icmp sle i64 %[[R1]], -1 +; CODEGEN-LABEL: polly.cond2: +; CODEGEN-NEXT: %[[R3:[0-9]*]] = ptrtoint float* %P to i64 +; CODEGEN-NEXT: %[[R4:[0-9]*]] = icmp sge i64 %[[R3]], 1 diff --git a/polly/test/Isl/CodeGen/pointer-type-pointer-type-comparison.ll b/polly/test/Isl/CodeGen/pointer-type-pointer-type-comparison.ll index 48dda745dd8f..2fbb84a174c5 100644 --- a/polly/test/Isl/CodeGen/pointer-type-pointer-type-comparison.ll +++ b/polly/test/Isl/CodeGen/pointer-type-pointer-type-comparison.ll @@ -1,10 +1,6 @@ ; RUN: opt %loadPolly -polly-ast -analyze < %s | FileCheck %s ; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s -check-prefix=CODEGEN ; -; TODO: FIXME: IslExprBuilder is not capable of producing valid code -; for arbitrary pointer expressions at the moment. Until -; this is fixed we disallow pointer expressions completely. -; XFAIL: * ; void f(int a[], int N, float *P, float *Q) { ; int i; @@ -25,7 +21,7 @@ bb: br i1 %brcond, label %store, label %bb.backedge store: - %scevgep = getelementptr i64, i64* %a, i64 %i + %scevgep = getelementptr inbounds i64, i64* %a, i64 %i store i64 %i, i64* %scevgep br label %bb.backedge @@ -46,7 +42,14 @@ return: ; CHECK: Stmt_store(c0); ; CHECK: } -; CODEGEN: %[[Pinc:[_a-zA-Z0-9]+]] = getelementptr float, float* %P, i64 1 -; CODEGEN-NEXT: icmp uge float* %Q, %[[Pinc]] -; CODEGEN: %[[Qinc:[_a-zA-Z0-9]+]] = getelementptr float, float* %Q, i64 1 -; CODEGEN-NEXT: icmp uge float* %P, %[[Qinc]] +; CODEGEN: polly.cond: +; CODEGEN-NEXT: %[[Q:[_a-zA-Z0-9]+]] = ptrtoint float* %Q to i64 +; CODEGEN-NEXT: %[[P:[_a-zA-Z0-9]+]] = ptrtoint float* %P to i64 +; CODEGEN-NEXT: %[[PInc:[_a-zA-Z0-9]+]] = add nsw i64 %[[P]], 1 +; CODEGEN-NEXT: icmp sge i64 %[[Q]], %[[PInc]] + +; CODEGEN: polly.cond2: +; CODEGEN-NEXT: %[[P2:[_a-zA-Z0-9]+]] = ptrtoint float* %P to i64 +; CODEGEN-NEXT: %[[Q2:[_a-zA-Z0-9]+]] = ptrtoint float* %Q to i64 +; CODEGEN-NEXT: %[[QInc:[_a-zA-Z0-9]+]] = add nsw i64 %[[Q2]], 1 +; CODEGEN-NEXT: icmp sge i64 %[[P2]], %[[QInc]] diff --git a/polly/test/ScopInfo/pointer-comparison-no-nsw.ll b/polly/test/ScopInfo/pointer-comparison-no-nsw.ll new file mode 100644 index 000000000000..92519b271b94 --- /dev/null +++ b/polly/test/ScopInfo/pointer-comparison-no-nsw.ll @@ -0,0 +1,39 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; +; void f(int *A, int *B) { +; while (A != B) { +; *A = *A + 1; +; A++; +; } +; } +; +; CHECK: Invalid Context: +; CHECK-NEXT: [A, B] -> { : (4*floor((-A + B)/4) < -A + B and 4*floor((A - B)/4) < A - B) or (4*floor((-A + B)/4) = -A + B and B >= 9223372036854775808 + A) or (4*floor((-A + B)/4) = -A + B and B <= -4 + A) } +; +; CHECK: Domain := +; CHECK-NEXT: [A, B] -> { Stmt_while_body[i0] : 4*floor((A - B)/4) = A - B and B >= A and i0 >= 0 and 4i0 < -A + B } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i32* %A, i32* %B) { +entry: + br label %entry.split + +entry.split: + br i1 true, label %while.cond, label %while.end + +while.cond: ; preds = %while.body, %entry + %A.addr.0 = phi i32* [ %A, %entry.split ], [ %incdec.ptr, %while.body ] + %cmp = icmp eq i32* %A.addr.0, %B + br i1 %cmp, label %while.end, label %while.body + +while.body: ; preds = %while.cond + %tmp = load i32, i32* %A.addr.0, align 4 + %add = add i32 %tmp, 1 + store i32 %add, i32* %A.addr.0, align 4 + %incdec.ptr = getelementptr i32, i32* %A.addr.0, i64 1 + br label %while.cond + +while.end: ; preds = %while.cond + ret void +} diff --git a/polly/test/ScopInfo/pointer-comparison.ll b/polly/test/ScopInfo/pointer-comparison.ll new file mode 100644 index 000000000000..fc65694018d2 --- /dev/null +++ b/polly/test/ScopInfo/pointer-comparison.ll @@ -0,0 +1,38 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; +; TODO: FIXME: Investigate why we need a InvalidContext here. +; +; void f(int *A, int *B) { +; while (A != B) { +; *A = *A + 1; +; A++; +; } +; } +; +; CHECK: Invalid Context: +; CHECK-NEXT: [A, B] -> { : (4*floor((-A + B)/4) < -A + B and 4*floor((A - B)/4) < A - B) or (4*floor((-A + B)/4) = -A + B and B >= 9223372036854775808 + A) or (4*floor((-A + B)/4) = -A + B and B <= -4 + A) } +; +; CHECK: Domain := +; CHECK-NEXT: [A, B] -> { Stmt_while_body[i0] : 4*floor((A - B)/4) = A - B and B >= A and i0 >= 0 and 4i0 < -A + B } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i32* %A, i32* %B) { +entry: + br label %while.cond + +while.cond: ; preds = %while.body, %entry + %A.addr.0 = phi i32* [ %A, %entry ], [ %incdec.ptr, %while.body ] + %cmp = icmp eq i32* %A.addr.0, %B + br i1 %cmp, label %while.end, label %while.body + +while.body: ; preds = %while.cond + %tmp = load i32, i32* %A.addr.0, align 4 + %add = add nsw i32 %tmp, 1 + store i32 %add, i32* %A.addr.0, align 4 + %incdec.ptr = getelementptr inbounds i32, i32* %A.addr.0, i64 1 + br label %while.cond + +while.end: ; preds = %while.cond + ret void +} diff --git a/polly/test/ScopInfo/pointer-type-expressions.ll b/polly/test/ScopInfo/pointer-type-expressions.ll index b416286f8f55..36abd9e21057 100644 --- a/polly/test/ScopInfo/pointer-type-expressions.ll +++ b/polly/test/ScopInfo/pointer-type-expressions.ll @@ -1,10 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s -; TODO: FIXME: IslExprBuilder is not capable of producing valid code -; for arbitrary pointer expressions at the moment. Until -; this is fixed we disallow pointer expressions completely. -; XFAIL: * - ; void f(int a[], int N, float *P) { ; int i; ; for (i = 0; i < N; ++i) @@ -37,17 +32,15 @@ return: ret void } -; CHECK: Assumed Context: -; CHECK: { : } +; CHECK: Assumed Context: +; CHECK-NEXT: { : } +; CHECK-NEXT: Invalid Context: +; CHECK-NEXT: { : 1 = 0 } ; CHECK: Stmt_store ; CHECK: Domain := -; CHECK: [P, N] -> { Stmt_store[i0] : -; CHECK-DAG: (P <= -1 and i0 >= 0 and i0 <= -1 + N) -; CHECK-DAG: or -; CHECK-DAG: (P >= 1 and i0 >= 0 and i0 <= -1 + N) -; CHECK: }; +; CHECK: [P, N] -> { Stmt_store[i0] : 0 <= i0 < N and (P < 0 or P > 0) }; ; CHECK: Schedule := -; CHECK: [P, N] -> { Stmt_store[i0] -> [i0] : P <= -1 or P >= 1 }; +; CHECK: [P, N] -> { Stmt_store[i0] -> [i0] : P < 0 or P > 0 }; ; CHECK: MustWriteAccess := [Reduction Type: NONE] ; CHECK: [P, N] -> { Stmt_store[i0] -> MemRef_a[i0] };