diff options
Diffstat (limited to 'polly')
-rw-r--r-- | polly/lib/Support/SCEVAffinator.cpp | 4 | ||||
-rw-r--r-- | polly/lib/Support/SCEVValidator.cpp | 4 | ||||
-rw-r--r-- | polly/lib/Support/ScopHelper.cpp | 29 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll | 5 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll | 34 | ||||
-rw-r--r-- | polly/test/ScopInfo/int2ptr_ptr2int.ll | 71 | ||||
-rw-r--r-- | polly/test/ScopInfo/int2ptr_ptr2int_2.ll | 72 |
7 files changed, 210 insertions, 9 deletions
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp index bff074761e0..347c12f60fd 100644 --- a/polly/lib/Support/SCEVAffinator.cpp +++ b/polly/lib/Support/SCEVAffinator.cpp @@ -565,6 +565,10 @@ __isl_give PWACtx SCEVAffinator::visitSRemInstruction(Instruction *SRem) { __isl_give PWACtx SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) { if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) { switch (I->getOpcode()) { + case Instruction::IntToPtr: + return visit(SE.getSCEVAtScope(I->getOperand(0), getScope())); + case Instruction::PtrToInt: + return visit(SE.getSCEVAtScope(I->getOperand(0), getScope())); case Instruction::SDiv: return visitSDivInstruction(I); case Instruction::SRem: diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp index 85bf815a21d..4b8516338e6 100644 --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -368,6 +368,10 @@ public: if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) { switch (I->getOpcode()) { + case Instruction::IntToPtr: + return visit(SE.getSCEVAtScope(I->getOperand(0), Scope)); + case Instruction::PtrToInt: + return visit(SE.getSCEVAtScope(I->getOperand(0), Scope)); case Instruction::Load: return visitLoadInstruction(I, Expr); case Instruction::SDiv: diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp index 8e7fb1edfff..d2c544d098d 100644 --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -246,6 +246,27 @@ private: const Region &R; ValueMapT *VMap; + const SCEV *visitGenericInst(const SCEVUnknown *E, Instruction *Inst, + Instruction *IP) { + if (!Inst || !R.contains(Inst)) + return E; + + assert(!Inst->mayThrow() && !Inst->mayReadOrWriteMemory() && + !isa<PHINode>(Inst)); + + auto *InstClone = Inst->clone(); + for (auto &Op : Inst->operands()) { + assert(SE.isSCEVable(Op->getType())); + auto *OpSCEV = SE.getSCEV(Op); + auto *OpClone = expandCodeFor(OpSCEV, Op->getType(), IP); + InstClone->replaceUsesOfWith(Op, OpClone); + } + + InstClone->setName(Name + Inst->getName()); + InstClone->insertBefore(IP); + return SE.getSCEV(InstClone); + } + const SCEV *visitUnknown(const SCEVUnknown *E) { // If a value mapping was given try if the underlying value is remapped. @@ -259,15 +280,11 @@ private: return visit(NewE); } + Instruction *StartIP = R.getEnteringBlock()->getTerminator(); Instruction *Inst = dyn_cast<Instruction>(E->getValue()); if (!Inst || (Inst->getOpcode() != Instruction::SRem && Inst->getOpcode() != Instruction::SDiv)) - return E; - - if (!R.contains(Inst)) - return E; - - Instruction *StartIP = R.getEnteringBlock()->getTerminator(); + return visitGenericInst(E, Inst, StartIP); const SCEV *LHSScev = SE.getSCEV(Inst->getOperand(0)); const SCEV *RHSScev = SE.getSCEV(Inst->getOperand(1)); diff --git a/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll b/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll index b98846a469e..9b925443300 100644 --- a/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll +++ b/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll @@ -3,10 +3,9 @@ ; The SCEV expression in this test case refers to a sequence of sdiv ; instructions, which are part of different bbs in the SCoP. When code ; generating the parameter expressions, the code that is generated by the SCEV -; expander has still references to the in-scop instructions, which is invalid. +; expander has still references to the in-scop instructions, which was invalid. ; -; CHECK: polly.split_new_and_old: -; CHECK-NOT: = sdiv i64 0, -4 +; CHECK: polly.start ; target triple = "x86_64-unknown-linux-gnu" diff --git a/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll b/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll new file mode 100644 index 00000000000..1bbb9dd27ff --- /dev/null +++ b/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll @@ -0,0 +1,34 @@ +; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; +; CHECK: polly.split_new_and_old: +; CHECK-NEXT: %pollysub.ptr.lhs.cast263 = ptrtoint i8* inttoptr (i64 1 to i8*) to i64 +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: nounwind uwtable +define void @XS_MIME__QuotedPrint_encode_qp() { +entry: + %Perl_sv_len = alloca i64, align 8 + br label %if.end + +if.end: ; preds = %entry + br label %while.cond + +while.cond: ; preds = %cond.true270, %if.then260, %if.end + %p.0 = phi i8* [ null, %if.end ], [ %p.4, %if.then260 ], [ %p.4, %cond.true270 ] + br i1 undef, label %if.then260, label %while.body210 + +while.body210: ; preds = %while.cond + unreachable + +if.then260: ; preds = %while.cond + %p.4 = getelementptr inbounds i8, i8* null, i64 1 + %sub.ptr.lhs.cast263 = ptrtoint i8* %p.4 to i64 + %sub.ptr.sub265 = sub i64 %sub.ptr.lhs.cast263, 0 + %div = udiv i64 0, %sub.ptr.sub265 + %cmp268 = icmp ult i64 0, %div + br i1 %cmp268, label %cond.true270, label %while.cond + +cond.true270: ; preds = %if.then260 + br label %while.cond +} diff --git a/polly/test/ScopInfo/int2ptr_ptr2int.ll b/polly/test/ScopInfo/int2ptr_ptr2int.ll new file mode 100644 index 00000000000..0979ebaebba --- /dev/null +++ b/polly/test/ScopInfo/int2ptr_ptr2int.ll @@ -0,0 +1,71 @@ +; RUN: opt %loadPolly -analyze -polly-scops < %s | FileCheck %s +; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s --check-prefix=IR +; +; void f(long *A, long *ptr, long val) { +; for (long i = 0; i < 100; i++) { +; long ptrV = ((long)(ptr + 1)) + 1; +; long valP = (long)(((long *)(val + 1)) + 1); +; A[ptrV] += A[valP]; +; } +; } +; +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + val] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; +; IR: polly.stmt.for.body: +; IR-NEXT: %p_tmp = ptrtoint i64* %scevgep to i64 +; IR-NEXT: %p_add = add nsw i64 %p_tmp, 1 +; IR-NEXT: %p_tmp1 = inttoptr i64 %10 to i64* +; IR-NEXT: %p_add.ptr2 = getelementptr inbounds i64, i64* %p_tmp1, i64 1 +; IR-NEXT: %p_tmp2 = ptrtoint i64* %p_add.ptr2 to i64 +; IR-NEXT: %p_arrayidx = getelementptr inbounds i64, i64* %A, i64 %p_tmp2 +; IR-NEXT: %tmp3_p_scalar_ = load i64, i64* %p_arrayidx +; IR-NEXT: %p_arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %p_add +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %p_arrayidx3 +; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %tmp3_p_scalar_ +; IR-NEXT: store i64 %p_add4, i64* %p_arrayidx3 +; +; IR: polly.loop_preheader: +; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i64 1 +; IR-NEXT: %10 = add i64 %val, 1 +; IR-NEXT: br label %polly.loop_header +; +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i64* %A, i64* %ptr, i64 %val) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ] + %exitcond = icmp ne i64 %i.0, 100 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %add.ptr = getelementptr inbounds i64, i64* %ptr, i64 1 + %tmp = ptrtoint i64* %add.ptr to i64 + %add = add nsw i64 %tmp, 1 + %add1 = add nsw i64 %val, 1 + %tmp1 = inttoptr i64 %add1 to i64* + %add.ptr2 = getelementptr inbounds i64, i64* %tmp1, i64 1 + %tmp2 = ptrtoint i64* %add.ptr2 to i64 + %arrayidx = getelementptr inbounds i64, i64* %A, i64 %tmp2 + %tmp3 = load i64, i64* %arrayidx + %arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %add + %tmp4 = load i64, i64* %arrayidx3 + %add4 = add nsw i64 %tmp4, %tmp3 + store i64 %add4, i64* %arrayidx3 + br label %for.inc + +for.inc: ; preds = %for.body + %inc = add nuw nsw i64 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} diff --git a/polly/test/ScopInfo/int2ptr_ptr2int_2.ll b/polly/test/ScopInfo/int2ptr_ptr2int_2.ll new file mode 100644 index 00000000000..e47e181c97b --- /dev/null +++ b/polly/test/ScopInfo/int2ptr_ptr2int_2.ll @@ -0,0 +1,72 @@ +; RUN: opt %loadPolly -analyze -polly-scops < %s | FileCheck %s +; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s --check-prefix=IR +; +; void f(long *A, long *B, long *ptr, long val) { +; for (long i = 0; i < 100; i++) { +; long ptrV = ((long)(ptr + 1)) + 1; +; long valP = (long)(((long *)(val + 1)) + 1); +; A[ptrV] += B[valP]; +; } +; } +; +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_B[9 + val] }; +; CHECK-NEXT: Execution Context: [val, ptr] -> { : val <= 9223372036854775806 } +; +; CHECK: ReadAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; +; IR: polly.stmt.for.body: +; IR-NEXT: %p_tmp = ptrtoint i64* %scevgep to i64 +; IR-NEXT: %p_add = add nsw i64 %p_tmp, 1 +; IR-NEXT: %p_tmp1 = inttoptr i64 %26 to i64* +; IR-NEXT: %p_add.ptr2 = getelementptr inbounds i64, i64* %p_tmp1, i64 1 +; IR-NEXT: %p_tmp2 = ptrtoint i64* %p_add.ptr2 to i64 +; IR-NEXT: %p_arrayidx = getelementptr inbounds i64, i64* %B, i64 %p_tmp2 +; IR-NEXT: %p_arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %p_add +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %p_arrayidx3 +; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %polly.preload.tmp3.merge +; IR-NEXT: store i64 %p_add4, i64* %p_arrayidx3 +; +; IR: polly.loop_preheader: +; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i64 1 +; IR-NEXT: %26 = add i64 %val, 1 +; IR-NEXT: br label %polly.loop_header +; +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i64* %A, i64* %B, i64* %ptr, i64 %val) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ] + %exitcond = icmp ne i64 %i.0, 100 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %add.ptr = getelementptr inbounds i64, i64* %ptr, i64 1 + %tmp = ptrtoint i64* %add.ptr to i64 + %add = add nsw i64 %tmp, 1 + %add1 = add nsw i64 %val, 1 + %tmp1 = inttoptr i64 %add1 to i64* + %add.ptr2 = getelementptr inbounds i64, i64* %tmp1, i64 1 + %tmp2 = ptrtoint i64* %add.ptr2 to i64 + %arrayidx = getelementptr inbounds i64, i64* %B, i64 %tmp2 + %tmp3 = load i64, i64* %arrayidx + %arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %add + %tmp4 = load i64, i64* %arrayidx3 + %add4 = add nsw i64 %tmp4, %tmp3 + store i64 %add4, i64* %arrayidx3 + br label %for.inc + +for.inc: ; preds = %for.body + %inc = add nuw nsw i64 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} |