diff options
author | Craig Topper <craig.topper@sifive.com> | 2025-04-29 14:10:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-29 14:10:37 -0700 |
commit | fff622fbf760f9ff4e10073ad859c2b663f33af8 (patch) | |
tree | 08d215d157e0287dc6f53221e6e80db375991cef /llvm/lib/Analysis/BasicAliasAnalysis.cpp | |
parent | 7e71466900f84770c08cc53807425a19918a3975 (diff) | |
download | llvm-fff622fbf760f9ff4e10073ad859c2b663f33af8.zip llvm-fff622fbf760f9ff4e10073ad859c2b663f33af8.tar.gz llvm-fff622fbf760f9ff4e10073ad859c2b663f33af8.tar.bz2 |
[BasicAA] Account for wrapping when using abs(Scale*V0 + (-Scale)*V1) >= abs(Scale) (#137755)
Similar to 1b7ef6aac8a3cad245c0ed14fe21725e31261f73, add a check to only
set MinAbsVarIndex if abs(Scale*V0) and abs((-Scale)*V1) won't wrap. In
the absence of IsNSW, try to use the bitwidths of the original V and
Scale to rule out wrapping
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index cbec13c..a46edc0 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1301,6 +1301,23 @@ AliasResult BasicAAResult::aliasGEP( if (Range1.intersectWith(Range2).isEmptySet()) return AliasResult::NoAlias; + // 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())); + }; + // Try to determine the range of values for VarIndex such that // VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex. std::optional<APInt> MinAbsVarIndex; @@ -1309,22 +1326,6 @@ AliasResult BasicAAResult::aliasGEP( const VariableGEPIndex &Var = DecompGEP1.VarIndices[0]; if (Var.Val.TruncBits == 0 && isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CxtI))) { - // 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)) { @@ -1341,6 +1342,7 @@ AliasResult BasicAAResult::aliasGEP( const VariableGEPIndex &Var1 = DecompGEP1.VarIndices[1]; if (Var0.hasNegatedScaleOf(Var1) && Var0.Val.TruncBits == 0 && Var0.Val.hasSameCastsAs(Var1.Val) && !AAQI.MayBeCrossIteration && + MultiplyByScaleNoWrap(Var0) && MultiplyByScaleNoWrap(Var1) && isKnownNonEqual(Var0.Val.V, Var1.Val.V, SimplifyQuery(DL, DT, &AC, /*CxtI=*/Var0.CxtI ? Var0.CxtI |