From 7805c3ebd6384413b70430dc54f05c44939c7ec1 Mon Sep 17 00:00:00 2001 From: David Green Date: Mon, 5 Feb 2024 09:59:32 +0000 Subject: [PATCH] [BasicAA] Handle scalable type sizes with constant offsets This is a separate, but related issue to #69152 that was attempting to improve AA with scalable dependency distances. This patch attempts to improve when there are scalable accesses with a constant offset between them. We happen to get a report of such a thing recently, where so long as the vscale_range is known, the maximum size of the access can be assessed and better aliasing results can be returned. The Upper range of the vscale_range, along with known part of the typesize are used to prove that Off >= CR.upper * LSize. It does not try to produce PartialAlias results at the moment from the lower vscale_range. --- llvm/lib/Analysis/BasicAliasAnalysis.cpp | 46 ++++++++++++-------- llvm/test/Analysis/AliasSet/memloc-vscale.ll | 3 +- llvm/test/Analysis/BasicAA/vscale.ll | 14 +++--- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 1028b52a79123f..19c4393add6ab9 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1113,10 +1113,6 @@ AliasResult BasicAAResult::aliasGEP( return BaseAlias; } - // Bail on analysing scalable LocationSize - if (V1Size.isScalable() || V2Size.isScalable()) - return AliasResult::MayAlias; - // If there is a constant difference between the pointers, but the difference // is less than the size of the associated memory object, then we know // that the objects are partially overlapping. If the difference is @@ -1146,24 +1142,38 @@ AliasResult BasicAAResult::aliasGEP( if (!VLeftSize.hasValue()) return AliasResult::MayAlias; - const uint64_t LSize = VLeftSize.getValue(); - if (Off.ult(LSize)) { - // Conservatively drop processing if a phi was visited and/or offset is - // too big. - AliasResult AR = AliasResult::PartialAlias; - if (VRightSize.hasValue() && Off.ule(INT32_MAX) && - (Off + VRightSize.getValue()).ule(LSize)) { - // Memory referenced by right pointer is nested. Save the offset in - // cache. Note that originally offset estimated as GEP1-V2, but - // AliasResult contains the shift that represents GEP1+Offset=V2. - AR.setOffset(-Off.getSExtValue()); - AR.swap(Swapped); + const TypeSize LSize = VLeftSize.getValue(); + if (!LSize.isScalable()) { + if (Off.ult(LSize)) { + // Conservatively drop processing if a phi was visited and/or offset is + // too big. + AliasResult AR = AliasResult::PartialAlias; + if (VRightSize.hasValue() && !VRightSize.isScalable() && + Off.ule(INT32_MAX) && (Off + VRightSize.getValue()).ule(LSize)) { + // Memory referenced by right pointer is nested. Save the offset in + // cache. Note that originally offset estimated as GEP1-V2, but + // AliasResult contains the shift that represents GEP1+Offset=V2. + AR.setOffset(-Off.getSExtValue()); + AR.swap(Swapped); + } + return AR; } - return AR; + return AliasResult::NoAlias; + } else { + // We can use the getVScaleRange to prove that Off >= (CR.upper * LSize). + ConstantRange CR = getVScaleRange(&F, Off.getBitWidth()); + bool Overflow; + APInt UpperRange = CR.getUnsignedMax().umul_ov( + APInt(Off.getBitWidth(), LSize.getKnownMinValue()), Overflow); + if (!Overflow && Off.uge(UpperRange)) + return AliasResult::NoAlias; } - return AliasResult::NoAlias; } + // Bail on analysing scalable LocationSize + if (V1Size.isScalable() || V2Size.isScalable()) + return AliasResult::MayAlias; + // We need to know both acess sizes for all the following heuristics. if (!V1Size.hasValue() || !V2Size.hasValue()) return AliasResult::MayAlias; diff --git a/llvm/test/Analysis/AliasSet/memloc-vscale.ll b/llvm/test/Analysis/AliasSet/memloc-vscale.ll index 1c7ca79c8db11f..6b416046374057 100644 --- a/llvm/test/Analysis/AliasSet/memloc-vscale.ll +++ b/llvm/test/Analysis/AliasSet/memloc-vscale.ll @@ -34,7 +34,8 @@ define void @ss2(ptr %p) { ret void } ; CHECK-LABEL: Alias sets for function 'son': -; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %g, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8)) +; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %g, LocationSize::precise(vscale x 16)) +; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(8)) define void @son(ptr %p) { %g = getelementptr i8, ptr %p, i64 8 store zeroinitializer, ptr %g, align 2 diff --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll index 5c3c185af9141f..339e4400abc0f8 100644 --- a/llvm/test/Analysis/BasicAA/vscale.ll +++ b/llvm/test/Analysis/BasicAA/vscale.ll @@ -292,7 +292,7 @@ define void @gep_pos_scalable(ptr %p) vscale_range(1,16) { ; CHECK-DAG: MayAlias: * %m16, <4 x i32>* %p ; CHECK-DAG: MayAlias: * %m16, * %vm16 ; CHECK-DAG: MayAlias: * %m16, <4 x i32>* %vm16 -; CHECK-DAG: MayAlias: <4 x i32>* %m16, * %p +; CHECK-DAG: NoAlias: <4 x i32>* %m16, * %p ; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %p ; CHECK-DAG: MayAlias: <4 x i32>* %m16, * %vm16 ; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16 @@ -453,14 +453,14 @@ define void @gep_2048(ptr %p) { ; CHECK-LABEL: gep_2048_vscalerange ; CHECK-DAG: MayAlias: * %off255, * %p ; CHECK-DAG: MayAlias: * %noff255, * %p -; CHECK-DAG: MayAlias: * %noff255, * %off255 -; CHECK-DAG: MayAlias: * %off256, * %p +; CHECK-DAG: NoAlias: * %noff255, * %off255 +; CHECK-DAG: NoAlias: * %off256, * %p ; CHECK-DAG: MayAlias: * %off255, * %off256 -; CHECK-DAG: MayAlias: * %noff255, * %off256 -; CHECK-DAG: MayAlias: * %noff256, * %p -; CHECK-DAG: MayAlias: * %noff256, * %off255 +; CHECK-DAG: NoAlias: * %noff255, * %off256 +; CHECK-DAG: NoAlias: * %noff256, * %p +; CHECK-DAG: NoAlias: * %noff256, * %off255 ; CHECK-DAG: MayAlias: * %noff255, * %noff256 -; CHECK-DAG: MayAlias: * %noff256, * %off256 +; CHECK-DAG: NoAlias: * %noff256, * %off256 define void @gep_2048_vscalerange(ptr %p) vscale_range(1,16) { %off255 = getelementptr i8, ptr %p, i64 255 %noff255 = getelementptr i8, ptr %p, i64 -255