diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1252,6 +1252,7 @@ APInt GCD; bool AllNonNegative = DecompGEP1.Offset.isNonNegative(); bool AllNonPositive = DecompGEP1.Offset.isNonPositive(); + ConstantRange Range = ConstantRange(DecompGEP1.Offset); for (unsigned i = 0, e = DecompGEP1.VarIndices.size(); i != e; ++i) { const VariableGEPIndex &Index = DecompGEP1.VarIndices[i]; const APInt &Scale = Index.Scale; @@ -1275,6 +1276,14 @@ AllNonPositive &= (SignKnownZero && Scale.isNonPositive()) || (SignKnownOne && Scale.isNonNegative()); } + + assert(Range.getBitWidth() == Scale.getBitWidth() && + "Bit widths are normalized to MaxPointerSize"); + Range = Range.add(Index.Val + .evaluateWith(computeConstantRange( + Index.Val.V, true, &AC, Index.CxtI)) + .sextOrTrunc(Range.getBitWidth()) + .smul_fast(ConstantRange(Scale))); } // We now have accesses at two offsets from the same base: @@ -1306,13 +1315,22 @@ (-DecompGEP1.Offset).uge(V1Size.getValue())) return AliasResult::NoAlias; + if (!Range.isEmptySet()) { + // We know that Offset >= MinOffset. + // (MinOffset >= V2Size) => (Offset >= V2Size) => NoAlias. + if (V2Size.hasValue() && Range.getSignedMin().sge(V2Size.getValue())) + return AliasResult::NoAlias; + + // We know that Offset <= MaxOffset. + // (MaxOffset <= -V1Size) => (Offset <= -V1Size) => NoAlias. + if (V1Size.hasValue() && Range.getSignedMax().sle(-V1Size.getValue())) + return AliasResult::NoAlias; + } + if (V1Size.hasValue() && V2Size.hasValue()) { - // Try to determine the range of values for VarIndex. - // VarIndexRange is such that: - // (VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex) && - // VarIndexRange.contains(VarIndex) + // Try to determine the range of values for VarIndex such that + // VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex. Optional MinAbsVarIndex; - Optional VarIndexRange; if (DecompGEP1.VarIndices.size() == 1) { // VarIndex = Scale*V. const VariableGEPIndex &Var = DecompGEP1.VarIndices[0]; @@ -1321,11 +1339,6 @@ // If V != 0 then abs(VarIndex) >= abs(Scale). MinAbsVarIndex = Var.Scale.abs(); } - ConstantRange R = Var.Val.evaluateWith( - computeConstantRange(Var.Val.V, true, &AC, Var.CxtI)); - if (!R.isFullSet() && !R.isEmptySet()) - VarIndexRange = R.sextOrTrunc(Var.Scale.getBitWidth()) - .smul_fast(ConstantRange(Var.Scale)); } else if (DecompGEP1.VarIndices.size() == 2) { // VarIndex = Scale*V0 + (-Scale)*V1. // If V0 != V1 then abs(VarIndex) >= abs(Scale). @@ -1349,21 +1362,6 @@ OffsetHi.isNonNegative() && OffsetHi.uge(V2Size.getValue())) return AliasResult::NoAlias; } - - if (VarIndexRange) { - ConstantRange OffsetRange = - VarIndexRange->add(ConstantRange(DecompGEP1.Offset)); - - // We know that Offset >= MinOffset. - // (MinOffset >= V2Size) => (Offset >= V2Size) => NoAlias. - if (OffsetRange.getSignedMin().sge(V2Size.getValue())) - return AliasResult::NoAlias; - - // We know that Offset <= MaxOffset. - // (MaxOffset <= -V1Size) => (Offset <= -V1Size) => NoAlias. - if (OffsetRange.getSignedMax().sle(-V1Size.getValue())) - return AliasResult::NoAlias; - } } if (constantOffsetHeuristic(DecompGEP1, V1Size, V2Size, &AC, DT)) diff --git a/llvm/test/Analysis/BasicAA/range.ll b/llvm/test/Analysis/BasicAA/range.ll --- a/llvm/test/Analysis/BasicAA/range.ll +++ b/llvm/test/Analysis/BasicAA/range.ll @@ -185,8 +185,7 @@ ; CHECK: NoAlias: i32* %p.01, i32* %p.2 ; CHECK: MayAlias: i32* %p.02, i32* %p.2 ; CHECK: NoAlias: i32* %p.01, i32* %p.3 -; TODO: This can be NoAlias. -; CHECK: MayAlias: i32* %p.02, i32* %p.3 +; CHECK: NoAlias: i32* %p.02, i32* %p.3 define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) { %o1 = load i32, i32* %o1_ptr, !range !0 %o2 = load i32, i32* %o2_ptr, !range !0