llvm.org GIT mirror llvm / b80d8da
[BasicAA] Extend inbound GEP negative offset logic to GlobalVariables r270777 improved the precision of alloca vs. inbounbds GEP alias queries: if we have (a) an inbounds GEP and (b) a pointer based on an alloca, and the beginning of the object the GEP points to would have a negative offset with respect to the alloca, then the GEP can not alias pointer (b). This makes the same logic fire when (b) is based on a GlobalVariable instead of an alloca. Differential Revision: http://reviews.llvm.org/D20652 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270893 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Kuperstein 3 years ago
3 changed file(s) with 31 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
156156 const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT);
157157
158158 static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
159 const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompAlloca,
160 uint64_t AllocaAccessSize);
159 const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
160 uint64_t ObjectAccessSize);
161161
162162 /// \brief A Heuristic for aliasGEP that searches for a constant offset
163163 /// between the variables.
954954 // repsect to the alloca, that means the GEP can not alias pointer (b).
955955 // Note that the pointer based on the alloca may not be a GEP. For
956956 // example, it may be the alloca itself.
957 // The same applies if (b) is based on a GlobalVariable. Note that just being
958 // based on isIdentifiedObject() is not enough - we need an identified object
959 // that does not permit access to negative offsets. For example, a negative
960 // offset from a noalias argument or call can be inbounds w.r.t the actual
961 // underlying object.
957962 //
958963 // For example, consider:
959964 //
976981 // the highest %f1 can be is (%alloca + 3). This means %random can not be higher
977982 // than (%alloca - 1), and so is not inbounds, a contradiction.
978983 bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
979 const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompAlloca,
980 uint64_t AllocaAccessSize) {
981 // If the alloca access size is unknown, or the GEP isn't inbounds, bail.
982 if (AllocaAccessSize == MemoryLocation::UnknownSize || !GEPOp->isInBounds())
984 const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
985 uint64_t ObjectAccessSize) {
986 // If the object access size is unknown, or the GEP isn't inbounds, bail.
987 if (ObjectAccessSize == MemoryLocation::UnknownSize || !GEPOp->isInBounds())
983988 return false;
984989
985 // We need an alloca, and want to know the offset of the pointer
986 // from the alloca precisely, so no variable indices are allowed.
987 if (!isa(DecompAlloca.Base) || !DecompAlloca.VarIndices.empty())
990 // We need the object to be an alloca or a globalvariable, and want to know
991 // the offset of the pointer from the object precisely, so no variable
992 // indices are allowed.
993 if (!(isa(DecompObject.Base) ||
994 isa(DecompObject.Base)) ||
995 !DecompObject.VarIndices.empty())
988996 return false;
989997
990 int64_t AllocaBaseOffset = DecompAlloca.StructOffset +
991 DecompAlloca.OtherOffset;
998 int64_t ObjectBaseOffset = DecompObject.StructOffset +
999 DecompObject.OtherOffset;
9921000
9931001 // If the GEP has no variable indices, we know the precise offset
9941002 // from the base, then use it. If the GEP has variable indices, we're in
9991007 if (DecompGEP.VarIndices.empty())
10001008 GEPBaseOffset += DecompGEP.OtherOffset;
10011009
1002 return (GEPBaseOffset >= AllocaBaseOffset + (int64_t)AllocaAccessSize);
1010 return (GEPBaseOffset >= ObjectBaseOffset + (int64_t)ObjectAccessSize);
10031011 }
10041012
10051013 /// Provides a bunch of ad-hoc rules to disambiguate a GEP instruction against
2020 ; CHECK-DAG: MayAlias: i32* %arg, i32* %p1
2121 define void @arg(i32* %arg) {
2222 %random = call i32* @random.i32(i32* %arg)
23 %p0 = getelementptr inbounds i32, i32* %random, i32 0
24 %p1 = getelementptr inbounds i32, i32* %random, i32 1
25 ret void
26 }
27
28 @gv = global i32 1
29 ; CHECK-LABEL: Function: global:
30 ; CHECK-DAG: MayAlias: i32* %p0, i32* @gv
31 ; CHECK-DAG: NoAlias: i32* %p1, i32* @gv
32 define void @global() {
33 %random = call i32* @random.i32(i32* @gv)
2334 %p0 = getelementptr inbounds i32, i32* %random, i32 0
2435 %p1 = getelementptr inbounds i32, i32* %random, i32 1
2536 ret void