Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1107,6 +1107,20 @@ : AliasResult::MayAlias; } + // If it can be confirmed NoAlias, no further decomposition is required. + if (isa(V2) && UnderlyingV1 == UnderlyingV2 && + V1Size.hasValue() && V2Size.hasValue()) { + auto *EltTy1 = GEP1->getResultElementType(); + auto *EltTy2 = cast(V2)->getResultElementType(); + unsigned MaxIndexSize = DL.getMaxIndexSizeInBits() - 1; + TypeSize AllocaTypeSize = DL.getTypeAllocSize(EltTy1); + Optional Offset = isPointerOffset(GEP1, V2, DL); + if ((EltTy1 == EltTy2) && Offset && !AllocaTypeSize.isScalable() && + std::max(V1Size.getValue(), V2Size.getValue()) <= std::abs(*Offset) && + (std::abs(*Offset) < 1ULL << MaxIndexSize)) + return AliasResult::NoAlias; + } + DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT); DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT); Index: llvm/test/Analysis/BasicAA/vscale.ll =================================================================== --- llvm/test/Analysis/BasicAA/vscale.ll +++ llvm/test/Analysis/BasicAA/vscale.ll @@ -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 Index: llvm/test/Transforms/GVN/vscale.ll =================================================================== --- llvm/test/Transforms/GVN/vscale.ll +++ llvm/test/Transforms/GVN/vscale.ll @@ -288,8 +288,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