Skip to content

Commit 311fafd

Browse files
committed
[BasicAA] Fix -basicaa-recphi for geps with negative offsets
As shown in D82998, the basic-aa-recphi option can cause miscompiles for gep's with negative constants. The option checks for recursive phi, that recurse through a contant gep. If it finds one, it performs aliasing calculations using the other phi operands with an unknown size, to specify that an unknown number of elements after the initial value are potentially accessed. This works fine expect where the constant is negative, as the size is still considered to be positive. So this patch expands the check to make sure that the constant is also positive. Differential Revision: https://reviews.llvm.org/D83576
1 parent c74cfd4 commit 311fafd

File tree

2 files changed

+34
-31
lines changed

2 files changed

+34
-31
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,8 +1648,32 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
16481648
}
16491649

16501650
SmallVector<Value *, 4> V1Srcs;
1651+
// For a recursive phi, that recurses through a contant gep, we can perform
1652+
// aliasing calculations using the other phi operands with an unknown size to
1653+
// specify that an unknown number of elements after the initial value are
1654+
// potentially accessed.
16511655
bool isRecursive = false;
1652-
if (PV) {
1656+
auto CheckForRecPhi = [&](Value *PV) {
1657+
if (!EnableRecPhiAnalysis)
1658+
return false;
1659+
if (GEPOperator *PVGEP = dyn_cast<GEPOperator>(PV)) {
1660+
// Check whether the incoming value is a GEP that advances the pointer
1661+
// result of this PHI node (e.g. in a loop). If this is the case, we
1662+
// would recurse and always get a MayAlias. Handle this case specially
1663+
// below. We need to ensure that the phi is inbounds and has a constant
1664+
// positive operand so that we can check for alias with the initial value
1665+
// and an unknown but positive size.
1666+
if (PVGEP->getPointerOperand() == PN && PVGEP->isInBounds() &&
1667+
PVGEP->getNumIndices() == 1 && isa<ConstantInt>(PVGEP->idx_begin()) &&
1668+
!cast<ConstantInt>(PVGEP->idx_begin())->isNegative()) {
1669+
isRecursive = true;
1670+
return true;
1671+
}
1672+
}
1673+
return false;
1674+
};
1675+
1676+
if (PV) {
16531677
// If we have PhiValues then use it to get the underlying phi values.
16541678
const PhiValues::ValueSet &PhiValueSet = PV->getValuesForPhi(PN);
16551679
// If we have more phi values than the search depth then return MayAlias
@@ -1660,19 +1684,8 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
16601684
return MayAlias;
16611685
// Add the values to V1Srcs
16621686
for (Value *PV1 : PhiValueSet) {
1663-
if (EnableRecPhiAnalysis) {
1664-
if (GEPOperator *PV1GEP = dyn_cast<GEPOperator>(PV1)) {
1665-
// Check whether the incoming value is a GEP that advances the pointer
1666-
// result of this PHI node (e.g. in a loop). If this is the case, we
1667-
// would recurse and always get a MayAlias. Handle this case specially
1668-
// below.
1669-
if (PV1GEP->getPointerOperand() == PN && PV1GEP->getNumIndices() == 1 &&
1670-
isa<ConstantInt>(PV1GEP->idx_begin())) {
1671-
isRecursive = true;
1672-
continue;
1673-
}
1674-
}
1675-
}
1687+
if (CheckForRecPhi(PV1))
1688+
continue;
16761689
V1Srcs.push_back(PV1);
16771690
}
16781691
} else {
@@ -1687,18 +1700,8 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
16871700
// and 'n' are the number of PHI sources.
16881701
return MayAlias;
16891702

1690-
if (EnableRecPhiAnalysis)
1691-
if (GEPOperator *PV1GEP = dyn_cast<GEPOperator>(PV1)) {
1692-
// Check whether the incoming value is a GEP that advances the pointer
1693-
// result of this PHI node (e.g. in a loop). If this is the case, we
1694-
// would recurse and always get a MayAlias. Handle this case specially
1695-
// below.
1696-
if (PV1GEP->getPointerOperand() == PN && PV1GEP->getNumIndices() == 1 &&
1697-
isa<ConstantInt>(PV1GEP->idx_begin())) {
1698-
isRecursive = true;
1699-
continue;
1700-
}
1701-
}
1703+
if (CheckForRecPhi(PV1))
1704+
continue;
17021705

17031706
if (UniqueSrc.insert(PV1).second)
17041707
V1Srcs.push_back(PV1);

llvm/test/Analysis/BasicAA/recphi.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ if.end: ; preds = %f.exit
9292
; CHECK: NoAlias: i32* %arrayidx1, i8* %0
9393
; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1
9494
; CHECK: MayAlias: [10 x i32]* %tab, i32* %p.addr.05.i
95-
; CHECK: NoAlias: i32* %p.addr.05.i, i8* %0
96-
; CHECK: NoAlias: i32* %arrayidx, i32* %p.addr.05.i
95+
; CHECK: MayAlias: i32* %p.addr.05.i, i8* %0
96+
; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i
9797
; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i
9898
; CHECK: MayAlias: [10 x i32]* %tab, i32* %incdec.ptr.i
9999
; CHECK: MayAlias: i32* %incdec.ptr.i, i8* %0
@@ -141,17 +141,17 @@ if.end: ; preds = %f.exit
141141
; CHECK: NoAlias: [3 x i16]* %int_arr.10, i16** %argv.6.par
142142
; CHECK: NoAlias: i16* %_tmp1, i16** %argv.6.par
143143
; CHECK: PartialAlias: [3 x i16]* %int_arr.10, i16* %_tmp1
144-
; CHECK: NoAlias: i16* %ls1.9.0, i16** %argv.6.par
144+
; CHECK: MayAlias: i16* %ls1.9.0, i16** %argv.6.par
145145
; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %ls1.9.0
146146
; CHECK: MayAlias: i16* %_tmp1, i16* %ls1.9.0
147-
; CHECK: NoAlias: i16* %_tmp7, i16** %argv.6.par
147+
; CHECK: MayAlias: i16* %_tmp7, i16** %argv.6.par
148148
; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %_tmp7
149149
; CHECK: MayAlias: i16* %_tmp1, i16* %_tmp7
150150
; CHECK: NoAlias: i16* %_tmp7, i16* %ls1.9.0
151151
; CHECK: NoAlias: i16* %_tmp11, i16** %argv.6.par
152152
; CHECK: PartialAlias: [3 x i16]* %int_arr.10, i16* %_tmp11
153153
; CHECK: NoAlias: i16* %_tmp1, i16* %_tmp11
154-
; CHECK: NoAlias: i16* %_tmp11, i16* %ls1.9.0
154+
; CHECK: MayAlias: i16* %_tmp11, i16* %ls1.9.0
155155
; CHECK: MayAlias: i16* %_tmp11, i16* %_tmp7
156156
; CHECK: Both ModRef: Ptr: i16** %argv.6.par <-> %_tmp16 = call i16 @call(i32 %_tmp13)
157157
; CHECK: NoModRef: Ptr: [3 x i16]* %int_arr.10 <-> %_tmp16 = call i16 @call(i32 %_tmp13)

0 commit comments

Comments
 (0)