Skip to content

Commit 9d8a236

Browse files
authored
[BasicAA] Check for Overflow using vscale_range (#81144)
This extends #80818 when IsNSW is lost (possibly due to looking through multiple GEPs), to check the vscale_range for an access that will not overflow even with the maximum range.
1 parent 53c260d commit 9d8a236

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ AliasResult BasicAAResult::aliasGEP(
11731173
// VScale Alias Analysis - Given one scalable offset between accesses and a
11741174
// scalable typesize, we can divide each side by vscale, treating both values
11751175
// as a constant. We prove that Offset/vscale >= TypeSize/vscale.
1176-
if (DecompGEP1.VarIndices.size() == 1 && DecompGEP1.VarIndices[0].IsNSW &&
1176+
if (DecompGEP1.VarIndices.size() == 1 &&
11771177
DecompGEP1.VarIndices[0].Val.TruncBits == 0 &&
11781178
DecompGEP1.Offset.isZero() &&
11791179
PatternMatch::match(DecompGEP1.VarIndices[0].Val.V,
@@ -1183,12 +1183,22 @@ AliasResult BasicAAResult::aliasGEP(
11831183
ScalableVar.IsNegated ? -ScalableVar.Scale : ScalableVar.Scale;
11841184
LocationSize VLeftSize = Scale.isNegative() ? V1Size : V2Size;
11851185

1186-
// Note that we do not check that the typesize is scalable, as vscale >= 1
1187-
// so noalias still holds so long as the dependency distance is at least as
1188-
// big as the typesize.
1189-
if (VLeftSize.hasValue() &&
1190-
Scale.abs().uge(VLeftSize.getValue().getKnownMinValue()))
1191-
return AliasResult::NoAlias;
1186+
// Check if the offset is known to not overflow, if it does then attempt to
1187+
// prove it with the known values of vscale_range.
1188+
bool Overflows = !DecompGEP1.VarIndices[0].IsNSW;
1189+
if (Overflows) {
1190+
ConstantRange CR = getVScaleRange(&F, Scale.getBitWidth());
1191+
(void)CR.getSignedMax().smul_ov(Scale, Overflows);
1192+
}
1193+
1194+
if (!Overflows) {
1195+
// Note that we do not check that the typesize is scalable, as vscale >= 1
1196+
// so noalias still holds so long as the dependency distance is at least
1197+
// as big as the typesize.
1198+
if (VLeftSize.hasValue() &&
1199+
Scale.abs().uge(VLeftSize.getValue().getKnownMinValue()))
1200+
return AliasResult::NoAlias;
1201+
}
11921202
}
11931203

11941204
// Bail on analysing scalable LocationSize

llvm/test/Analysis/BasicAA/vscale.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ define void @vscale_negativescale(ptr %p) vscale_range(1,16) {
471471

472472
; CHECK-LABEL: onevscale
473473
; CHECK-DAG: MustAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp162
474-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp161b
475-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161b, <vscale x 4 x i32>* %vp162
474+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp161b
475+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %vp161b, <vscale x 4 x i32>* %vp162
476476
define void @onevscale(ptr %p) vscale_range(1,16) {
477477
%v1 = call i64 @llvm.vscale.i64()
478478
%vp1 = mul nsw i64 %v1, 16
@@ -489,7 +489,7 @@ define void @onevscale(ptr %p) vscale_range(1,16) {
489489

490490
; CHECK-LABEL: twovscales
491491
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp162
492-
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp161b
492+
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp161b
493493
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161b, <vscale x 4 x i32>* %vp162
494494
define void @twovscales(ptr %p) vscale_range(1,16) {
495495
%v1 = call i64 @llvm.vscale.i64()

0 commit comments

Comments
 (0)