Skip to content

Commit fff622f

Browse files
authored
[BasicAA] Account for wrapping when using abs(Scale*V0 + (-Scale)*V1) >= abs(Scale) (#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
1 parent 7e71466 commit fff622f

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,23 @@ AliasResult BasicAAResult::aliasGEP(
13011301
if (Range1.intersectWith(Range2).isEmptySet())
13021302
return AliasResult::NoAlias;
13031303

1304+
// Check if abs(V*Scale) >= abs(Scale) holds in the presence of
1305+
// potentially wrapping math.
1306+
auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
1307+
if (Var.IsNSW)
1308+
return true;
1309+
1310+
int ValOrigBW = Var.Val.V->getType()->getPrimitiveSizeInBits();
1311+
// If Scale is small enough so that abs(V*Scale) >= abs(Scale) holds.
1312+
// The max value of abs(V) is 2^ValOrigBW - 1. Multiplying with a
1313+
// constant smaller than 2^(bitwidth(Val) - ValOrigBW) won't wrap.
1314+
int MaxScaleValueBW = Var.Val.getBitWidth() - ValOrigBW;
1315+
if (MaxScaleValueBW <= 0)
1316+
return false;
1317+
return Var.Scale.ule(
1318+
APInt::getMaxValue(MaxScaleValueBW).zext(Var.Scale.getBitWidth()));
1319+
};
1320+
13041321
// Try to determine the range of values for VarIndex such that
13051322
// VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex.
13061323
std::optional<APInt> MinAbsVarIndex;
@@ -1309,22 +1326,6 @@ AliasResult BasicAAResult::aliasGEP(
13091326
const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
13101327
if (Var.Val.TruncBits == 0 &&
13111328
isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
1312-
// Check if abs(V*Scale) >= abs(Scale) holds in the presence of
1313-
// potentially wrapping math.
1314-
auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
1315-
if (Var.IsNSW)
1316-
return true;
1317-
1318-
int ValOrigBW = Var.Val.V->getType()->getPrimitiveSizeInBits();
1319-
// If Scale is small enough so that abs(V*Scale) >= abs(Scale) holds.
1320-
// The max value of abs(V) is 2^ValOrigBW - 1. Multiplying with a
1321-
// constant smaller than 2^(bitwidth(Val) - ValOrigBW) won't wrap.
1322-
int MaxScaleValueBW = Var.Val.getBitWidth() - ValOrigBW;
1323-
if (MaxScaleValueBW <= 0)
1324-
return false;
1325-
return Var.Scale.ule(
1326-
APInt::getMaxValue(MaxScaleValueBW).zext(Var.Scale.getBitWidth()));
1327-
};
13281329
// Refine MinAbsVarIndex, if abs(Scale*V) >= abs(Scale) holds in the
13291330
// presence of potentially wrapping math.
13301331
if (MultiplyByScaleNoWrap(Var)) {
@@ -1341,6 +1342,7 @@ AliasResult BasicAAResult::aliasGEP(
13411342
const VariableGEPIndex &Var1 = DecompGEP1.VarIndices[1];
13421343
if (Var0.hasNegatedScaleOf(Var1) && Var0.Val.TruncBits == 0 &&
13431344
Var0.Val.hasSameCastsAs(Var1.Val) && !AAQI.MayBeCrossIteration &&
1345+
MultiplyByScaleNoWrap(Var0) && MultiplyByScaleNoWrap(Var1) &&
13441346
isKnownNonEqual(Var0.Val.V, Var1.Val.V,
13451347
SimplifyQuery(DL, DT, &AC, /*CxtI=*/Var0.CxtI
13461348
? Var0.CxtI

llvm/test/Analysis/BasicAA/gep-modulo.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,17 @@ entry:
393393
}
394394

395395
declare void @llvm.assume(i1)
396+
397+
define i64 @mul_may_overflow_var_nonzero_minabsvarindex_two_index(i64 %arg, ptr %arg1) {
398+
; CHECK-LABEL: Function: mul_may_overflow_var_nonzero_minabsvarindex_two_index
399+
; CHECK-LABEL: MayAlias: i64* %getelementptr, i64* %getelementptr2
400+
bb:
401+
%xor = xor i64 %arg, -9223372036854775808
402+
%getelementptr = getelementptr i64, ptr %arg1, i64 %xor
403+
%load = load i64, ptr %getelementptr, align 8
404+
%getelementptr2 = getelementptr i64, ptr %arg1, i64 %arg
405+
store i64 1, ptr %getelementptr2, align 8
406+
%load3 = load i64, ptr %getelementptr, align 8
407+
%mul = mul i64 %load, %load3
408+
ret i64 %mul
409+
}

0 commit comments

Comments
 (0)