[polly] r245288 - Introduce the ScopExpander as a SCEVExpander replacement

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 04:56:01 PDT 2015


Author: jdoerfert
Date: Tue Aug 18 06:56:00 2015
New Revision: 245288

URL: http://llvm.org/viewvc/llvm-project?rev=245288&view=rev
Log:
Introduce the ScopExpander as a SCEVExpander replacement

  The SCEVExpander cannot deal with all SCEVs Polly allows in all kinds
  of expressions. To this end we introduce a ScopExpander that handles
  the additional expressions separatly and falls back to the
  SCEVExpander for everything else.

Reviewers: grosser, Meinersbur

Subscribers: #polly

Differential Revision: http://reviews.llvm.org/D12066


Added:
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_1.ll
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_3.ll
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb.ll
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb_invariant.ll
    polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_rtc.ll
Removed:
    polly/trunk/test/Isl/CodeGen/inner_scev.ll
    polly/trunk/test/Isl/CodeGen/inner_scev_2.ll
Modified:
    polly/trunk/include/polly/CodeGen/IslExprBuilder.h
    polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
    polly/trunk/include/polly/Support/ScopHelper.h
    polly/trunk/lib/CodeGen/BlockGenerators.cpp
    polly/trunk/lib/CodeGen/IslExprBuilder.cpp
    polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
    polly/trunk/lib/Support/ScopHelper.cpp

Modified: polly/trunk/include/polly/CodeGen/IslExprBuilder.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslExprBuilder.h?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslExprBuilder.h (original)
+++ polly/trunk/include/polly/CodeGen/IslExprBuilder.h Tue Aug 18 06:56:00 2015
@@ -17,7 +17,8 @@
 #include "isl/ast.h"
 
 namespace llvm {
-class SCEVExpander;
+class DataLayout;
+class ScalarEvolution;
 }
 
 namespace polly {
@@ -91,12 +92,10 @@ public:
   ///                  variables (identified by an isl_id). The IDTOValue map
   ///                  specifies the LLVM-IR Values that correspond to these
   ///                  parameters and variables.
-  /// @param Expander  A SCEVExpander to create the indices for multi
-  ///                  dimensional accesses.
-  IslExprBuilder(PollyIRBuilder &Builder, IDToValueTy &IDToValue,
-                 llvm::SCEVExpander &Expander, llvm::DominatorTree &DT,
-                 llvm::LoopInfo &LI)
-      : Builder(Builder), IDToValue(IDToValue), Expander(Expander), DT(DT),
+  IslExprBuilder(Scop &S, PollyIRBuilder &Builder, IDToValueTy &IDToValue,
+                 const llvm::DataLayout &DL, llvm::ScalarEvolution &SE,
+                 llvm::DominatorTree &DT, llvm::LoopInfo &LI)
+      : S(S), Builder(Builder), IDToValue(IDToValue), DL(DL), SE(SE), DT(DT),
         LI(LI) {}
 
   /// @brief Create LLVM-IR for an isl_ast_expr[ession].
@@ -124,12 +123,13 @@ public:
   llvm::IntegerType *getType(__isl_keep isl_ast_expr *Expr);
 
 private:
+  Scop &S;
+
   PollyIRBuilder &Builder;
   IDToValueTy &IDToValue;
 
-  /// @brief A SCEVExpander to translate dimension sizes to llvm values.
-  llvm::SCEVExpander &Expander;
-
+  const llvm::DataLayout &DL;
+  llvm::ScalarEvolution &SE;
   llvm::DominatorTree &DT;
   llvm::LoopInfo &LI;
 

Modified: polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslNodeBuilder.h?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslNodeBuilder.h (original)
+++ polly/trunk/include/polly/CodeGen/IslNodeBuilder.h Tue Aug 18 06:56:00 2015
@@ -16,7 +16,6 @@
 #include "polly/CodeGen/BlockGenerators.h"
 #include "polly/CodeGen/IslExprBuilder.h"
 #include "polly/CodeGen/LoopGenerators.h"
-#include "llvm/Analysis/ScalarEvolutionExpander.h"
 #include "isl/ctx.h"
 #include "isl/union_map.h"
 
@@ -30,8 +29,8 @@ public:
   IslNodeBuilder(PollyIRBuilder &Builder, ScopAnnotator &Annotator, Pass *P,
                  const DataLayout &DL, LoopInfo &LI, ScalarEvolution &SE,
                  DominatorTree &DT, Scop &S)
-      : S(S), Builder(Builder), Annotator(Annotator), Rewriter(SE, DL, "polly"),
-        ExprBuilder(Builder, IDToValue, Rewriter, DT, LI),
+      : S(S), Builder(Builder), Annotator(Annotator),
+        ExprBuilder(S, Builder, IDToValue, DL, SE, DT, LI),
         BlockGen(Builder, LI, SE, DT, ScalarMap, PHIOpMap, EscapeMap,
                  &ExprBuilder),
         RegionGen(BlockGen), P(P), DL(DL), LI(LI), SE(SE), DT(DT) {}
@@ -53,9 +52,6 @@ private:
   PollyIRBuilder &Builder;
   ScopAnnotator &Annotator;
 
-  /// @brief A SCEVExpander to create llvm values from SCEVs.
-  SCEVExpander Rewriter;
-
   IslExprBuilder ExprBuilder;
 
   /// @brief Maps used by the block and region generator to demote scalars.

Modified: polly/trunk/include/polly/Support/ScopHelper.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/ScopHelper.h?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/ScopHelper.h (original)
+++ polly/trunk/include/polly/Support/ScopHelper.h Tue Aug 18 06:56:00 2015
@@ -27,6 +27,7 @@ class Region;
 class Pass;
 class BasicBlock;
 class StringRef;
+class DataLayout;
 class DominatorTree;
 class RegionInfo;
 class ScalarEvolution;
@@ -77,5 +78,26 @@ void simplifyRegion(llvm::Region *R, llv
 /// @param P          The pass that currently running.
 ///
 void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);
+
+/// @brief Wrapper for SCEVExpander extended to all Polly features.
+///
+/// This wrapper will internally call the SCEVExpander but also makes sure that
+/// all additional features not represented in SCEV (e.g., SDiv/SRem are not
+/// black boxes but can be part of the function) will be expanded correctly.
+///
+/// The parameters are the same as for the creation of a SCEVExpander as well
+/// as the call to SCEVExpander::expandCodeFor:
+///
+/// @param S    The current Scop.
+/// @param SE   The Scalar Evolution pass.
+/// @param DL   The module data layout.
+/// @param Name The suffix added to the new instruction names.
+/// @param E    The expression for which code is actually generated.
+/// @param Ty   The type of the resulting code.
+/// @param IP   The insertion point for the new code.
+llvm::Value *expandCodeFor(Scop &S, llvm::ScalarEvolution &SE,
+                           const llvm::DataLayout &DL, const char *Name,
+                           const llvm::SCEV *E, llvm::Type *Ty,
+                           llvm::Instruction *IP);
 }
 #endif

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Tue Aug 18 06:56:00 2015
@@ -24,7 +24,6 @@
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/RegionInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ScalarEvolutionExpander.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -116,17 +115,16 @@ Value *BlockGenerator::getNewValue(ScopS
         VTV.insert(BBMap.begin(), BBMap.end());
         VTV.insert(GlobalMap.begin(), GlobalMap.end());
         NewScev = SCEVParameterRewriter::rewrite(NewScev, SE, VTV);
-        SCEVExpander Expander(SE, Stmt.getParent()
-                                      ->getRegion()
-                                      .getEntry()
-                                      ->getParent()
-                                      ->getParent()
-                                      ->getDataLayout(),
-                              "polly");
-        assert(Builder.GetInsertPoint() != Builder.GetInsertBlock()->end() &&
+
+        Scop &S = *Stmt.getParent();
+        const DataLayout &DL =
+            S.getRegion().getEntry()->getParent()->getParent()->getDataLayout();
+        auto IP = Builder.GetInsertPoint();
+
+        assert(IP != Builder.GetInsertBlock()->end() &&
                "Only instructions can be insert points for SCEVExpander");
-        Value *Expanded = Expander.expandCodeFor(NewScev, Old->getType(),
-                                                 Builder.GetInsertPoint());
+        Value *Expanded =
+            expandCodeFor(S, SE, DL, "polly", NewScev, Old->getType(), IP);
 
         BBMap[Old] = Expanded;
         return Expanded;
@@ -376,6 +374,7 @@ AllocaInst *BlockGenerator::getOrCreateA
 
 void BlockGenerator::handleOutsideUsers(const Region &R, Instruction *Inst,
                                         Value *InstCopy) {
+
   EscapeUserVectorTy EscapeUsers;
   for (User *U : Inst->users()) {
 

Modified: polly/trunk/lib/CodeGen/IslExprBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslExprBuilder.cpp?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslExprBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslExprBuilder.cpp Tue Aug 18 06:56:00 2015
@@ -12,7 +12,7 @@
 #include "polly/CodeGen/IslExprBuilder.h"
 #include "polly/ScopInfo.h"
 #include "polly/Support/GICHelper.h"
-#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "polly/Support/ScopHelper.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 
@@ -148,8 +148,9 @@ Value *IslExprBuilder::createAccessAddre
       break;
 
     const SCEV *DimSCEV = SAI->getDimensionSize(u - 1);
-    Value *DimSize = Expander.expandCodeFor(DimSCEV, DimSCEV->getType(),
-                                            Builder.GetInsertPoint());
+    Value *DimSize =
+        expandCodeFor(S, SE, DL, "polly", DimSCEV, DimSCEV->getType(),
+                      Builder.GetInsertPoint());
 
     Type *Ty = getWidestType(DimSize->getType(), IndexOp->getType());
 

Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Tue Aug 18 06:56:00 2015
@@ -31,7 +31,6 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/PostDominators.h"
-#include "llvm/Analysis/ScalarEvolutionExpander.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Verifier.h"
@@ -742,5 +741,6 @@ void IslNodeBuilder::addParameters(__isl
 
 Value *IslNodeBuilder::generateSCEV(const SCEV *Expr) {
   Instruction *InsertLocation = --(Builder.GetInsertBlock()->end());
-  return Rewriter.expandCodeFor(Expr, Expr->getType(), InsertLocation);
+  return expandCodeFor(S, SE, DL, "polly", Expr, Expr->getType(),
+                       InsertLocation);
 }

Modified: polly/trunk/lib/Support/ScopHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/ScopHelper.cpp?rev=245288&r1=245287&r2=245288&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Tue Aug 18 06:56:00 2015
@@ -17,12 +17,14 @@
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/RegionInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 
 using namespace llvm;
+using namespace polly;
 
 #define DEBUG_TYPE "polly-scop-helper"
 
@@ -252,3 +254,110 @@ void polly::splitEntryBlockForAlloca(Bas
   // splitBlock updates DT, LI and RI.
   splitBlock(EntryBlock, I, DT, LI, RI);
 }
+
+/// The SCEVExpander will __not__ generate any code for an existing SDiv/SRem
+/// instruction but just use it, if it is referenced as a SCEVUnknown. We want
+/// however to generate new code if the instruction is in the analyzed region
+/// and we generate code outside/in front of that region. Hence, we generate the
+/// code for the SDiv/SRem operands in front of the analyzed region and then
+/// create a new SDiv/SRem operation there too.
+struct ScopExpander : SCEVVisitor<ScopExpander, const SCEV *> {
+  friend struct SCEVVisitor<ScopExpander, const SCEV *>;
+
+  explicit ScopExpander(const Region &R, ScalarEvolution &SE,
+                        const DataLayout &DL, const char *Name)
+      : Expander(SCEVExpander(SE, DL, Name)), SE(SE), Name(Name), R(R) {}
+
+  Value *expandCodeFor(const SCEV *E, Type *Ty, Instruction *I) {
+    // If we generate code in the region we will immediately fall back to the
+    // SCEVExpander, otherwise we will stop at all unknowns in the SCEV and if
+    // needed replace them by copies computed in the entering block.
+    if (!R.contains(I))
+      E = visit(E);
+    return Expander.expandCodeFor(E, Ty, I);
+  }
+
+private:
+  SCEVExpander Expander;
+  ScalarEvolution &SE;
+  const char *Name;
+  const Region &R;
+
+  const SCEV *visitUnknown(const SCEVUnknown *E) {
+    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();
+
+    const SCEV *LHSScev = visit(SE.getSCEV(Inst->getOperand(0)));
+    const SCEV *RHSScev = visit(SE.getSCEV(Inst->getOperand(1)));
+
+    Value *LHS = Expander.expandCodeFor(LHSScev, E->getType(), StartIP);
+    Value *RHS = Expander.expandCodeFor(RHSScev, E->getType(), StartIP);
+
+    Inst = BinaryOperator::Create((Instruction::BinaryOps)Inst->getOpcode(),
+                                  LHS, RHS, Inst->getName() + Name, StartIP);
+    return SE.getSCEV(Inst);
+  }
+
+  /// The following functions will just traverse the SCEV and rebuild it with
+  /// the new operands returned by the traversal.
+  ///
+  ///{
+  const SCEV *visitConstant(const SCEVConstant *E) { return E; }
+  const SCEV *visitTruncateExpr(const SCEVTruncateExpr *E) {
+    return SE.getTruncateExpr(visit(E->getOperand()), E->getType());
+  }
+  const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *E) {
+    return SE.getZeroExtendExpr(visit(E->getOperand()), E->getType());
+  }
+  const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *E) {
+    return SE.getSignExtendExpr(visit(E->getOperand()), E->getType());
+  }
+  const SCEV *visitUDivExpr(const SCEVUDivExpr *E) {
+    return SE.getUDivExpr(visit(E->getLHS()), visit(E->getRHS()));
+  }
+  const SCEV *visitAddExpr(const SCEVAddExpr *E) {
+    SmallVector<const SCEV *, 4> NewOps;
+    for (const SCEV *Op : E->operands())
+      NewOps.push_back(visit(Op));
+    return SE.getAddExpr(NewOps);
+  }
+  const SCEV *visitMulExpr(const SCEVMulExpr *E) {
+    SmallVector<const SCEV *, 4> NewOps;
+    for (const SCEV *Op : E->operands())
+      NewOps.push_back(visit(Op));
+    return SE.getMulExpr(NewOps);
+  }
+  const SCEV *visitUMaxExpr(const SCEVUMaxExpr *E) {
+    SmallVector<const SCEV *, 4> NewOps;
+    for (const SCEV *Op : E->operands())
+      NewOps.push_back(visit(Op));
+    return SE.getUMaxExpr(NewOps);
+  }
+  const SCEV *visitSMaxExpr(const SCEVSMaxExpr *E) {
+    SmallVector<const SCEV *, 4> NewOps;
+    for (const SCEV *Op : E->operands())
+      NewOps.push_back(visit(Op));
+    return SE.getSMaxExpr(NewOps);
+  }
+  const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) {
+    SmallVector<const SCEV *, 4> NewOps;
+    for (const SCEV *Op : E->operands())
+      NewOps.push_back(visit(Op));
+    return SE.getAddRecExpr(NewOps, E->getLoop(), E->getNoWrapFlags());
+  }
+  ///}
+};
+
+Value *polly::expandCodeFor(Scop &S, ScalarEvolution &SE, const DataLayout &DL,
+                            const char *Name, const SCEV *E, Type *Ty,
+                            Instruction *IP) {
+  ScopExpander Expander(S.getRegion(), SE, DL, Name);
+  return Expander.expandCodeFor(E, Ty, IP);
+}

Removed: polly/trunk/test/Isl/CodeGen/inner_scev.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev.ll?rev=245287&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev.ll (original)
+++ polly/trunk/test/Isl/CodeGen/inner_scev.ll (removed)
@@ -1,46 +0,0 @@
-; RUN: opt %loadPolly -S -polly-no-early-exit -polly-detect-unprofitable -polly-codegen < %s
-;
-; Excerpt from the test-suite's oggenc reduced using bugpoint.
-;
-; It features a SCEV value using %div44 for the inner loop (for.body.51 =>
-; for.cond.60.preheader) that is computed within the body of the outer loop
-; (for.cond.30.preheader => for.cond.60.preheader). CodeGenerator would add a
-; computation of the SCEV to before the scop that references %div44, which is
-; not available then.
-;
-; XFAIL: *
-;
-target triple = "x86_64-unknown-linux-gnu"
-
-define void @_vorbis_apply_window(float* %d) {
-entry:
-  %0 = load float*, float** undef, align 8
-  %div23.neg = sdiv i64 0, -4
-  %sub24 = add i64 0, %div23.neg
-  br label %for.cond.30.preheader
-
-for.cond.30.preheader:                            ; preds = %for.body, %entry
-  %sext = shl i64 %sub24, 32
-  %conv48.74 = ashr exact i64 %sext, 32
-  %cmp49.75 = icmp slt i64 %conv48.74, 0
-  br i1 %cmp49.75, label %for.body.51.lr.ph, label %for.cond.60.preheader
-
-for.body.51.lr.ph:                                ; preds = %for.cond.30.preheader
-  %div44 = sdiv i64 0, 2
-  %sub45 = add nsw i64 %div44, 4294967295
-  %1 = trunc i64 %sub45 to i32
-  %2 = sext i32 %1 to i64
-  br label %for.body.51
-
-for.cond.60.preheader:                            ; preds = %for.body.51, %for.cond.30.preheader
-  ret void
-
-for.body.51:                                      ; preds = %for.body.51, %for.body.51.lr.ph
-  %indvars.iv86 = phi i64 [ %2, %for.body.51.lr.ph ], [ undef, %for.body.51 ]
-  %arrayidx53 = getelementptr inbounds float, float* %0, i64 %indvars.iv86
-  %3 = load float, float* %arrayidx53, align 4
-  %arrayidx55 = getelementptr inbounds float, float* %d, i64 0
-  %mul56 = fmul float %3, undef
-  store float %mul56, float* %arrayidx55, align 4
-  br i1 false, label %for.body.51, label %for.cond.60.preheader
-}

Removed: polly/trunk/test/Isl/CodeGen/inner_scev_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_2.ll?rev=245287&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_2.ll (original)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_2.ll (removed)
@@ -1,43 +0,0 @@
-; RUN: opt %loadPolly -S -polly-no-early-exit -polly-detect-unprofitable -polly-codegen < %s | FileCheck %s
-; XFAIL: *
-;
-; 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.
-
-target triple = "x86_64-unknown-linux-gnu"
-
-define void @_vorbis_apply_window(float* %d, i64 %param) {
-entry:
-  %0 = load float*, float** undef, align 8
-  %div23.neg = sdiv i64 0, -4
-  %sub24 = add i64 0, %div23.neg
-  br label %for.cond.30.preheader
-
-for.cond.30.preheader:                            ; preds = %for.body, %entry
-  %sext = shl i64 %sub24, 32
-  %conv48.74 = ashr exact i64 %sext, 32
-  %div43 = sdiv i64 %param, 2
-  %cmp49.75 = icmp slt i64 %conv48.74, 0
-  br i1 %cmp49.75, label %for.body.51.lr.ph, label %for.cond.60.preheader
-
-for.body.51.lr.ph:                                ; preds = %for.cond.30.preheader
-  %div44 = sdiv i64 %div43, 2
-  %sub45 = add nsw i64 %div44, 4294967295
-  %1 = trunc i64 %sub45 to i32
-  %2 = sext i32 %1 to i64
-  br label %for.body.51
-
-for.cond.60.preheader:                            ; preds = %for.body.51, %for.cond.30.preheader
-  ret void
-
-for.body.51:                                      ; preds = %for.body.51, %for.body.51.lr.ph
-  %indvars.iv86 = phi i64 [ %2, %for.body.51.lr.ph ], [ undef, %for.body.51 ]
-  %arrayidx53 = getelementptr inbounds float, float* %0, i64 %indvars.iv86
-  %3 = load float, float* %arrayidx53, align 4
-  %arrayidx55 = getelementptr inbounds float, float* %d, i64 0
-  %mul56 = fmul float %3, undef
-  store float %mul56, float* %arrayidx55, align 4
-  br i1 false, label %for.body.51, label %for.cond.60.preheader
-}

Added: polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_1.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_1.ll?rev=245288&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_1.ll (added)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_1.ll Tue Aug 18 06:56:00 2015
@@ -0,0 +1,47 @@
+; RUN: opt %loadPolly -S -polly-no-early-exit -polly-detect-unprofitable -polly-codegen < %s
+;
+; Excerpt from the test-suite's oggenc reduced using bugpoint.
+;
+; It features a SCEV value using %div44 for the inner loop (for.body.51 =>
+; for.cond.60.preheader) that is computed within the body of the outer loop
+; (for.cond.30.preheader => for.cond.60.preheader). CodeGenerator would add a
+; computation of the SCEV to before the scop that references %div44, which is
+; not available then.
+;
+; CHECK:      polly.split_new_and_old:
+; CHECK-NEXT:   %div23.neg.polly.copy = sdiv i64 0, -4
+;
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @_vorbis_apply_window(float* %d) {
+entry:
+  %0 = load float*, float** undef, align 8
+  %div23.neg = sdiv i64 0, -4
+  %sub24 = add i64 0, %div23.neg
+  br label %for.cond.30.preheader
+
+for.cond.30.preheader:                            ; preds = %for.body, %entry
+  %sext = shl i64 %sub24, 32
+  %conv48.74 = ashr exact i64 %sext, 32
+  %cmp49.75 = icmp slt i64 %conv48.74, 0
+  br i1 %cmp49.75, label %for.body.51.lr.ph, label %for.cond.60.preheader
+
+for.body.51.lr.ph:                                ; preds = %for.cond.30.preheader
+  %div44 = sdiv i64 0, 2
+  %sub45 = add nsw i64 %div44, 4294967295
+  %1 = trunc i64 %sub45 to i32
+  %2 = sext i32 %1 to i64
+  br label %for.body.51
+
+for.cond.60.preheader:                            ; preds = %for.body.51, %for.cond.30.preheader
+  ret void
+
+for.body.51:                                      ; preds = %for.body.51, %for.body.51.lr.ph
+  %indvars.iv86 = phi i64 [ %2, %for.body.51.lr.ph ], [ undef, %for.body.51 ]
+  %arrayidx53 = getelementptr inbounds float, float* %0, i64 %indvars.iv86
+  %3 = load float, float* %arrayidx53, align 4
+  %arrayidx55 = getelementptr inbounds float, float* %d, i64 0
+  %mul56 = fmul float %3, undef
+  store float %mul56, float* %arrayidx55, align 4
+  br i1 false, label %for.body.51, label %for.cond.60.preheader
+}

Added: 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=245288&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll (added)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_2.ll Tue Aug 18 06:56:00 2015
@@ -0,0 +1,47 @@
+; RUN: opt %loadPolly -S -polly-no-early-exit -polly-detect-unprofitable -polly-codegen < %s | FileCheck %s
+;
+; 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.
+;
+; CHECK:    polly.split_new_and_old:
+; CHECK-NOT:  = sdiv i64 0, -4
+; CHECK:      %div43polly = sdiv i64 %param, 2
+; CHECK:      %div44polly = sdiv i64 %div43polly, 2
+;
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @_vorbis_apply_window(float* %d, i64 %param) {
+entry:
+  %0 = load float*, float** undef, align 8
+  %div23.neg = sdiv i64 0, -4
+  %sub24 = add i64 0, %div23.neg
+  br label %for.cond.30.preheader
+
+for.cond.30.preheader:                            ; preds = %for.body, %entry
+  %sext = shl i64 %sub24, 32
+  %conv48.74 = ashr exact i64 %sext, 32
+  %div43 = sdiv i64 %param, 2
+  %cmp49.75 = icmp slt i64 %conv48.74, 0
+  br i1 %cmp49.75, label %for.body.51.lr.ph, label %for.cond.60.preheader
+
+for.body.51.lr.ph:                                ; preds = %for.cond.30.preheader
+  %div44 = sdiv i64 %div43, 2
+  %sub45 = add nsw i64 %div44, 4294967295
+  %1 = trunc i64 %sub45 to i32
+  %2 = sext i32 %1 to i64
+  br label %for.body.51
+
+for.cond.60.preheader:                            ; preds = %for.body.51, %for.cond.30.preheader
+  ret void
+
+for.body.51:                                      ; preds = %for.body.51, %for.body.51.lr.ph
+  %indvars.iv86 = phi i64 [ %2, %for.body.51.lr.ph ], [ undef, %for.body.51 ]
+  %arrayidx53 = getelementptr inbounds float, float* %0, i64 %indvars.iv86
+  %3 = load float, float* %arrayidx53, align 4
+  %arrayidx55 = getelementptr inbounds float, float* %d, i64 0
+  %mul56 = fmul float %3, undef
+  store float %mul56, float* %arrayidx55, align 4
+  br i1 false, label %for.body.51, label %for.cond.60.preheader
+}

Added: polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_3.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_3.ll?rev=245288&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_3.ll (added)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_3.ll Tue Aug 18 06:56:00 2015
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -S -polly-no-early-exit -polly-detect-unprofitable -polly-codegen < %s | FileCheck %s
+;
+; This test case has a inner SCEV sdiv that will escape the SCoP. Just check we
+; do not crash and generate valid code.
+;
+; CHECK:    polly.split_new_and_old:
+;
+target triple = "x86_64-unknown-linux-gnu"
+
+define i64 @_vorbis_apply_window(float* %d, i64 %param) {
+entry:
+  %0 = load float*, float** undef, align 8
+  %div23.neg = sdiv i64 0, -4
+  %sub24 = add i64 0, %div23.neg
+  br label %for.cond.30.preheader
+
+for.cond.30.preheader:                            ; preds = %for.body, %entry
+  %sext = shl i64 %sub24, 32
+  %conv48.74 = ashr exact i64 %sext, 32
+  %div43 = sdiv i64 %param, 2
+  %cmp49.75 = icmp slt i64 %conv48.74, 0
+  br i1 %cmp49.75, label %for.body.51.lr.ph, label %for.cond.60.preheader
+
+for.body.51.lr.ph:                                ; preds = %for.cond.30.preheader
+  %div44 = sdiv i64 %div43, 2
+  %sub45 = add nsw i64 %div44, 4294967295
+  %1 = trunc i64 %sub45 to i32
+  %2 = sext i32 %1 to i64
+  br label %for.body.51
+
+for.cond.60.preheader:                            ; preds = %for.body.51, %for.cond.30.preheader
+  %div44.m = phi i64 [%div44, %for.body.51], [ 0, %for.cond.30.preheader]
+  br i1 true, label %end, label %for.cond.30.preheader
+
+end:
+  ret i64 %div44.m
+
+for.body.51:                                      ; preds = %for.body.51, %for.body.51.lr.ph
+  %indvars.iv86 = phi i64 [ %2, %for.body.51.lr.ph ], [ undef, %for.body.51 ]
+  %arrayidx53 = getelementptr inbounds float, float* %0, i64 %indvars.iv86
+  %3 = load float, float* %arrayidx53, align 4
+  %arrayidx55 = getelementptr inbounds float, float* %d, i64 0
+  %mul56 = fmul float %3, undef
+  store float %mul56, float* %arrayidx55, align 4
+  br i1 false, label %for.body.51, label %for.cond.60.preheader
+}

Added: polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb.ll?rev=245288&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb.ll (added)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb.ll Tue Aug 18 06:56:00 2015
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s --check-prefix=CODEGEN
+;
+; TODO: This is a negative test.
+;
+;       Once we use isl to come up with loop bounds this should work
+;       and hopefully not break 
+;
+; CHECK-NOT: Valid Region
+; CODEGEN-NOT: polly
+;
+;    void f(int *A, int N) {
+;      for (int i = 0; i < N; i++)
+;        for (int j = 0; j < i / 3; j++)
+;          A[i] += A[j];
+;    }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A, i32 %N) {
+bb:
+  %tmp = sext i32 %N to i64
+  br label %bb3
+
+bb3:                                              ; preds = %bb19, %bb
+  %indvars.iv1 = phi i64 [ %indvars.iv.next2, %bb19 ], [ 0, %bb ]
+  %tmp4 = icmp slt i64 %indvars.iv1, %tmp
+  br i1 %tmp4, label %bb5, label %bb20
+
+bb5:                                              ; preds = %bb3
+  br label %bb6
+
+bb6:                                              ; preds = %bb17, %bb5
+  %indvars.iv = phi i64 [ %indvars.iv.next, %bb17 ], [ 0, %bb5 ]
+  %tmp7 = trunc i64 %indvars.iv1 to i32
+  %tmp8 = sdiv i32 %tmp7, 3
+  %tmp9 = sext i32 %tmp8 to i64
+  %tmp10 = icmp slt i64 %indvars.iv, %tmp9
+  br i1 %tmp10, label %bb11, label %bb18
+
+bb11:                                             ; preds = %bb6
+  %tmp12 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+  %tmp13 = load i32, i32* %tmp12, align 4
+  %tmp14 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
+  %tmp15 = load i32, i32* %tmp14, align 4
+  %tmp16 = add nsw i32 %tmp15, %tmp13
+  store i32 %tmp16, i32* %tmp14, align 4
+  br label %bb17
+
+bb17:                                             ; preds = %bb11
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %bb6
+
+bb18:                                             ; preds = %bb6
+  br label %bb19
+
+bb19:                                             ; preds = %bb18
+  %indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
+  br label %bb3
+
+bb20:                                             ; preds = %bb3
+  ret void
+}

Added: polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb_invariant.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb_invariant.ll?rev=245288&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb_invariant.ll (added)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_lb_invariant.ll Tue Aug 18 06:56:00 2015
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly -S -polly-codegen -polly-no-early-exit < %s | FileCheck %s
+;
+; Check that this will not crash our code generation.
+;
+; CHECK: polly.start:
+;
+;    void f(int *A, int N) {
+;      for (int i = 0; i < N / 4; i++)
+;        A[i] += A[i - 1];
+;    }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A, i32 %N) {
+bb:
+  %tmp = sdiv i32 %N, 4
+  %tmp2 = sext i32 %tmp to i64
+  br label %bb1
+
+bb1:                                              ; preds = %bb11, %bb
+  %indvars.iv = phi i64 [ %indvars.iv.next, %bb11 ], [ 0, %bb ]
+  %tmp3 = icmp slt i64 %indvars.iv, %tmp2
+  br i1 %tmp3, label %bb4, label %bb12
+
+bb4:                                              ; preds = %bb1
+  %tmp5 = add nsw i64 %indvars.iv, -1
+  %tmp6 = getelementptr inbounds i32, i32* %A, i64 %tmp5
+  %tmp7 = load i32, i32* %tmp6, align 4
+  %tmp8 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+  %tmp9 = load i32, i32* %tmp8, align 4
+  %tmp10 = add nsw i32 %tmp9, %tmp7
+  store i32 %tmp10, i32* %tmp8, align 4
+  br label %bb11
+
+bb11:                                             ; preds = %bb4
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %bb1
+
+bb12:                                             ; preds = %bb1
+  ret void
+}

Added: polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_rtc.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_rtc.ll?rev=245288&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_rtc.ll (added)
+++ polly/trunk/test/Isl/CodeGen/inner_scev_sdiv_in_rtc.ll Tue Aug 18 06:56:00 2015
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s
+;
+; This will just check that we generate valid code here.
+;
+; CHECK: polly.start:
+;
+;    void f(int *A, int *B) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i % 3] = B[i / 42];
+;    }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A, i32* %B, i32 %N) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb9, %bb
+  %i.0 = phi i32 [ 0, %bb ], [ %tmp10, %bb9 ]
+  %exitcond = icmp ne i32 %i.0, %N
+  br i1 %exitcond, label %bb2, label %bb11
+
+bb2:                                              ; preds = %bb1
+  %tmp = sdiv i32 %i.0, 42
+  %tmp3 = sext i32 %tmp to i64
+  %tmp4 = getelementptr inbounds i32, i32* %B, i64 %tmp3
+  %tmp5 = load i32, i32* %tmp4, align 4
+  %tmp6 = srem i32 %i.0, 3
+  %tmp7 = sext i32 %tmp6 to i64
+  %tmp8 = getelementptr inbounds i32, i32* %A, i64 %tmp7
+  store i32 %tmp5, i32* %tmp8, align 4
+  br label %bb9
+
+bb9:                                              ; preds = %bb2
+  %tmp10 = add nuw nsw i32 %i.0, 1
+  br label %bb1
+
+bb11:                                             ; preds = %bb1
+  ret void
+}




More information about the llvm-commits mailing list