Do not allow multiple possibly aliasing ptrs in an expression
Relational comparisons should not involve multiple potentially
aliasing pointers. Similarly this should hold for switch conditions
and the two conditions involved in equality comparisons (separately!).
This is a heuristic based on the C semantics that does only allow such
operations when the base pointers do point into the same object.
Since this makes aliasing likely we will bail out early instead of
producing a probably failing runtime check.
llvm-svn: 288516
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 438d80a..756cb5d 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -346,6 +346,40 @@
return true;
}
+bool ScopDetection::involvesMultiplePtrs(const SCEV *S0, const SCEV *S1,
+ Loop *Scope) const {
+ SetVector<Value *> Values;
+ findValues(S0, *SE, Values);
+ if (S1)
+ findValues(S1, *SE, Values);
+
+ SmallPtrSet<Value *, 8> PtrVals;
+ for (auto *V : Values) {
+ if (auto *P2I = dyn_cast<PtrToIntInst>(V))
+ V = P2I->getOperand(0);
+
+ if (!V->getType()->isPointerTy())
+ continue;
+
+ auto *PtrSCEV = SE->getSCEVAtScope(V, Scope);
+ if (isa<SCEVConstant>(PtrSCEV))
+ continue;
+
+ auto *BasePtr = dyn_cast<SCEVUnknown>(SE->getPointerBase(PtrSCEV));
+ if (!BasePtr)
+ return true;
+
+ auto *BasePtrVal = BasePtr->getValue();
+ if (PtrVals.insert(BasePtrVal).second) {
+ for (auto *PtrVal : PtrVals)
+ if (PtrVal != BasePtrVal && !AA->isNoAlias(PtrVal, BasePtrVal))
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool ScopDetection::isAffine(const SCEV *S, Loop *Scope,
DetectionContext &Context) const {
@@ -368,6 +402,10 @@
if (IsLoopBranch && L->isLoopLatch(&BB))
return false;
+ // Check for invalid usage of different pointers in one expression.
+ if (involvesMultiplePtrs(ConditionSCEV, nullptr, L))
+ return false;
+
if (isAffine(ConditionSCEV, L, Context))
return true;
@@ -416,6 +454,15 @@
const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
+ // Check for invalid usage of different pointers in one expression.
+ if (ICmp->isEquality() && involvesMultiplePtrs(LHS, nullptr, L) &&
+ involvesMultiplePtrs(RHS, nullptr, L))
+ return false;
+
+ // Check for invalid usage of different pointers in a relational comparison.
+ if (ICmp->isRelational() && involvesMultiplePtrs(LHS, RHS, L))
+ return false;
+
if (isAffine(LHS, L, Context) && isAffine(RHS, L, Context))
return true;