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
This commit is contained in:
Johannes Doerfert 2016-04-10 09:50:10 +00:00
parent 35db8ecb50
commit 561d36b320
15 changed files with 172 additions and 166 deletions

View File

@ -399,12 +399,6 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI,
isa<UndefValue>(ICmp->getOperand(1)))
return invalid<ReportUndefOperand>(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);

View File

@ -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 ((-<pointer>) + <pointer>) which is for
// isl the same as (<pointer> - <pointer>). We have to treat it here because
// there is no valid semantics for the (-<pointer>) 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 <pointer> - <pointer>
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 <pointer> +/- <integer> and <integer> +/- <pointer>
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);

View File

@ -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);
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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]]
;

View File

@ -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

View File

@ -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

View File

@ -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]]

View File

@ -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

View File

@ -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]]

View File

@ -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
}

View File

@ -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
}

View File

@ -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] };