[llvm] 0d20ebf - [BasicAA] Use ranges for more than one index

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 25 06:31:00 PDT 2021


Author: Nikita Popov
Date: 2021-10-25T15:30:50+02:00
New Revision: 0d20ebf6862f77ce0913187c05c02ba5df175f29

URL: https://github.com/llvm/llvm-project/commit/0d20ebf6862f77ce0913187c05c02ba5df175f29
DIFF: https://github.com/llvm/llvm-project/commit/0d20ebf6862f77ce0913187c05c02ba5df175f29.diff

LOG: [BasicAA] Use ranges for more than one index

D109746 made BasicAA use range information to determine the
minimum/maximum GEP offset. However, it was limited to the case of
a single variable index. This patch extends support to multiple
indices by adding all the ranges together.

Differential Revision: https://reviews.llvm.org/D112378

Added: 
    

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/test/Analysis/BasicAA/range.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 25b6d9bc73847..f0e5d65f961d1 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1252,6 +1252,7 @@ AliasResult BasicAAResult::aliasGEP(
     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 @@ AliasResult BasicAAResult::aliasGEP(
         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 @@ AliasResult BasicAAResult::aliasGEP(
         (-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<APInt> MinAbsVarIndex;
-      Optional<ConstantRange> VarIndexRange;
       if (DecompGEP1.VarIndices.size() == 1) {
         // VarIndex = Scale*V.
         const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
@@ -1321,11 +1339,6 @@ AliasResult BasicAAResult::aliasGEP(
           // 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 @@ AliasResult BasicAAResult::aliasGEP(
             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
index d1847d618e948..78e6add0f50fa 100644
--- a/llvm/test/Analysis/BasicAA/range.ll
+++ b/llvm/test/Analysis/BasicAA/range.ll
@@ -185,8 +185,7 @@ define void @zeroext_index([256 x i32]* %s, i8* %q) {
 ; 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


        


More information about the llvm-commits mailing list