[polly] r271888 - Look through IntToPtr & PtrToInt instructions

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 6 05:12:28 PDT 2016


Author: jdoerfert
Date: Mon Jun  6 07:12:27 2016
New Revision: 271888

URL: http://llvm.org/viewvc/llvm-project?rev=271888&view=rev
Log:
Look through IntToPtr & PtrToInt instructions

  IntToPtr and PtrToInt instructions are basically no-ops that we can handle as
  such. In order to generate them properly as parameters we had to improve the
  ScopExpander, though the change is the first in the direction of a more
  aggressive scalar synthetization.

Added:
    polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll
    polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll
    polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll
Modified:
    polly/trunk/lib/Support/SCEVAffinator.cpp
    polly/trunk/lib/Support/SCEVValidator.cpp
    polly/trunk/lib/Support/ScopHelper.cpp
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll

Modified: polly/trunk/lib/Support/SCEVAffinator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVAffinator.cpp?rev=271888&r1=271887&r2=271888&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVAffinator.cpp (original)
+++ polly/trunk/lib/Support/SCEVAffinator.cpp Mon Jun  6 07:12:27 2016
@@ -565,6 +565,10 @@ __isl_give PWACtx SCEVAffinator::visitSR
 __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:

Modified: polly/trunk/lib/Support/SCEVValidator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVValidator.cpp?rev=271888&r1=271887&r2=271888&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (original)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Mon Jun  6 07:12:27 2016
@@ -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:

Modified: polly/trunk/lib/Support/ScopHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/ScopHelper.cpp?rev=271888&r1=271887&r2=271888&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Mon Jun  6 07:12:27 2016
@@ -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));

Modified: polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll?rev=271888&r1=271887&r2=271888&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll (original)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll Mon Jun  6 07:12:27 2016
@@ -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"
 

Added: polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll?rev=271888&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll (added)
+++ polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll Mon Jun  6 07:12:27 2016
@@ -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
+}

Added: polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll?rev=271888&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll (added)
+++ polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll Mon Jun  6 07:12:27 2016
@@ -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 %9 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:   %9 = 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
+}

Added: polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll?rev=271888&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll (added)
+++ polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll Mon Jun  6 07:12:27 2016
@@ -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 %25 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:   %25 = 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
+}




More information about the llvm-commits mailing list