Skip to content

Commit 4356c6e

Browse files
committed
[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.
1 parent 70f6109 commit 4356c6e

File tree

3 files changed

+36
-26
lines changed

3 files changed

+36
-26
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 27 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,37 @@ 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 used the getVScaleRange to prove that Off >= (CR.upper * LSize).
1164+
ConstantRange CR = getVScaleRange(&F, Off.getBitWidth());
1165+
APInt UpperRange = CR.getUnsignedMax().umul_sat(
1166+
APInt(Off.getBitWidth(), LSize.getKnownMinValue()));
1167+
if (Off.uge(UpperRange))
1168+
return AliasResult::NoAlias;
11631169
}
1164-
return AliasResult::NoAlias;
11651170
}
11661171

1172+
// Bail on analysing scalable LocationSize
1173+
if (V1Size.isScalable() || V2Size.isScalable())
1174+
return AliasResult::MayAlias;
1175+
11671176
// We need to know both acess sizes for all the following heuristics.
11681177
if (!V1Size.hasValue() || !V2Size.hasValue())
11691178
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)