Skip to content

Commit 84ea236

Browse files
authored
[BasicAA] Handle scalable type sizes with constant offsets (llvm#80445)
This is a separate, but related issue to llvm#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. It also enables the added benefit of allowing better alias analysis when the RHS of the two values is scalable, but the LHS is normal and can be treated like any other aliasing query.
1 parent 13e52b3 commit 84ea236

File tree

3 files changed

+37
-26
lines changed

3 files changed

+37
-26
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,10 +1113,6 @@ AliasResult BasicAAResult::aliasGEP(
11131113
return BaseAlias;
11141114
}
11151115

1116-
// Bail on analysing scalable LocationSize
1117-
if (V1Size.isScalable() || V2Size.isScalable())
1118-
return AliasResult::MayAlias;
1119-
11201116
// If there is a constant difference between the pointers, but the difference
11211117
// is less than the size of the associated memory object, then we know
11221118
// that the objects are partially overlapping. If the difference is
@@ -1146,24 +1142,38 @@ AliasResult BasicAAResult::aliasGEP(
11461142
if (!VLeftSize.hasValue())
11471143
return AliasResult::MayAlias;
11481144

1149-
const uint64_t LSize = VLeftSize.getValue();
1150-
if (Off.ult(LSize)) {
1151-
// Conservatively drop processing if a phi was visited and/or offset is
1152-
// too big.
1153-
AliasResult AR = AliasResult::PartialAlias;
1154-
if (VRightSize.hasValue() && Off.ule(INT32_MAX) &&
1155-
(Off + VRightSize.getValue()).ule(LSize)) {
1156-
// Memory referenced by right pointer is nested. Save the offset in
1157-
// cache. Note that originally offset estimated as GEP1-V2, but
1158-
// AliasResult contains the shift that represents GEP1+Offset=V2.
1159-
AR.setOffset(-Off.getSExtValue());
1160-
AR.swap(Swapped);
1145+
const TypeSize LSize = VLeftSize.getValue();
1146+
if (!LSize.isScalable()) {
1147+
if (Off.ult(LSize)) {
1148+
// Conservatively drop processing if a phi was visited and/or offset is
1149+
// too big.
1150+
AliasResult AR = AliasResult::PartialAlias;
1151+
if (VRightSize.hasValue() && !VRightSize.isScalable() &&
1152+
Off.ule(INT32_MAX) && (Off + VRightSize.getValue()).ule(LSize)) {
1153+
// Memory referenced by right pointer is nested. Save the offset in
1154+
// cache. Note that originally offset estimated as GEP1-V2, but
1155+
// AliasResult contains the shift that represents GEP1+Offset=V2.
1156+
AR.setOffset(-Off.getSExtValue());
1157+
AR.swap(Swapped);
1158+
}
1159+
return AR;
11611160
}
1162-
return AR;
1161+
return AliasResult::NoAlias;
1162+
} else {
1163+
// We can use the getVScaleRange to prove that Off >= (CR.upper * LSize).
1164+
ConstantRange CR = getVScaleRange(&F, Off.getBitWidth());
1165+
bool Overflow;
1166+
APInt UpperRange = CR.getUnsignedMax().umul_ov(
1167+
APInt(Off.getBitWidth(), LSize.getKnownMinValue()), Overflow);
1168+
if (!Overflow && Off.uge(UpperRange))
1169+
return AliasResult::NoAlias;
11631170
}
1164-
return AliasResult::NoAlias;
11651171
}
11661172

1173+
// Bail on analysing scalable LocationSize
1174+
if (V1Size.isScalable() || V2Size.isScalable())
1175+
return AliasResult::MayAlias;
1176+
11671177
// We need to know both acess sizes for all the following heuristics.
11681178
if (!V1Size.hasValue() || !V2Size.hasValue())
11691179
return AliasResult::MayAlias;

llvm/test/Analysis/AliasSet/memloc-vscale.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ define void @ss2(ptr %p) {
3434
ret void
3535
}
3636
; CHECK-LABEL: Alias sets for function 'son':
37-
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %g, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8))
37+
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %g, LocationSize::precise(vscale x 16))
38+
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(8))
3839
define void @son(ptr %p) {
3940
%g = getelementptr i8, ptr %p, i64 8
4041
store <vscale x 2 x i64> zeroinitializer, ptr %g, align 2

llvm/test/Analysis/BasicAA/vscale.ll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ define void @gep_pos_scalable(ptr %p) vscale_range(1,16) {
292292
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <4 x i32>* %p
293293
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
294294
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <4 x i32>* %vm16
295-
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %p
295+
; CHECK-DAG: NoAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %p
296296
; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %p
297297
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %vm16
298298
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16
@@ -453,14 +453,14 @@ define void @gep_2048(ptr %p) {
453453
; CHECK-LABEL: gep_2048_vscalerange
454454
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %p
455455
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %p
456-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off255
457-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %off256, <vscale x 4 x i32>* %p
456+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off255
457+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %off256, <vscale x 4 x i32>* %p
458458
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %off256
459-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off256
460-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %p
461-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off255
459+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off256
460+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %p
461+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off255
462462
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %noff256
463-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off256
463+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off256
464464
define void @gep_2048_vscalerange(ptr %p) vscale_range(1,16) {
465465
%off255 = getelementptr i8, ptr %p, i64 255
466466
%noff255 = getelementptr i8, ptr %p, i64 -255

0 commit comments

Comments
 (0)