-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[BasicAA] Account for wrapping when using abs(Scale*V0 + (-Scale)*V1) >= abs(Scale) #137755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… >= abs(Scale) Similar to 1b7ef6a, 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
@llvm/pr-subscribers-llvm-analysis Author: Craig Topper (topperc) ChangesSimilar to 1b7ef6a, add a check to Full diff: https://github.com/llvm/llvm-project/pull/137755.diff 2 Files Affected:
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
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Approximate proof: https://alive2.llvm.org/ce/z/hTla9G This is not quite correct for the non-IsNegated case (src2), but I think we'd only hit that in cases where NSW is dropped earlier already (
llvm-project/llvm/lib/Analysis/BasicAliasAnalysis.cpp
Lines 1872 to 1874 in a9ece2d
Dest.Scale = -Dest.Scale; | |
Dest.IsNegated = false; | |
Dest.IsNSW = false; |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/88/builds/11076 Here is the relevant piece of the build log for the reference
|
… >= abs(Scale) (llvm#137755) Similar to 1b7ef6a, 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
… >= abs(Scale) (llvm#137755) Similar to 1b7ef6a, 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
… >= abs(Scale) (llvm#137755) Similar to 1b7ef6a, 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
… >= abs(Scale) (llvm#137755) Similar to 1b7ef6a, 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
… >= abs(Scale) (llvm#137755) Similar to 1b7ef6a, 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
Similar to 1b7ef6a, 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