[llvm] 1b7ef6a - [BasicAA] Account for wrapping when using abs(VarIndex) >= abs(Scale).

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 18 07:41:22 PDT 2022


Author: Florian Hahn
Date: 2022-03-18T14:41:15Z
New Revision: 1b7ef6aac8a3cad245c0ed14fe21725e31261f73

URL: https://github.com/llvm/llvm-project/commit/1b7ef6aac8a3cad245c0ed14fe21725e31261f73
DIFF: https://github.com/llvm/llvm-project/commit/1b7ef6aac8a3cad245c0ed14fe21725e31261f73.diff

LOG: [BasicAA] Account for wrapping when using abs(VarIndex) >= abs(Scale).

The patch adds an extra check to only set MinAbsVarIndex if
abs(V * Scale) won't wrap. In the absence of IsNSW, try to use the
bitwidths of the original V and Scale to rule out wrapping.

Attempt to model https://alive2.llvm.org/ce/z/HE8ZKj

The code in the else if below probably needs the same treatment, but I
need to come up with a test first.

Reviewed By: asbirlea

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

Added: 
    

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/test/Analysis/BasicAA/gep-modulo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 8c11cdf4834d6..e8d0c76730c95 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1297,8 +1297,31 @@ AliasResult BasicAAResult::aliasGEP(
     const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
     if (Var.Val.TruncBits == 0 &&
         isKnownNonZero(Var.Val.V, DL, 0, &AC, Var.CxtI, DT)) {
-      // If V != 0 then abs(VarIndex) >= abs(Scale).
-      MinAbsVarIndex = Var.Scale.abs();
+      // If V != 0, then abs(VarIndex) > 0.
+      MinAbsVarIndex = APInt(Var.Scale.getBitWidth(), 1);
+
+      // Check if abs(V*Scale) >= abs(Scale) holds in the presence of
+      // potentially wrapping math.
+      auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
+        if (Var.IsNSW)
+          return true;
+
+        int ValOrigBW = Var.Val.V->getType()->getPrimitiveSizeInBits();
+        // If Scale is small enough so that abs(V*Scale) >= abs(Scale) holds.
+        // The max value of abs(V) is 2^ValOrigBW - 1. Multiplying with a
+        // constant smaller than 2^(bitwidth(Val) - ValOrigBW) won't wrap.
+        int MaxScaleValueBW = Var.Val.getBitWidth() - ValOrigBW;
+        if (MaxScaleValueBW <= 0)
+          return false;
+        return Var.Scale.ule(
+            APInt::getMaxValue(MaxScaleValueBW).zext(Var.Scale.getBitWidth()));
+      };
+      // Refine MinAbsVarIndex, if abs(Scale*V) >= abs(Scale) holds in the
+      // presence of potentially wrapping math.
+      if (MultiplyByScaleNoWrap(Var)) {
+        // If V != 0 then abs(VarIndex) >= abs(Scale).
+        MinAbsVarIndex = Var.Scale.abs();
+      }
     }
   } else if (DecompGEP1.VarIndices.size() == 2) {
     // VarIndex = Scale*V0 + (-Scale)*V1.

diff  --git a/llvm/test/Analysis/BasicAA/gep-modulo.ll b/llvm/test/Analysis/BasicAA/gep-modulo.ll
index 6e1779679d686..7e62a15aac47d 100644
--- a/llvm/test/Analysis/BasicAA/gep-modulo.ll
+++ b/llvm/test/Analysis/BasicAA/gep-modulo.ll
@@ -323,9 +323,9 @@ define void @may_overflow_mul_scale_neg([200 x [ 6 x i8]]* %ptr, i64 %idx.1,i64
 ; If %v == 10581764700698480926, %idx == 917, so %gep.917 and %gep.idx may alias.
 define i8 @mul_may_overflow_var_nonzero_minabsvarindex_one_index([2000 x i8]* %arr, i8 %x, i64 %v) {
 ; CHECK-LABEL: Function: mul_may_overflow_var_nonzero_minabsvarindex_one_index: 4 pointers, 0 call sites
-; CHECK-NEXT:  NoAlias: [2000 x i8]* %arr, i8* %gep.idx
+; CHECK-NEXT:  MayAlias: [2000 x i8]* %arr, i8* %gep.idx
 ; CHECK-NEXT:  PartialAlias (off 917): [2000 x i8]* %arr, i8* %gep.917
-; CHECK-NEXT:  NoAlias: i8* %gep.917, i8* %gep.idx
+; CHECK-NEXT:  MayAlias: i8* %gep.917, i8* %gep.idx
 ; CHECK-NEXT:  MustAlias: [2000 x i8]* %arr, i8* %gep.0
 ; CHECK-NEXT:  NoAlias: i8* %gep.0, i8* %gep.idx
 ; CHECK-NEXT:  NoAlias: i8* %gep.0, i8* %gep.917


        


More information about the llvm-commits mailing list