[PATCH] D112486: [BasicAA] Make range check more precise

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 25 13:32:04 PDT 2021


nikic created this revision.
nikic added reviewers: courbet, reames, fhahn, jdoerfert.
Herald added subscribers: jeroen.dobbelaere, hiraditya.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Make the range check more precise by calculating the range of potentially accessed bytes for both accesses and checking whether their intersection is empty. In that case there can be no overlap between the accesses and the result is NoAlias.

This is more powerful than the previous approach, because it can deal with sign-wrapped ranges. In the test case the original range is [-1, INT_MAX] but becomes [0, INT_MIN] after applying the offset. This is a wrapping range, so getSignedMin/getSignedMax will treat it as a full range. However, the range excludes the elements [INT_MIN+1, -1], which is enough to prove NoAlias with an access at offset -1.


https://reviews.llvm.org/D112486

Files:
  llvm/lib/Analysis/BasicAliasAnalysis.cpp
  llvm/test/Analysis/BasicAA/range.ll


Index: llvm/test/Analysis/BasicAA/range.ll
===================================================================
--- llvm/test/Analysis/BasicAA/range.ll
+++ llvm/test/Analysis/BasicAA/range.ll
@@ -196,13 +196,13 @@
   ret void
 }
 
-; TODO: p.neg1 and p.o.1 don't alias, even though the addition o+1 may overflow.
+; p.neg1 and p.o.1 don't alias, even though the addition o+1 may overflow.
 ; While it makes INT_MIN a possible offset, offset -1 is not possible.
 ; CHECK-LABEL: Function: benign_overflow
 ; CHECK: MayAlias: i8* %p, i8* %p.o
 ; CHECK: MayAlias: i8* %p.neg1, i8* %p.o
 ; CHECK: MayAlias: i8* %p, i8* %p.o.1
-; CHECK: MayAlias: i8* %p.neg1, i8* %p.o.1
+; CHECK: NoAlias: i8* %p.neg1, i8* %p.o.1
 ; CHECK: NoAlias:  i8* %p.o, i8* %p.o.1
 define void @benign_overflow(i8* %p, i64 %o) {
   %c = icmp sge i64 %o, -1
Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp
===================================================================
--- llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1315,15 +1315,16 @@
         (-DecompGEP1.Offset).uge(V1Size.getValue()))
       return AliasResult::NoAlias;
 
-    if (!Range.isEmptySet()) {
-      // We know that Offset >= MinOffset.
-      // (MinOffset >= V2Size) => (Offset >= V2Size) => NoAlias.
-      if (V2Size.hasValue() && Range.getSignedMin().sge(V2Size.getValue()))
-        return AliasResult::NoAlias;
-
-      // We know that Offset <= MaxOffset.
-      // (MaxOffset <= -V1Size) => (Offset <= -V1Size) => NoAlias.
-      if (V1Size.hasValue() && Range.getSignedMax().sle(-V1Size.getValue()))
+    if (V1Size.hasValue() && V2Size.hasValue()) {
+      // Range currently holds possible offsets. Convert it into a range of
+      // potentially accessed bytes and intersect it with potentially accessed
+      // bytes of the other access.
+      unsigned BW = Range.getBitWidth();
+      Range = Range.add(ConstantRange(APInt(BW, 0),
+                                      APInt(BW, V1Size.getValue())));
+      ConstantRange Range2 =
+          ConstantRange(APInt(BW, 0), APInt(BW, V2Size.getValue()));
+      if (Range.intersectWith(Range2).isEmptySet())
         return AliasResult::NoAlias;
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112486.382104.patch
Type: text/x-patch
Size: 2206 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211025/41bb7cf1/attachment.bin>


More information about the llvm-commits mailing list