Skip to content

Commit bfda694

Browse files
committed
[BasicAA] Fix a bug with relational reasoning across iterations
Due to the recursion through phis basicaa does, the code needs to be extremely careful not to reason about equality between values which might represent distinct iterations. I'm generally skeptical of the correctness of the whole scheme, but this particular patch fixes one particular instance which is demonstrateable incorrect. Interestingly, this appears to be the second attempted fix for the same issue. The former fix is incomplete and doesn't address the actual issue. Differential Revision: https://reviews.llvm.org/D92694
1 parent 13ee00d commit bfda694

File tree

3 files changed

+39
-21
lines changed

3 files changed

+39
-21
lines changed

llvm/include/llvm/Analysis/BasicAliasAnalysis.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
202202
const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
203203
LocationSize ObjectAccessSize);
204204

205+
AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
206+
LocationSize MaybeV1Size,
207+
const GEPOperator *GEP2,
208+
LocationSize MaybeV2Size,
209+
const DataLayout &DL);
210+
205211
/// A Heuristic for aliasGEP that searches for a constant offset
206212
/// between the variables.
207213
///

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,11 +1032,11 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call1,
10321032

10331033
/// Provide ad-hoc rules to disambiguate accesses through two GEP operators,
10341034
/// both having the exact same pointer operand.
1035-
static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
1036-
LocationSize MaybeV1Size,
1037-
const GEPOperator *GEP2,
1038-
LocationSize MaybeV2Size,
1039-
const DataLayout &DL) {
1035+
AliasResult BasicAAResult::aliasSameBasePointerGEPs(const GEPOperator *GEP1,
1036+
LocationSize MaybeV1Size,
1037+
const GEPOperator *GEP2,
1038+
LocationSize MaybeV2Size,
1039+
const DataLayout &DL) {
10401040
assert(GEP1->getPointerOperand()->stripPointerCastsAndInvariantGroups() ==
10411041
GEP2->getPointerOperand()->stripPointerCastsAndInvariantGroups() &&
10421042
GEP1->getPointerOperandType() == GEP2->getPointerOperandType() &&
@@ -1126,24 +1126,12 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
11261126
if (C1 && C2)
11271127
return NoAlias;
11281128
{
1129+
// If we're not potentially reasoning about values from different
1130+
// iterations, see if we can prove them inequal.
11291131
Value *GEP1LastIdx = GEP1->getOperand(GEP1->getNumOperands() - 1);
11301132
Value *GEP2LastIdx = GEP2->getOperand(GEP2->getNumOperands() - 1);
1131-
if (isa<PHINode>(GEP1LastIdx) || isa<PHINode>(GEP2LastIdx)) {
1132-
// If one of the indices is a PHI node, be safe and only use
1133-
// computeKnownBits so we don't make any assumptions about the
1134-
// relationships between the two indices. This is important if we're
1135-
// asking about values from different loop iterations. See PR32314.
1136-
// TODO: We may be able to change the check so we only do this when
1137-
// we definitely looked through a PHINode.
1138-
if (GEP1LastIdx != GEP2LastIdx &&
1139-
GEP1LastIdx->getType() == GEP2LastIdx->getType()) {
1140-
KnownBits Known1 = computeKnownBits(GEP1LastIdx, DL);
1141-
KnownBits Known2 = computeKnownBits(GEP2LastIdx, DL);
1142-
if (Known1.Zero.intersects(Known2.One) ||
1143-
Known1.One.intersects(Known2.Zero))
1144-
return NoAlias;
1145-
}
1146-
} else if (isKnownNonEqual(GEP1LastIdx, GEP2LastIdx, DL))
1133+
if (VisitedPhiBBs.empty() &&
1134+
isKnownNonEqual(GEP1LastIdx, GEP2LastIdx, DL))
11471135
return NoAlias;
11481136
}
11491137
}

llvm/test/Analysis/BasicAA/phi-aa.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,27 @@ exit:
173173
}
174174

175175
declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1)
176+
177+
; CHECK-LABEL: unsound_inequality
178+
; CHECK: MayAlias: i32* %arrayidx13, i32* %phi
179+
; CHECK: MayAlias: i32* %arrayidx5, i32* %phi
180+
; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5
181+
182+
; When recursively reasoning about phis, we can't use predicates between
183+
; two values as we might be comparing the two from different iterations.
184+
define i32 @unsound_inequality(i32* %jj7, i32* %j) {
185+
entry:
186+
%oa5 = alloca [100 x i32], align 16
187+
br label %for.body
188+
189+
for.body: ; preds = %for.body, %entry
190+
%phi = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ]
191+
%idx = load i32, i32* %jj7, align 4
192+
%arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %idx
193+
store i32 0, i32* %arrayidx5, align 4
194+
store i32 0, i32* %phi, align 4
195+
%notequal = add i32 %idx, 1
196+
%arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %notequal
197+
store i32 0, i32* %arrayidx13, align 4
198+
br label %for.body
199+
}

0 commit comments

Comments
 (0)