[llvm] [BasicAA] Account for wrapping when using abs(Scale*V0 + (-Scale)*V1) >= abs(Scale) (PR #137755)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 28 22:16:36 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Craig Topper (topperc)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/137755.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/BasicAliasAnalysis.cpp (+19-17)
- (modified) llvm/test/Analysis/BasicAA/gep-modulo.ll (+14)
``````````diff
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index cbec13c7808be..03977551afadd 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)) {
@@ -1345,7 +1346,8 @@ AliasResult BasicAAResult::aliasGEP(
SimplifyQuery(DL, DT, &AC, /*CxtI=*/Var0.CxtI
? Var0.CxtI
: Var1.CxtI)))
- MinAbsVarIndex = Var0.Scale.abs();
+ if (MultiplyByScaleNoWrap(Var0) && MultiplyByScaleNoWrap(Var1))
+ MinAbsVarIndex = Var0.Scale.abs();
}
if (MinAbsVarIndex) {
diff --git a/llvm/test/Analysis/BasicAA/gep-modulo.ll b/llvm/test/Analysis/BasicAA/gep-modulo.ll
index 159aaf94039d3..9ca69b2d7bbdd 100644
--- a/llvm/test/Analysis/BasicAA/gep-modulo.ll
+++ b/llvm/test/Analysis/BasicAA/gep-modulo.ll
@@ -393,3 +393,17 @@ entry:
}
declare void @llvm.assume(i1)
+
+define i64 @mul_may_overflow_var_nonzero_minabsvarindex_two_index(i64 %arg, ptr %arg1) {
+; CHECK-LABEL: Function: mul_may_overflow_var_nonzero_minabsvarindex_two_index
+; CHECK-LABEL: MayAlias: i64* %getelementptr, i64* %getelementptr2
+bb:
+ %xor = xor i64 %arg, -9223372036854775808
+ %getelementptr = getelementptr i64, ptr %arg1, i64 %xor
+ %load = load i64, ptr %getelementptr, align 8
+ %getelementptr2 = getelementptr i64, ptr %arg1, i64 %arg
+ store i64 1, ptr %getelementptr2, align 8
+ %load3 = load i64, ptr %getelementptr, align 8
+ %mul = mul i64 %load, %load3
+ ret i64 %mul
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/137755
More information about the llvm-commits
mailing list