[llvm] [BasicAA] Make use of nusw+nuw -> nneg implication (PR #102141)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 6 06:40:34 PDT 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/102141
If the GEP is both nuw and inbounds/nusw, the offset is non-negative. Pass this information to CastedValue and make use of it when determining the value range.
Proof for nusw+nuw->nneg: https://alive2.llvm.org/ce/z/a_CKAw
Proof for the test case: https://alive2.llvm.org/ce/z/yJ3ymP
>From f1c0df19a37c7a67be0cf6eae78c688aee496b49 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 6 Aug 2024 15:36:00 +0200
Subject: [PATCH] [BasicAA] Make use of nusw+nuw -> nneg implication
If the GEP is both nuw and inbounds/nusw, the offset is
non-negative. Pass this information to CastedValue and make use
of it when determining the value range.
Proof for nusw+nuw->nneg: https://alive2.llvm.org/ce/z/a_CKAw
Proof for the test case: https://alive2.llvm.org/ce/z/yJ3ymP
---
llvm/lib/Analysis/BasicAliasAnalysis.cpp | 10 ++++++++--
llvm/test/Analysis/BasicAA/nusw_nuw_nonneg.ll | 20 +++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/Analysis/BasicAA/nusw_nuw_nonneg.ll
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 33131d80b35fa..7bfb23e14aaa7 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -337,6 +337,10 @@ struct CastedValue {
assert(N.getBitWidth() == V->getType()->getPrimitiveSizeInBits() &&
"Incompatible bit width");
if (TruncBits) N = N.truncate(N.getBitWidth() - TruncBits);
+ if (IsNonNegative && !N.isAllNonNegative())
+ N = N.intersectWith(
+ ConstantRange(APInt::getZero(N.getBitWidth()),
+ APInt::getSignedMinValue(N.getBitWidth())));
if (SExtBits) N = N.signExtend(N.getBitWidth() + SExtBits);
if (ZExtBits) N = N.zeroExtend(N.getBitWidth() + ZExtBits);
return N;
@@ -693,15 +697,17 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
// If the integer type is smaller than the index size, it is implicitly
// sign extended or truncated to index size.
+ bool NUSW = GEPOp->hasNoUnsignedSignedWrap();
+ bool NonNeg = NUSW && GEPOp->hasNoUnsignedWrap();
unsigned Width = Index->getType()->getIntegerBitWidth();
unsigned SExtBits = IndexSize > Width ? IndexSize - Width : 0;
unsigned TruncBits = IndexSize < Width ? Width - IndexSize : 0;
LinearExpression LE = GetLinearExpression(
- CastedValue(Index, 0, SExtBits, TruncBits, false), DL, 0, AC, DT);
+ CastedValue(Index, 0, SExtBits, TruncBits, NonNeg), DL, 0, AC, DT);
// Scale by the type size.
unsigned TypeSize = AllocTypeSize.getFixedValue();
- LE = LE.mul(APInt(IndexSize, TypeSize), GEPOp->hasNoUnsignedSignedWrap());
+ LE = LE.mul(APInt(IndexSize, TypeSize), NUSW);
Decomposed.Offset += LE.Offset.sext(MaxIndexSize);
APInt Scale = LE.Scale.sext(MaxIndexSize);
diff --git a/llvm/test/Analysis/BasicAA/nusw_nuw_nonneg.ll b/llvm/test/Analysis/BasicAA/nusw_nuw_nonneg.ll
new file mode 100644
index 0000000000000..84df62938e2f5
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/nusw_nuw_nonneg.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: test
+; CHECK: NoAlias: i8* %p.minus.2, i8* %p.plus.2
+; CHECK: MayAlias: i8* %p.idx.maybeneg, i8* %p.minus.2
+; CHECK: MayAlias: i8* %p.idx.maybeneg, i8* %p.plus.2
+; CHECK: NoAlias: i8* %p.idx.nneg, i8* %p.minus.2
+; CHECK: MayAlias: i8* %p.idx.nneg, i8* %p.plus.2
+; CHECK: MustAlias: i8* %p.idx.maybeneg, i8* %p.idx.nneg
+define void @test(ptr %p, i64 %idx) {
+ %p.minus.2 = getelementptr i8, ptr %p, i64 -2
+ %p.plus.2 = getelementptr i8, ptr %p, i64 2
+ %p.idx.maybeneg = getelementptr inbounds i8, ptr %p, i64 %idx
+ %p.idx.nneg = getelementptr nuw nusw i8, ptr %p, i64 %idx
+ load i8, ptr %p.minus.2
+ load i8, ptr %p.plus.2
+ load i8, ptr %p.idx.maybeneg
+ load i8, ptr %p.idx.nneg
+ ret void
+}
More information about the llvm-commits
mailing list