summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/ScopDetection.h1
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp12
-rw-r--r--polly/lib/Support/SCEVValidator.cpp22
3 files changed, 33 insertions, 2 deletions
diff --git a/polly/include/polly/ScopDetection.h b/polly/include/polly/ScopDetection.h
index 2bca384041f..702eb7ab6e9 100644
--- a/polly/include/polly/ScopDetection.h
+++ b/polly/include/polly/ScopDetection.h
@@ -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;
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 756cb5d6d68..60911a7e5b9 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -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))
diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp
index b263873284d..848357f5afb 100644
--- a/polly/lib/Support/SCEVValidator.cpp
+++ b/polly/lib/Support/SCEVValidator.cpp
@@ -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);
OpenPOWER on IntegriCloud