Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -82,7 +82,9 @@ // The max limit of the search depth in DecomposeGEPExpression() and // getUnderlyingObject(). -static const unsigned MaxLookupSearchDepth = 6; +static cl::opt + MaxLookupSearchDepth("max-lookup-search-depth", cl::init(6), cl::Hidden, + cl::desc("Max limit of the search depth")); bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv) { @@ -610,18 +612,40 @@ if (CIdx->isZero()) continue; - // Don't attempt to analyze GEPs if the scalable index is not zero. + // Use VariableGEPIndex with a vscale constant expression if the + // scalable index is not zero. TypeSize AllocTypeSize = DL.getTypeAllocSize(GTI.getIndexedType()); if (AllocTypeSize.isScalable()) { - Decomposed.Base = V; - return Decomposed; - } - - Decomposed.Offset += AllocTypeSize.getFixedSize() * - CIdx->getValue().sextOrTrunc(MaxIndexSize); + GepHasConstantOffset = false; + + // If the integer type is smaller than the index size, it is + // implicitly sign extended or truncated to index size. + unsigned Width = Index->getType()->getIntegerBitWidth(); + unsigned SExtBits = IndexSize > Width ? IndexSize - Width : 0; + unsigned TruncBits = IndexSize < Width ? Width - IndexSize : 0; + LinearExpression LE = GetLinearExpression( + CastedValue(Index, 0, SExtBits, TruncBits), DL, 0, AC, DT); + + // Scale by the type size. + unsigned TypeSize = AllocTypeSize.getKnownMinSize(); + LE = LE.mul(APInt(IndexSize, TypeSize), GEPOp->isInBounds()); + Decomposed.Offset += LE.Offset.sext(MaxIndexSize); + APInt Scale = LE.Scale.sext(MaxIndexSize); + + // Make sure that we have a scale that makes sense for this target's + // index size. + const uint64_t CValue = CIdx->getSExtValue(); + Scale = adjustToIndexSize(APInt(IndexSize, CValue), IndexSize); + + VariableGEPIndex Entry = {LE.Val, Scale, CxtI, LE.IsNSW}; + Decomposed.VarIndices.push_back(Entry); + } else + Decomposed.Offset += AllocTypeSize.getFixedSize() * + CIdx->getValue().sextOrTrunc(MaxIndexSize); continue; } + // The vscale index is non-constant. TypeSize AllocTypeSize = DL.getTypeAllocSize(GTI.getIndexedType()); if (AllocTypeSize.isScalable()) { Decomposed.Base = V; Index: llvm/test/Analysis/BasicAA/vscale.ll =================================================================== --- llvm/test/Analysis/BasicAA/vscale.ll +++ llvm/test/Analysis/BasicAA/vscale.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -max-lookup-search-depth=7 -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s ; getelementptr @@ -76,8 +76,8 @@ ; CHECK-LABEL: gep_same_base_const_offset ; CHECK-DAG: MayAlias: i32* %gep1, * %p ; CHECK-DAG: MayAlias: i32* %gep2, * %p -; TODO: AliasResult for gep1,gep2 can be improved as NoAlias -; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2 +; AliasResult for gep1,gep2 can be improved as NoAlias +; CHECK-DAG: NoAlias: i32* %gep1, i32* %gep2 define void @gep_same_base_const_offset(* %p) { %gep1 = getelementptr , * %p, i64 1, i64 0 %gep2 = getelementptr , * %p, i64 1, i64 1 @@ -122,7 +122,7 @@ ; CHECK-LABEL: gep_bitcast_1 ; CHECK-DAG: MustAlias: * %p, i32* %p2 ; CHECK-DAG: MayAlias: i32* %gep1, * %p -; CHECK-DAG: MayAlias: i32* %gep1, i32* %p2 +; CHECK-DAG: NoAlias: i32* %gep1, i32* %p2 ; CHECK-DAG: MayAlias: i32* %gep2, * %p ; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2 ; CHECK-DAG: NoAlias: i32* %gep2, i32* %p2 @@ -142,7 +142,7 @@ ; CHECK-DAG: MayAlias: i32* %gep1, * %p ; CHECK-DAG: MayAlias: i32* %gep1, * %p2 ; CHECK-DAG: MayAlias: float* %gep2, * %p -; CHECK-DAG: MayAlias: i32* %gep1, float* %gep2 +; CHECK-DAG: MustAlias: i32* %gep1, float* %gep2 ; CHECK-DAG: MayAlias: float* %gep2, * %p2 define void @gep_bitcast_2(* %p) { %gep1 = getelementptr , * %p, i64 1, i64 0 @@ -176,8 +176,8 @@ ; CHECK-LABEL: gep_recursion_level_1_bitcast ; CHECK-DAG: MustAlias: i32* %a, * %p -; CHECK-DAG: MayAlias: i32* %a, i32* %gep -; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1 +; CHECK-DAG: NoAlias: i32* %a, i32* %gep +; CHECK-DAG: NoAlias: i32* %a, i32* %gep_rec_1 ; CHECK-DAG: MayAlias: i32* %gep, * %p ; CHECK-DAG: MayAlias: i32* %gep_rec_1, * %p ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 @@ -252,7 +252,7 @@ ; 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. +; GEP max lookup depth was set to 7. define void @gep_recursion_max_lookup_depth_reached(i32* %a, * %p) { %gep = getelementptr , * %p, i64 1, i64 2 %gep_rec_1 = getelementptr i32, i32* %gep, i64 1 Index: llvm/test/Transforms/GVN/vscale.ll =================================================================== --- llvm/test/Transforms/GVN/vscale.ll +++ llvm/test/Transforms/GVN/vscale.ll @@ -82,16 +82,12 @@ ret i32 %add } -; TODO: BasicAA return MayAlias for %gep1,%gep2, could improve as MustAlias. +; BasicAA return MayAlias for %gep1,%gep2, could improve as MustAlias. define i32 @load_clobber_load_gep3(* %p) { ; CHECK-LABEL: @load_clobber_load_gep3( ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr , * [[P:%.*]], i64 1, i64 0 ; CHECK-NEXT: [[LOAD1:%.*]] = load i32, i32* [[GEP1]], align 4 -; CHECK-NEXT: [[P2:%.*]] = bitcast * [[P]] to * -; CHECK-NEXT: [[GEP2:%.*]] = getelementptr , * [[P2]], i64 1, i64 0 -; CHECK-NEXT: [[LOAD2:%.*]] = load float, float* [[GEP2]], align 4 -; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[LOAD2]] to i32 -; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[CAST]] +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD1]] ; CHECK-NEXT: ret i32 [[ADD]] ; %gep1 = getelementptr , * %p, i64 1, i64 0 @@ -288,8 +284,7 @@ ; CHECK-NEXT: store i32 1, i32* [[GEP2]], align 4 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] ; CHECK: if.then: -; CHECK-NEXT: [[T:%.*]] = load i32, i32* [[GEP1]], align 4 -; CHECK-NEXT: store i32 [[T]], i32* [[Q:%.*]], align 4 +; CHECK-NEXT: store i32 0, i32* [[Q:%.*]], align 4 ; CHECK-NEXT: ret void ; CHECK: if.else: ; CHECK-NEXT: ret void