diff options
| -rw-r--r-- | polly/include/polly/ScopDetection.h | 1 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 12 | ||||
| -rw-r--r-- | polly/lib/Support/SCEVValidator.cpp | 22 |
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); |

