[llvm] 3c87f66 - [BasicAA] Make use of nusw+nuw -> nneg implication (#102141)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 7 03:47:24 PDT 2024


Author: Nikita Popov
Date: 2024-08-07T12:47:21+02:00
New Revision: 3c87f66b7e642790cafd877ff6b1fcb8a712c66a

URL: https://github.com/llvm/llvm-project/commit/3c87f66b7e642790cafd877ff6b1fcb8a712c66a
DIFF: https://github.com/llvm/llvm-project/commit/3c87f66b7e642790cafd877ff6b1fcb8a712c66a.diff

LOG: [BasicAA] Make use of nusw+nuw -> nneg implication (#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

Added: 
    llvm/test/Analysis/BasicAA/nusw_nuw_nonneg.ll

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp

Removed: 
    


################################################################################
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