Skip to content

Commit 1b7ef6a

Browse files
committed
[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
1 parent a36c2dd commit 1b7ef6a

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,8 +1297,31 @@ AliasResult BasicAAResult::aliasGEP(
12971297
const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
12981298
if (Var.Val.TruncBits == 0 &&
12991299
isKnownNonZero(Var.Val.V, DL, 0, &AC, Var.CxtI, DT)) {
1300-
// If V != 0 then abs(VarIndex) >= abs(Scale).
1301-
MinAbsVarIndex = Var.Scale.abs();
1300+
// If V != 0, then abs(VarIndex) > 0.
1301+
MinAbsVarIndex = APInt(Var.Scale.getBitWidth(), 1);
1302+
1303+
// Check if abs(V*Scale) >= abs(Scale) holds in the presence of
1304+
// potentially wrapping math.
1305+
auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
1306+
if (Var.IsNSW)
1307+
return true;
1308+
1309+
int ValOrigBW = Var.Val.V->getType()->getPrimitiveSizeInBits();
1310+
// If Scale is small enough so that abs(V*Scale) >= abs(Scale) holds.
1311+
// The max value of abs(V) is 2^ValOrigBW - 1. Multiplying with a
1312+
// constant smaller than 2^(bitwidth(Val) - ValOrigBW) won't wrap.
1313+
int MaxScaleValueBW = Var.Val.getBitWidth() - ValOrigBW;
1314+
if (MaxScaleValueBW <= 0)
1315+
return false;
1316+
return Var.Scale.ule(
1317+
APInt::getMaxValue(MaxScaleValueBW).zext(Var.Scale.getBitWidth()));
1318+
};
1319+
// Refine MinAbsVarIndex, if abs(Scale*V) >= abs(Scale) holds in the
1320+
// presence of potentially wrapping math.
1321+
if (MultiplyByScaleNoWrap(Var)) {
1322+
// If V != 0 then abs(VarIndex) >= abs(Scale).
1323+
MinAbsVarIndex = Var.Scale.abs();
1324+
}
13021325
}
13031326
} else if (DecompGEP1.VarIndices.size() == 2) {
13041327
// VarIndex = Scale*V0 + (-Scale)*V1.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,9 @@ define void @may_overflow_mul_scale_neg([200 x [ 6 x i8]]* %ptr, i64 %idx.1,i64
323323
; If %v == 10581764700698480926, %idx == 917, so %gep.917 and %gep.idx may alias.
324324
define i8 @mul_may_overflow_var_nonzero_minabsvarindex_one_index([2000 x i8]* %arr, i8 %x, i64 %v) {
325325
; CHECK-LABEL: Function: mul_may_overflow_var_nonzero_minabsvarindex_one_index: 4 pointers, 0 call sites
326-
; CHECK-NEXT: NoAlias: [2000 x i8]* %arr, i8* %gep.idx
326+
; CHECK-NEXT: MayAlias: [2000 x i8]* %arr, i8* %gep.idx
327327
; CHECK-NEXT: PartialAlias (off 917): [2000 x i8]* %arr, i8* %gep.917
328-
; CHECK-NEXT: NoAlias: i8* %gep.917, i8* %gep.idx
328+
; CHECK-NEXT: MayAlias: i8* %gep.917, i8* %gep.idx
329329
; CHECK-NEXT: MustAlias: [2000 x i8]* %arr, i8* %gep.0
330330
; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.idx
331331
; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.917

0 commit comments

Comments
 (0)