Allow to disable unsigned operations (zext, icmp ugt, ...)
authorJohannes Doerfert <doerfert@cs.uni-saarland.de>
Fri, 2 Dec 2016 17:55:41 +0000 (17:55 +0000)
committerJohannes Doerfert <doerfert@cs.uni-saarland.de>
Fri, 2 Dec 2016 17:55:41 +0000 (17:55 +0000)
Unsigned operations are often useful to support but the heuristics are
not yet tuned. This options allows to disable them if necessary.

llvm-svn: 288521

polly/include/polly/ScopDetection.h
polly/lib/Analysis/ScopDetection.cpp
polly/lib/Support/SCEVValidator.cpp

index 2bca384..702eb7a 100644 (file)
@@ -111,6 +111,7 @@ extern bool PollyDelinearize;
 extern bool PollyUseRuntimeAliasChecks;
 extern bool PollyProcessUnprofitable;
 extern bool PollyInvariantLoadHoisting;
+extern bool PollyAllowUnsignedOperations;
 
 /// A function attribute which will cause Polly to skip the function
 extern llvm::StringRef PollySkipFnAttr;
index 756cb5d..60911a7 100644 (file)
@@ -109,6 +109,13 @@ static cl::opt<bool>
                    cl::Hidden, cl::init(false), cl::ZeroOrMore,
                    cl::cat(PollyCategory));
 
+bool polly::PollyAllowUnsignedOperations;
+static cl::opt<bool, true> XPollyAllowUnsignedOperations(
+    "polly-allow-unsigned-operations",
+    cl::desc("Allow unsigned operations such as comparisons or zero-extends."),
+    cl::location(PollyAllowUnsignedOperations), cl::Hidden, cl::ZeroOrMore,
+    cl::init(true), cl::cat(PollyCategory));
+
 bool polly::PollyUseRuntimeAliasChecks;
 static cl::opt<bool, true> XPollyUseRuntimeAliasChecks(
     "polly-use-runtime-alias-checks",
@@ -454,6 +461,11 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI,
   const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
   const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
 
+  // If unsigned operations are not allowed try to approximate the region.
+  if (ICmp->isUnsigned() && !PollyAllowUnsignedOperations)
+    return !IsLoopBranch && AllowNonAffineSubRegions &&
+           addOverApproximatedRegion(RI->getRegionFor(&BB), Context);
+
   // Check for invalid usage of different pointers in one expression.
   if (ICmp->isEquality() && involvesMultiplePtrs(LHS, nullptr, L) &&
       involvesMultiplePtrs(RHS, nullptr, L))
index b263873..848357f 100644 (file)
@@ -135,12 +135,27 @@ public:
     return ValidatorResult(SCEVType::INT);
   }
 
+  class ValidatorResult visitZeroExtendOrTruncateExpr(const SCEV *Expr,
+                                                      const SCEV *Operand) {
+    ValidatorResult Op = visit(Operand);
+    auto Type = Op.getType();
+
+    // If unsigned operations are allowed return the operand, otherwise
+    // check if we can model the expression without unsigned assumptions.
+    if (PollyAllowUnsignedOperations || Type == SCEVType::INVALID)
+      return Op;
+
+    if (Type == SCEVType::IV)
+      return ValidatorResult(SCEVType::INVALID);
+    return ValidatorResult(SCEVType::PARAM, Expr);
+  }
+
   class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) {
-    return visit(Expr->getOperand());
+    return visitZeroExtendOrTruncateExpr(Expr, Expr->getOperand());
   }
 
   class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
-    return visit(Expr->getOperand());
+    return visitZeroExtendOrTruncateExpr(Expr, Expr->getOperand());
   }
 
   class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
@@ -325,6 +340,9 @@ public:
   }
 
   ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) {
+    if (!PollyAllowUnsignedOperations)
+      return ValidatorResult(SCEVType::INVALID);
+
     auto *Dividend = Expr->getLHS();
     auto *Divisor = Expr->getRHS();
     return visitDivision(Dividend, Divisor, Expr);