Skip to content

Commit 81ce23d

Browse files
committed
Swap order of GEPs to simplify things
1 parent 452c8de commit 81ce23d

File tree

3 files changed

+25
-51
lines changed

3 files changed

+25
-51
lines changed

llvm/include/llvm/Analysis/BasicAliasAnalysis.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ class BasicAAResult : public AAResultBase {
122122
bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2,
123123
const AAQueryInfo &AAQI);
124124

125-
void subtractDecomposedGEPs(DecomposedGEP &DestGEP, DecomposedGEP &SrcGEP,
125+
void subtractDecomposedGEPs(DecomposedGEP &DestGEP,
126+
const DecomposedGEP &SrcGEP,
126127
const AAQueryInfo &AAQI);
127128

128129
AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size,

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,6 @@ struct VariableGEPIndex {
530530
return Scale == Other.Scale;
531531
}
532532

533-
bool isSubtracted() const { return IsNegated || Scale.isNegative(); }
534-
535533
void dump() const {
536534
print(dbgs());
537535
dbgs() << "\n";
@@ -1113,6 +1111,13 @@ AliasResult BasicAAResult::aliasGEP(
11131111
if (DecompGEP1.Base == GEP1 && DecompGEP2.Base == V2)
11141112
return AliasResult::MayAlias;
11151113

1114+
// Swap GEP1 and GEP2 if GEP2 has more variable indices.
1115+
if (DecompGEP1.VarIndices.size() < DecompGEP2.VarIndices.size()) {
1116+
std::swap(DecompGEP1, DecompGEP2);
1117+
std::swap(V1Size, V2Size);
1118+
std::swap(UnderlyingV1, UnderlyingV2);
1119+
}
1120+
11161121
// Subtract the GEP2 pointer from the GEP1 pointer to find out their
11171122
// symbolic difference.
11181123
subtractDecomposedGEPs(DecompGEP1, DecompGEP2, AAQI);
@@ -1121,20 +1126,18 @@ AliasResult BasicAAResult::aliasGEP(
11211126
// for the two to alias, then we can assume noalias.
11221127
// TODO: Remove !isScalable() once BasicAA fully support scalable location
11231128
// size
1124-
if (DecompGEP1.NWFlags->isInBounds() && DecompGEP1.VarIndices.empty() &&
1125-
V2Size.hasValue() && !V2Size.isScalable() &&
1126-
DecompGEP1.Offset.sge(V2Size.getValue()) &&
1129+
if (DecompGEP1.NWFlags && DecompGEP1.NWFlags->isInBounds() &&
1130+
DecompGEP1.VarIndices.empty() && V2Size.hasValue() &&
1131+
!V2Size.isScalable() && DecompGEP1.Offset.sge(V2Size.getValue()) &&
11271132
isBaseOfObject(DecompGEP2.Base))
11281133
return AliasResult::NoAlias;
11291134

1130-
if (isa<GEPOperator>(V2)) {
1131-
// Symmetric case to above.
1132-
if (DecompGEP2.NWFlags->isInBounds() && DecompGEP1.VarIndices.empty() &&
1133-
V1Size.hasValue() && !V1Size.isScalable() &&
1134-
DecompGEP1.Offset.sle(-V1Size.getValue()) &&
1135-
isBaseOfObject(DecompGEP1.Base))
1136-
return AliasResult::NoAlias;
1137-
}
1135+
// Symmetric case to above.
1136+
if (DecompGEP2.NWFlags && DecompGEP2.NWFlags->isInBounds() &&
1137+
DecompGEP1.VarIndices.empty() && V1Size.hasValue() &&
1138+
!V1Size.isScalable() && DecompGEP1.Offset.sle(-V1Size.getValue()) &&
1139+
isBaseOfObject(DecompGEP1.Base))
1140+
return AliasResult::NoAlias;
11381141

11391142
// For GEPs with identical offsets, we can preserve the size and AAInfo
11401143
// when performing the alias check on the underlying objects.
@@ -1250,20 +1253,9 @@ AliasResult BasicAAResult::aliasGEP(
12501253
// |-->VLeftSize | |-------> VRightSize
12511254
// LHS RHS
12521255
if (!DecompGEP1.VarIndices.empty() &&
1253-
llvm::all_of(DecompGEP1.VarIndices, [&](const VariableGEPIndex &V) {
1254-
return V.isSubtracted() == DecompGEP1.VarIndices.front().isSubtracted();
1255-
})) {
1256-
const APInt &Off = DecompGEP1.Offset;
1257-
bool Swapped = Off.isNegative();
1258-
LocationSize VLeftSize = Swapped ? V1Size : V2Size;
1259-
const DecomposedGEP &DecompRight = Swapped ? DecompGEP2 : DecompGEP1;
1260-
1261-
bool IndicesAdded = DecompGEP1.VarIndices.front().isSubtracted() == Swapped;
1262-
if (IndicesAdded && DecompRight.NWFlags->hasNoUnsignedWrap())
1263-
if (VLeftSize.hasValue() && !VLeftSize.isScalable() &&
1264-
Off.abs().uge(VLeftSize.getValue()))
1265-
return AliasResult::NoAlias;
1266-
}
1256+
DecompGEP1.NWFlags->hasNoUnsignedWrap() && V2Size.hasValue() &&
1257+
!V2Size.isScalable() && DecompGEP1.Offset.sge(V2Size.getValue()))
1258+
return AliasResult::NoAlias;
12671259

12681260
// Bail on analysing scalable LocationSize
12691261
if (V1Size.isScalable() || V2Size.isScalable())
@@ -1867,14 +1859,12 @@ bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
18671859

18681860
/// Computes the symbolic difference between two de-composed GEPs.
18691861
void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
1870-
DecomposedGEP &SrcGEP,
1862+
const DecomposedGEP &SrcGEP,
18711863
const AAQueryInfo &AAQI) {
18721864
// Drop nuw flag from GEP if subtraction of constant offsets overflows in an
18731865
// unsigned sense.
18741866
if (DestGEP.Offset.ult(SrcGEP.Offset))
18751867
DestGEP.NWFlags = DestGEP.NWFlags->withoutNoUnsignedWrap();
1876-
else if (SrcGEP.Offset.ult(DestGEP.Offset) && SrcGEP.NWFlags)
1877-
SrcGEP.NWFlags = SrcGEP.NWFlags->withoutNoUnsignedWrap();
18781868

18791869
DestGEP.Offset -= SrcGEP.Offset;
18801870
for (const VariableGEPIndex &Src : SrcGEP.VarIndices) {
@@ -1902,8 +1892,6 @@ void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
19021892
// unsigned sense.
19031893
if (Dest.Scale.ult(Src.Scale))
19041894
DestGEP.NWFlags = DestGEP.NWFlags->withoutNoUnsignedWrap();
1905-
else if (SrcGEP.NWFlags)
1906-
SrcGEP.NWFlags = SrcGEP.NWFlags->withoutNoUnsignedWrap();
19071895

19081896
Dest.Scale -= Src.Scale;
19091897
Dest.IsNSW = false;
@@ -1919,6 +1907,9 @@ void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
19191907
VariableGEPIndex Entry = {Src.Val, Src.Scale, Src.CxtI, Src.IsNSW,
19201908
/* IsNegated */ true};
19211909
DestGEP.VarIndices.push_back(Entry);
1910+
1911+
// Drop nuw flag when we have unconsumed variable indices from SrcGEP.
1912+
DestGEP.NWFlags = DestGEP.NWFlags->withoutNoUnsignedWrap();
19221913
}
19231914
}
19241915
}

llvm/test/Analysis/BasicAA/gep-nuw-alias.ll

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -158,24 +158,6 @@ define void @constant_offset_overflow(ptr %p, i64 %i) {
158158
ret void
159159
}
160160

161-
; CHECK-LABEL: constant_offset_overflow_rev_order
162-
;
163-
; Same as above test, just verifying correct behaviour when GEPs encountered
164-
; in the reverse order;
165-
;
166-
; CHECK-DAG: MayAlias: i32* %a, i32* %b
167-
168-
define void @constant_offset_overflow_rev_order(ptr %p, i64 %i) {
169-
%a = getelementptr i8, ptr %p, i64 -8
170-
%add = getelementptr nuw i8, ptr %p, i64 4
171-
%b = getelementptr nuw i8, ptr %add, i64 %i
172-
173-
load i32, ptr %b
174-
load i32, ptr %a
175-
176-
ret void
177-
}
178-
179161
; CHECK-LABEL: equal_var_idx_noalias
180162
;
181163
; If GEPs have equal variable indices, we can prove NoAlias when the Scale of

0 commit comments

Comments
 (0)