Skip to content

Commit

Permalink
[BasicAA] Handle scalable type sizes with constant offsets
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
davemgreen committed Feb 5, 2024
1 parent 3e230bb commit 7805c3e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 26 deletions.
46 changes: 28 additions & 18 deletions llvm/lib/Analysis/BasicAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion llvm/test/Analysis/AliasSet/memloc-vscale.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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 <vscale x 2 x i64> zeroinitializer, ptr %g, align 2
Expand Down
14 changes: 7 additions & 7 deletions llvm/test/Analysis/BasicAA/vscale.ll
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ define void @gep_pos_scalable(ptr %p) vscale_range(1,16) {
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <4 x i32>* %vm16
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %p
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16
Expand Down Expand Up @@ -453,14 +453,14 @@ define void @gep_2048(ptr %p) {
; CHECK-LABEL: gep_2048_vscalerange
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off255
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %off256, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off255
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %off256, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %off256
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off256
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off255
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off256
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off255
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %noff256
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off256
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %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
Expand Down

0 comments on commit 7805c3e

Please sign in to comment.