Skip to content

Commit 9bc7e54

Browse files
committed
[BasicAA] Make range check more precise
Make the range check more precise by calculating the range of potentially accessed bytes for both accesses and checking whether their intersection is empty. In that case there can be no overlap between the accesses and the result is NoAlias. This is more powerful than the previous approach, because it can deal with sign-wrapped ranges. In the test case the original range is [-1, INT_MAX] but becomes [0, INT_MIN] after applying the offset. This is a wrapping range, so getSignedMin/getSignedMax will treat it as a full range. However, the range excludes the elements [INT_MIN+1, -1], which is enough to prove NoAlias with an access at offset -1. Differential Revision: https://reviews.llvm.org/D112486
1 parent db848fb commit 9bc7e54

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ AliasResult BasicAAResult::aliasGEP(
12521252
APInt GCD;
12531253
bool AllNonNegative = DecompGEP1.Offset.isNonNegative();
12541254
bool AllNonPositive = DecompGEP1.Offset.isNonPositive();
1255-
ConstantRange Range = ConstantRange(DecompGEP1.Offset);
1255+
ConstantRange OffsetRange = ConstantRange(DecompGEP1.Offset);
12561256
for (unsigned i = 0, e = DecompGEP1.VarIndices.size(); i != e; ++i) {
12571257
const VariableGEPIndex &Index = DecompGEP1.VarIndices[i];
12581258
const APInt &Scale = Index.Scale;
@@ -1277,12 +1277,12 @@ AliasResult BasicAAResult::aliasGEP(
12771277
(SignKnownOne && Scale.isNonNegative());
12781278
}
12791279

1280-
assert(Range.getBitWidth() == Scale.getBitWidth() &&
1280+
assert(OffsetRange.getBitWidth() == Scale.getBitWidth() &&
12811281
"Bit widths are normalized to MaxPointerSize");
1282-
Range = Range.add(Index.Val
1282+
OffsetRange = OffsetRange.add(Index.Val
12831283
.evaluateWith(computeConstantRange(
12841284
Index.Val.V, true, &AC, Index.CxtI))
1285-
.sextOrTrunc(Range.getBitWidth())
1285+
.sextOrTrunc(OffsetRange.getBitWidth())
12861286
.smul_fast(ConstantRange(Scale)));
12871287
}
12881288

@@ -1315,15 +1315,15 @@ AliasResult BasicAAResult::aliasGEP(
13151315
(-DecompGEP1.Offset).uge(V1Size.getValue()))
13161316
return AliasResult::NoAlias;
13171317

1318-
if (!Range.isEmptySet()) {
1319-
// We know that Offset >= MinOffset.
1320-
// (MinOffset >= V2Size) => (Offset >= V2Size) => NoAlias.
1321-
if (V2Size.hasValue() && Range.getSignedMin().sge(V2Size.getValue()))
1322-
return AliasResult::NoAlias;
1323-
1324-
// We know that Offset <= MaxOffset.
1325-
// (MaxOffset <= -V1Size) => (Offset <= -V1Size) => NoAlias.
1326-
if (V1Size.hasValue() && Range.getSignedMax().sle(-V1Size.getValue()))
1318+
if (V1Size.hasValue() && V2Size.hasValue()) {
1319+
// Compute ranges of potentially accessed bytes for both accesses. If the
1320+
// interseciton is empty, there can be no overlap.
1321+
unsigned BW = OffsetRange.getBitWidth();
1322+
ConstantRange Range1 = OffsetRange.add(
1323+
ConstantRange(APInt(BW, 0), APInt(BW, V1Size.getValue())));
1324+
ConstantRange Range2 =
1325+
ConstantRange(APInt(BW, 0), APInt(BW, V2Size.getValue()));
1326+
if (Range1.intersectWith(Range2).isEmptySet())
13271327
return AliasResult::NoAlias;
13281328
}
13291329

llvm/test/Analysis/BasicAA/range.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,13 @@ define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) {
196196
ret void
197197
}
198198

199-
; TODO: p.neg1 and p.o.1 don't alias, even though the addition o+1 may overflow.
199+
; p.neg1 and p.o.1 don't alias, even though the addition o+1 may overflow.
200200
; While it makes INT_MIN a possible offset, offset -1 is not possible.
201201
; CHECK-LABEL: Function: benign_overflow
202202
; CHECK: MayAlias: i8* %p, i8* %p.o
203203
; CHECK: MayAlias: i8* %p.neg1, i8* %p.o
204204
; CHECK: MayAlias: i8* %p, i8* %p.o.1
205-
; CHECK: MayAlias: i8* %p.neg1, i8* %p.o.1
205+
; CHECK: NoAlias: i8* %p.neg1, i8* %p.o.1
206206
; CHECK: NoAlias: i8* %p.o, i8* %p.o.1
207207
define void @benign_overflow(i8* %p, i64 %o) {
208208
%c = icmp sge i64 %o, -1

0 commit comments

Comments
 (0)