[llvm] 51e9f33 - [BasicAA] Use saturating multiply on range if nsw

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 2 12:31:45 PDT 2021


Author: Nikita Popov
Date: 2021-11-02T20:27:39+01:00
New Revision: 51e9f336030cc3892950763f9179e25fa582e3b9

URL: https://github.com/llvm/llvm-project/commit/51e9f336030cc3892950763f9179e25fa582e3b9
DIFF: https://github.com/llvm/llvm-project/commit/51e9f336030cc3892950763f9179e25fa582e3b9.diff

LOG: [BasicAA] Use saturating multiply on range if nsw

If we know that the var * scale multiplication is nsw, we can use
a saturating multiplication on the range (as a good approximation
of an nsw multiply). This recovers some cases where the fix from
D112611 is unnecessarily strict. (This can be further strengthened
by using a saturating add, but we currently don't track all the
necessary information for that.)

This exposes an issue in our NSW tracking for multiplies. The code
was assuming that (X +nsw Y) *nsw Z results in
(X *nsw Z) +nsw (Y *nsw Z) -- however, it is possible that the
distributed multiplications overflow, even if the non-distributed
one does not. We should discard the nsw flag if the the offset is
non-zero. If we just have (X *nsw Y) *nsw Z then concluding
X *nsw (Y *nsw Z) is fine.

Differential Revision: https://reviews.llvm.org/D112848

Added: 
    

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/test/Analysis/BasicAA/assume-index-positive.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 7895b57dfae69..a8ef2e03c54c1 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -360,8 +360,10 @@ struct LinearExpression {
   }
 
   LinearExpression mul(const APInt &Other, bool MulIsNSW) const {
-    return LinearExpression(Val, Scale * Other, Offset * Other,
-                            IsNSW && (Other.isOne() || MulIsNSW));
+    // The check for zero offset is necessary, because generally
+    // (X +nsw Y) *nsw Z does not imply (X *nsw Z) +nsw (Y *nsw Z).
+    bool NSW = IsNSW && (Other.isOne() || (MulIsNSW && Offset.isZero()));
+    return LinearExpression(Val, Scale * Other, Offset * Other, NSW);
   }
 };
 }
@@ -1249,12 +1251,14 @@ AliasResult BasicAAResult::aliasGEP(
       CR = CR.intersectWith(
           ConstantRange::fromKnownBits(Known, /* Signed */ true),
           ConstantRange::Signed);
+      CR = Index.Val.evaluateWith(CR).sextOrTrunc(OffsetRange.getBitWidth());
 
       assert(OffsetRange.getBitWidth() == Scale.getBitWidth() &&
              "Bit widths are normalized to MaxPointerSize");
-      OffsetRange = OffsetRange.add(
-          Index.Val.evaluateWith(CR).sextOrTrunc(OffsetRange.getBitWidth())
-                                    .smul_fast(ConstantRange(Scale)));
+      if (Index.IsNSW)
+        OffsetRange = OffsetRange.add(CR.smul_sat(ConstantRange(Scale)));
+      else
+        OffsetRange = OffsetRange.add(CR.smul_fast(ConstantRange(Scale)));
     }
 
     // We now have accesses at two offsets from the same base:

diff  --git a/llvm/test/Analysis/BasicAA/assume-index-positive.ll b/llvm/test/Analysis/BasicAA/assume-index-positive.ll
index b7ae7060bab40..13f51aba5db70 100644
--- a/llvm/test/Analysis/BasicAA/assume-index-positive.ll
+++ b/llvm/test/Analysis/BasicAA/assume-index-positive.ll
@@ -145,12 +145,12 @@ define void @shl_of_non_negative(i8* %ptr, i64 %a) {
   ret void
 }
 
-; TODO: Unlike the previous case, %ptr.neg and %ptr.shl can't alias, because
+; Unlike the previous case, %ptr.neg and %ptr.shl can't alias, because
 ; shl nsw of non-negative is non-negative.
 define void @shl_nsw_of_non_negative(i8* %ptr, i64 %a) {
 ; CHECK-LABEL: Function: shl_nsw_of_non_negative
 ; CHECK: NoAlias: i8* %ptr.a, i8* %ptr.neg
-; CHECK: MayAlias: i8* %ptr.neg, i8* %ptr.shl
+; CHECK: NoAlias: i8* %ptr.neg, i8* %ptr.shl
   %a.cmp = icmp sge i64 %a, 0
   call void @llvm.assume(i1 %a.cmp)
   %ptr.neg = getelementptr i8, i8* %ptr, i64 -2


        


More information about the llvm-commits mailing list