[llvm] BasicAA: return more PartialAlias when scalable (PR #110519)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 30 09:53:31 PDT 2024


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/110519

>From f88eba44d30031105337cc1b83e686e805d83cd3 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 30 Sep 2024 15:34:26 +0100
Subject: [PATCH 1/2] BasicAA: return more PartialAlias when scalable

Follow up on 84ea236 ([BasicAA] Handle scalable type sizes with constant
offsets) to increase accuracy of BasicAA in the case of scalable sizes,
returning more PartialAlias in place of MayAlias. This is done by
checking that Off < (CR.Lower * LSizeMin), analogous to the non-scalable
case.
---
 llvm/lib/Analysis/BasicAliasAnalysis.cpp | 20 ++++++++++++--------
 llvm/test/Analysis/BasicAA/vscale.ll     | 12 ++++++------
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index a00ed7530ebc4c..89f877cd4ce31a 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1210,15 +1210,19 @@ AliasResult BasicAAResult::aliasGEP(
         return AR;
       }
       return AliasResult::NoAlias;
-    } else {
-      // We can use the getVScaleRange to prove that Off >= (CR.upper * LSize).
-      ConstantRange CR = getVScaleRange(&F, Off.getBitWidth());
-      bool Overflow;
-      APInt UpperRange = CR.getUnsignedMax().umul_ov(
-          APInt(Off.getBitWidth(), LSize.getKnownMinValue()), Overflow);
-      if (!Overflow && Off.uge(UpperRange))
-        return AliasResult::NoAlias;
     }
+
+    // We can use the getVScaleRange to prove that Off >= (CR.upper * LSizeMin)
+    // and Off < (CR.Lower * LSizeMin).
+    APInt LSizeMin = APInt(Off.getBitWidth(), LSize.getKnownMinValue());
+    ConstantRange CR = getVScaleRange(&F, Off.getBitWidth());
+    bool Overflow;
+    APInt UpperRange = CR.getUnsignedMax().umul_ov(LSizeMin, Overflow);
+    if (!Overflow && Off.uge(UpperRange))
+      return AliasResult::NoAlias;
+    APInt LowerRange = CR.getUnsignedMin().umul_ov(LSizeMin, Overflow);
+    if (!Overflow && Off.ult(LowerRange))
+      return AliasResult::PartialAlias;
   }
 
   // VScale Alias Analysis - Given one scalable offset between accesses and a
diff --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll
index 05b9b6b3c3a970..8533c8d9e123af 100644
--- a/llvm/test/Analysis/BasicAA/vscale.ll
+++ b/llvm/test/Analysis/BasicAA/vscale.ll
@@ -33,8 +33,8 @@ define void @gep_alloca_const_offset_2() {
 
 ; CHECK-LABEL: gep_alloca_const_offset_3
 ; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
-; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, i32* %gep2
-; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, i32* %gep2
+; CHECK-DAG:  PartialAlias: <vscale x 4 x i32>* %alloc, i32* %gep2
+; CHECK-DAG:  PartialAlias: <vscale x 4 x i32>* %gep1, i32* %gep2
 define void @gep_alloca_const_offset_3() {
   %alloc = alloca <vscale x 4 x i32>
   %gep1 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 0
@@ -628,11 +628,11 @@ define void @gep_recursion_max_lookup_depth_reached(ptr %a, ptr %p) {
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %p
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off255
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %off256, <vscale x 4 x i32>* %p
-; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %off256
+; CHECK-DAG:   PartialAlias: <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %off256
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off256
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %p
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off255
-; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %noff256
+; CHECK-DAG:   PartialAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %noff256
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off256
 define void @gep_2048(ptr %p) {
   %off255 = getelementptr i8, ptr %p, i64 255
@@ -652,11 +652,11 @@ define void @gep_2048(ptr %p) {
 ; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %p
 ; CHECK-DAG:   NoAlias:      <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off255
 ; CHECK-DAG:   NoAlias:      <vscale x 4 x i32>* %off256, <vscale x 4 x i32>* %p
-; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %off256
+; CHECK-DAG:   PartialAlias: <vscale x 4 x i32>* %off255, <vscale x 4 x i32>* %off256
 ; CHECK-DAG:   NoAlias:      <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %off256
 ; CHECK-DAG:   NoAlias:      <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %p
 ; CHECK-DAG:   NoAlias:      <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off255
-; CHECK-DAG:   MayAlias:     <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %noff256
+; CHECK-DAG:   PartialAlias: <vscale x 4 x i32>* %noff255, <vscale x 4 x i32>* %noff256
 ; CHECK-DAG:   NoAlias:      <vscale x 4 x i32>* %noff256, <vscale x 4 x i32>* %off256
 define void @gep_2048_vscalerange(ptr %p) vscale_range(1,16) {
   %off255 = getelementptr i8, ptr %p, i64 255

>From b7d238f7747fa579e507c26ee3bc773bf7665fc9 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 30 Sep 2024 17:52:55 +0100
Subject: [PATCH 2/2] BasicAA: set Offset for PartialAlias + scalable

---
 llvm/lib/Analysis/BasicAliasAnalysis.cpp | 11 +++++++++--
 llvm/test/Analysis/BasicAA/vscale.ll     |  6 +++---
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 89f877cd4ce31a..6f61fd0e5950d0 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1221,8 +1221,15 @@ AliasResult BasicAAResult::aliasGEP(
     if (!Overflow && Off.uge(UpperRange))
       return AliasResult::NoAlias;
     APInt LowerRange = CR.getUnsignedMin().umul_ov(LSizeMin, Overflow);
-    if (!Overflow && Off.ult(LowerRange))
-      return AliasResult::PartialAlias;
+    if (!Overflow && Off.ult(LowerRange)) {
+      AliasResult AR = AliasResult::PartialAlias;
+      if (VRightSize.hasValue() && !VRightSize.isScalable() &&
+          Off.ule(INT32_MAX) && (Off + VRightSize.getValue()).ule(LSizeMin)) {
+        AR.setOffset(-Off.getSExtValue());
+        AR.swap(Swapped);
+      }
+      return AR;
+    }
   }
 
   // VScale Alias Analysis - Given one scalable offset between accesses and a
diff --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll
index 8533c8d9e123af..33edfc81b039bc 100644
--- a/llvm/test/Analysis/BasicAA/vscale.ll
+++ b/llvm/test/Analysis/BasicAA/vscale.ll
@@ -32,9 +32,9 @@ define void @gep_alloca_const_offset_2() {
 }
 
 ; CHECK-LABEL: gep_alloca_const_offset_3
-; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
-; CHECK-DAG:  PartialAlias: <vscale x 4 x i32>* %alloc, i32* %gep2
-; CHECK-DAG:  PartialAlias: <vscale x 4 x i32>* %gep1, i32* %gep2
+; CHECK-DAG:  MustAlias:            <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
+; CHECK-DAG:  PartialAlias (off 4): <vscale x 4 x i32>* %alloc, i32* %gep2
+; CHECK-DAG:  PartialAlias (off 4): <vscale x 4 x i32>* %gep1, i32* %gep2
 define void @gep_alloca_const_offset_3() {
   %alloc = alloca <vscale x 4 x i32>
   %gep1 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 0



More information about the llvm-commits mailing list