[polly] r272485 - Recommit: "Look through IntToPtr & PtrToInt instructions"

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 11 12:26:08 PDT 2016


Author: grosser
Date: Sat Jun 11 14:26:08 2016
New Revision: 272485

URL: http://llvm.org/viewvc/llvm-project?rev=272485&view=rev
Log:
Recommit: "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.

This patch was originally contributed by Johannes Doerfert in r271888, but was
in conflict with the revert in r272483. This is a recommit with some minor
adjustment to the test cases to take care of differing instruction names.

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=272485&r1=272484&r2=272485&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVAffinator.cpp (original)
+++ polly/trunk/lib/Support/SCEVAffinator.cpp Sat Jun 11 14:26:08 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=272485&r1=272484&r2=272485&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (original)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Sat Jun 11 14:26:08 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=272485&r1=272484&r2=272485&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Sat Jun 11 14:26:08 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=272485&r1=272484&r2=272485&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll (original)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll Sat Jun 11 14:26:08 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=272485&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll (added)
+++ polly/trunk/test/Isl/CodeGen/ptrtoint_as_parameter.ll Sat Jun 11 14:26:08 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=272485&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll (added)
+++ polly/trunk/test/ScopInfo/int2ptr_ptr2int.ll Sat Jun 11 14:26:08 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 %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
+}

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=272485&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll (added)
+++ polly/trunk/test/ScopInfo/int2ptr_ptr2int_2.ll Sat Jun 11 14:26:08 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 %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
+}




More information about the llvm-commits mailing list