Index: llvm/include/llvm/Analysis/BasicAliasAnalysis.h =================================================================== --- llvm/include/llvm/Analysis/BasicAliasAnalysis.h +++ llvm/include/llvm/Analysis/BasicAliasAnalysis.h @@ -140,8 +140,6 @@ APInt Offset; // Scaled variable (non-constant) indices. SmallVector VarIndices; - // Is GEP index scale compile-time constant. - bool HasCompileTimeConstantScale; // Are all operations inbounds GEPs or non-indexing operations? // (None iff expression doesn't involve any geps) Optional InBounds; @@ -159,8 +157,7 @@ OS << ", "; VarIndices[i].print(OS); } - OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale - << ")"; + OS << "])"; } }; Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -91,8 +91,7 @@ const unsigned MaxNumPhiBBsValueReachabilityCheck = 20; // The max limit of the search depth in DecomposeGEPExpression() and -// getUnderlyingObject(), both functions need to use the same search -// depth otherwise the algorithm in aliasGEP will assert. +// getUnderlyingObject(). static const unsigned MaxLookupSearchDepth = 6; bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA, @@ -462,11 +461,6 @@ /// in the VarIndices vector) are Value*'s that are known to be scaled by the /// specified amount, but which may have other unrepresented high bits. As /// such, the gep cannot necessarily be reconstructed from its decomposed form. -/// -/// This function is capable of analyzing everything that getUnderlyingObject -/// can look through. To be able to do that getUnderlyingObject and -/// DecomposeGEPExpression must use the same search depth -/// (MaxLookupSearchDepth). BasicAAResult::DecomposedGEP BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT) { @@ -478,7 +472,6 @@ unsigned MaxPointerSize = getMaxPointerSize(DL); DecomposedGEP Decomposed; Decomposed.Offset = APInt(MaxPointerSize, 0); - Decomposed.HasCompileTimeConstantScale = true; do { // See if this is a bitcast or GEP. const Operator *Op = dyn_cast(V); @@ -541,7 +534,6 @@ // constant. if (isa(GEPOp->getSourceElementType())) { Decomposed.Base = V; - Decomposed.HasCompileTimeConstantScale = false; return Decomposed; } @@ -1084,16 +1076,10 @@ DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT); DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT); - // Don't attempt to analyze the decomposed GEP if index scale is not a - // compile-time constant. - if (!DecompGEP1.HasCompileTimeConstantScale || - !DecompGEP2.HasCompileTimeConstantScale) + // Bail if we were not able to decompose anything. + if (DecompGEP1.Base == GEP1 && DecompGEP2.Base == V2) return AliasResult::MayAlias; - assert(DecompGEP1.Base == UnderlyingV1 && DecompGEP2.Base == UnderlyingV2 && - "DecomposeGEPExpression returned a result different from " - "getUnderlyingObject"); - // Subtract the GEP2 pointer from the GEP1 pointer to find out their // symbolic difference. DecompGEP1.Offset -= DecompGEP2.Offset; @@ -1118,13 +1104,13 @@ // when performing the alias check on the underlying objects. if (DecompGEP1.Offset == 0 && DecompGEP1.VarIndices.empty()) return getBestAAResults().alias( - MemoryLocation(UnderlyingV1, V1Size), - MemoryLocation(UnderlyingV2, V2Size), AAQI); + MemoryLocation(DecompGEP1.Base, V1Size), + MemoryLocation(DecompGEP2.Base, V2Size), AAQI); // Do the base pointers alias? AliasResult BaseAlias = getBestAAResults().alias( - MemoryLocation::getBeforeOrAfter(UnderlyingV1), - MemoryLocation::getBeforeOrAfter(UnderlyingV2), AAQI); + MemoryLocation::getBeforeOrAfter(DecompGEP1.Base), + MemoryLocation::getBeforeOrAfter(DecompGEP2.Base), AAQI); // If we get a No or May, then return it immediately, no amount of analysis // will improve this situation. Index: llvm/test/Analysis/BasicAA/vscale.ll =================================================================== --- llvm/test/Analysis/BasicAA/vscale.ll +++ llvm/test/Analysis/BasicAA/vscale.ll @@ -130,7 +130,7 @@ ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1 ; CHECK-DAG: MayAlias: * %p, i32* %gep ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_1 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 define void @gep_recursion_level_1(i32* %a, * %p) { %gep = getelementptr , * %p, i64 1, i64 2 %gep_rec_1 = getelementptr i32, i32* %gep, i64 1 @@ -143,7 +143,7 @@ ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1 ; CHECK-DAG: MayAlias: * %p, i32* %gep ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_1 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 define void @gep_recursion_level_1_bitcast(i32* %a) { %p = bitcast i32* %a to * %gep = getelementptr , * %p, i64 1, i64 2 @@ -159,9 +159,9 @@ ; CHECK-DAG: MayAlias: * %p, i32* %gep ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_2 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_2 -; CHECK-DAG: MayAlias: i32* %gep_rec_1, i32* %gep_rec_2 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2 +; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_2 define void @gep_recursion_level_2(i32* %a, * %p) { %gep = getelementptr , * %p, i64 1, i64 2 %gep_rec_1 = getelementptr i32, i32* %gep, i64 1 @@ -185,27 +185,27 @@ ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_4 ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_5 ; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_2 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_3 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_4 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_5 -; CHECK-DAG: MayAlias: i32* %gep, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: i32* %gep_rec_1, i32* %gep_rec_2 -; CHECK-DAG: MayAlias: i32* %gep_rec_1, i32* %gep_rec_3 -; CHECK-DAG: MayAlias: i32* %gep_rec_1, i32* %gep_rec_4 -; CHECK-DAG: MayAlias: i32* %gep_rec_1, i32* %gep_rec_5 -; CHECK-DAG: MayAlias: i32* %gep_rec_1, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: i32* %gep_rec_2, i32* %gep_rec_3 -; CHECK-DAG: MayAlias: i32* %gep_rec_2, i32* %gep_rec_4 -; CHECK-DAG: MayAlias: i32* %gep_rec_2, i32* %gep_rec_5 -; CHECK-DAG: MayAlias: i32* %gep_rec_2, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: i32* %gep_rec_3, i32* %gep_rec_4 -; CHECK-DAG: MayAlias: i32* %gep_rec_3, i32* %gep_rec_5 -; CHECK-DAG: MayAlias: i32* %gep_rec_3, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: i32* %gep_rec_4, i32* %gep_rec_5 -; CHECK-DAG: MayAlias: i32* %gep_rec_4, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: i32* %gep_rec_5, i32* %gep_rec_6 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_3 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_4 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_5 +; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_6 +; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_2 +; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_3 +; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_4 +; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_5 +; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_6 +; CHECK-DAG: NoAlias: i32* %gep_rec_2, i32* %gep_rec_3 +; CHECK-DAG: NoAlias: i32* %gep_rec_2, i32* %gep_rec_4 +; CHECK-DAG: NoAlias: i32* %gep_rec_2, i32* %gep_rec_5 +; CHECK-DAG: NoAlias: i32* %gep_rec_2, i32* %gep_rec_6 +; CHECK-DAG: NoAlias: i32* %gep_rec_3, i32* %gep_rec_4 +; CHECK-DAG: NoAlias: i32* %gep_rec_3, i32* %gep_rec_5 +; CHECK-DAG: NoAlias: i32* %gep_rec_3, i32* %gep_rec_6 +; CHECK-DAG: NoAlias: i32* %gep_rec_4, i32* %gep_rec_5 +; CHECK-DAG: NoAlias: i32* %gep_rec_4, i32* %gep_rec_6 +; CHECK-DAG: NoAlias: i32* %gep_rec_5, i32* %gep_rec_6 ; GEP max lookup depth was set to 6. define void @gep_recursion_max_lookup_depth_reached(i32* %a, * %p) { %gep = getelementptr , * %p, i64 1, i64 2