[llvm] [BasicAA] Scalable offset with scalable typesize. (PR #80818)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 7 02:30:36 PST 2024
https://github.com/davemgreen updated https://github.com/llvm/llvm-project/pull/80818
>From bb6be7cddc66afa8ef957c8c3c4df81e86edef5d Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Mon, 5 Feb 2024 15:02:50 +0000
Subject: [PATCH 1/2] [BasicAA] More vscale tests. NFC
This time with i8 geps and scale intrinsics, along with mutiple vscale
intrinsics that can be treated as identical.
---
llvm/test/Analysis/BasicAA/vscale.ll | 168 +++++++++++++++++++++++++++
1 file changed, 168 insertions(+)
diff --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll
index 3fff435463a6d2..1b9118bf3853ab 100644
--- a/llvm/test/Analysis/BasicAA/vscale.ll
+++ b/llvm/test/Analysis/BasicAA/vscale.ll
@@ -309,6 +309,174 @@ define void @v1v2types(ptr %p) vscale_range(1,16) {
ret void
}
+; VScale intrinsic offset tests
+
+; CHECK-LABEL: vscale_neg_notscalable
+; CHECK-DAG: NoAlias: <4 x i32>* %p, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %p
+; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <4 x i32>* %p, <4 x i32>* %vm16m16
+; CHECK-DAG: NoAlias: <4 x i32>* %vm16, <4 x i32>* %vm16m16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <4 x i32>* %m16pv16, <4 x i32>* %p
+; CHECK-DAG: NoAlias: <4 x i32>* %m16pv16, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %m16pv16
+; CHECK-DAG: MayAlias: <4 x i32>* %m16pv16, <4 x i32>* %vm16m16
+define void @vscale_neg_notscalable(ptr %p) {
+ %v = call i64 @llvm.vscale.i64()
+ %vp = mul nsw i64 %v, 16
+ %vm = mul nsw i64 %v, -16
+ %vm16 = getelementptr i8, ptr %p, i64 %vm
+ %m16 = getelementptr <4 x i32>, ptr %p, i64 -1
+ %vm16m16 = getelementptr <4 x i32>, ptr %vm16, i64 -1
+ %m16pv16 = getelementptr i8, ptr %m16, i64 %vp
+ load <4 x i32>, ptr %p
+ load <4 x i32>, ptr %vm16
+ load <4 x i32>, ptr %m16
+ load <4 x i32>, ptr %vm16m16
+ load <4 x i32>, ptr %m16pv16
+ ret void
+}
+
+; CHECK-LABEL: vscale_neg_scalable
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vm16, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %m16pv16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16m16
+define void @vscale_neg_scalable(ptr %p) {
+ %v = call i64 @llvm.vscale.i64()
+ %vp = mul nsw i64 %v, 16
+ %vm = mul nsw i64 %v, -16
+ %vm16 = getelementptr i8, ptr %p, i64 %vm
+ %m16 = getelementptr <4 x i32>, ptr %p, i64 -1
+ %vm16m16 = getelementptr <4 x i32>, ptr %vm16, i64 -1
+ %m16pv16 = getelementptr i8, ptr %m16, i64 %vp
+ load <vscale x 4 x i32>, ptr %p
+ load <vscale x 4 x i32>, ptr %vm16
+ load <vscale x 4 x i32>, ptr %m16
+ load <vscale x 4 x i32>, ptr %vm16m16
+ load <vscale x 4 x i32>, ptr %m16pv16
+ ret void
+}
+
+; CHECK-LABEL: vscale_pos_notscalable
+; CHECK-DAG: NoAlias: <4 x i32>* %p, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %p
+; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <4 x i32>* %p, <4 x i32>* %vm16m16
+; CHECK-DAG: NoAlias: <4 x i32>* %vm16, <4 x i32>* %vm16m16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <4 x i32>* %m16pv16, <4 x i32>* %p
+; CHECK-DAG: NoAlias: <4 x i32>* %m16pv16, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %m16pv16
+; CHECK-DAG: MayAlias: <4 x i32>* %m16pv16, <4 x i32>* %vm16m16
+define void @vscale_pos_notscalable(ptr %p) {
+ %v = call i64 @llvm.vscale.i64()
+ %vp = mul nsw i64 %v, 16
+ %vm = mul nsw i64 %v, -16
+ %vm16 = getelementptr i8, ptr %p, i64 %vp
+ %m16 = getelementptr <4 x i32>, ptr %p, i64 1
+ %vm16m16 = getelementptr <4 x i32>, ptr %vm16, i64 1
+ %m16pv16 = getelementptr i8, ptr %m16, i64 %vm
+ load <4 x i32>, ptr %p
+ load <4 x i32>, ptr %vm16
+ load <4 x i32>, ptr %m16
+ load <4 x i32>, ptr %vm16m16
+ load <4 x i32>, ptr %m16pv16
+ ret void
+}
+
+; CHECK-LABEL: vscale_pos_scalable
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vm16, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %m16pv16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16m16
+define void @vscale_pos_scalable(ptr %p) {
+ %v = call i64 @llvm.vscale.i64()
+ %vp = mul nsw i64 %v, 16
+ %vm = mul nsw i64 %v, -16
+ %vm16 = getelementptr i8, ptr %p, i64 %vp
+ %m16 = getelementptr <4 x i32>, ptr %p, i64 1
+ %vm16m16 = getelementptr <4 x i32>, ptr %vm16, i64 1
+ %m16pv16 = getelementptr i8, ptr %m16, i64 %vm
+ load <vscale x 4 x i32>, ptr %p
+ load <vscale x 4 x i32>, ptr %vm16
+ load <vscale x 4 x i32>, ptr %m16
+ load <vscale x 4 x i32>, ptr %vm16m16
+ load <vscale x 4 x i32>, ptr %m16pv16
+ ret void
+}
+
+; CHECK-LABEL: vscale_v1v2types
+; CHECK-DAG: MustAlias: <4 x i32>* %p, <vscale x 4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %p, <4 x i32>* %vm16
+; CHECK-DAG: MustAlias: <4 x i32>* %vm16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <4 x i32>* %p
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %p
+; CHECK-DAG: NoAlias: <4 x i32>* %m16, <4 x i32>* %p
+; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16
+; CHECK-DAG: MustAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %m16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: MayAlias: <4 x i32>* %p, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vm16, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: MayAlias: <4 x i32>* %vm16, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %vp16
+define void @vscale_v1v2types(ptr %p) {
+ %v = call i64 @llvm.vscale.i64()
+ %vp = mul nsw i64 %v, 16
+ %vm = mul nsw i64 %v, -16
+ %vp16 = getelementptr i8, ptr %p, i64 %vp
+ %vm16 = getelementptr i8, ptr %p, i64 %vm
+ %m16 = getelementptr <4 x i32>, ptr %p, i64 -1
+ load <vscale x 4 x i32>, ptr %p
+ load <4 x i32>, ptr %p
+ load <vscale x 4 x i32>, ptr %vm16
+ load <4 x i32>, ptr %vm16
+ load <vscale x 4 x i32>, ptr %m16
+ load <4 x i32>, ptr %m16
+ load <vscale x 4 x i32>, ptr %vp16
+ ret void
+}
+
+; CHECK-LABEL: twovscales
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp162
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161, <vscale x 4 x i32>* %vp161b
+; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vp161b, <vscale x 4 x i32>* %vp162
+define void @twovscales(ptr %p) {
+ %v1 = call i64 @llvm.vscale.i64()
+ %v2 = call i64 @llvm.vscale.i64()
+ %vp1 = mul nsw i64 %v1, 16
+ %vp2 = mul nsw i64 %v2, 16
+ %vp3 = mul nsw i64 %v1, 17
+ %vp161 = getelementptr i8, ptr %p, i64 %vp1
+ %vp162 = getelementptr i8, ptr %p, i64 %vp2
+ %vp161b = getelementptr i8, ptr %vp161, i64 %vp3
+ load <vscale x 4 x i32>, ptr %vp161
+ load <vscale x 4 x i32>, ptr %vp162
+ load <vscale x 4 x i32>, ptr %vp161b
+ ret void
+}
+
; getelementptr recursion
; CHECK-LABEL: gep_recursion_level_1
>From b1a2dbeff24a2297fac8ff6ac72bdd021b4ef748 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Wed, 7 Feb 2024 10:27:08 +0000
Subject: [PATCH 2/2] [BasicAA] Scalable offset with scalable typesize.
This patch adds a simple alias analysis check for accesses that are scalable
with a offset between them that is also trivially scalable (there are no other
constant/variable offsets). We essentially divide each side by vscale and are
left needing to check that the offset >= typesize.
---
llvm/lib/Analysis/BasicAliasAnalysis.cpp | 20 ++++++++++++++++++++
llvm/test/Analysis/BasicAA/vscale.ll | 22 +++++++++++-----------
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 19c4393add6ab9..7a968b07e44480 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1170,6 +1170,26 @@ AliasResult BasicAAResult::aliasGEP(
}
}
+ // VScale Alias Analysis - Given one scalable offset between accesses and a
+ // scalable typesize, we can divide each side by vscale, treating both values
+ // as a constant. We prove that Offset/vscale >= TypeSize/vscale.
+ if (DecompGEP1.VarIndices.size() == 1 && DecompGEP1.VarIndices[0].IsNSW &&
+ DecompGEP1.Offset.isZero() &&
+ PatternMatch::match(DecompGEP1.VarIndices[0].Val.V,
+ PatternMatch::m_VScale())) {
+ const VariableGEPIndex &ScalableVar = DecompGEP1.VarIndices[0];
+ APInt Scale =
+ ScalableVar.IsNegated ? -ScalableVar.Scale : ScalableVar.Scale;
+ LocationSize VLeftSize = Scale.isNegative() ? V1Size : V2Size;
+
+ // Note that we do not check that the typesize is scalable, as vscale >= 1
+ // so noalias still holds so long as the dependency distance is at least as
+ // big as the typesize.
+ if (VLeftSize.hasValue() &&
+ Scale.uge(VLeftSize.getValue().getKnownMinValue()))
+ return AliasResult::NoAlias;
+ }
+
// Bail on analysing scalable LocationSize
if (V1Size.isScalable() || V2Size.isScalable())
return AliasResult::MayAlias;
diff --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll
index 1b9118bf3853ab..ce0c6f145d1c88 100644
--- a/llvm/test/Analysis/BasicAA/vscale.ll
+++ b/llvm/test/Analysis/BasicAA/vscale.ll
@@ -339,15 +339,15 @@ define void @vscale_neg_notscalable(ptr %p) {
}
; CHECK-LABEL: vscale_neg_scalable
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16m16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vm16, <vscale x 4 x i32>* %vm16m16
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16m16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %m16pv16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %m16pv16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16m16
define void @vscale_neg_scalable(ptr %p) {
%v = call i64 @llvm.vscale.i64()
@@ -393,15 +393,15 @@ define void @vscale_pos_notscalable(ptr %p) {
}
; CHECK-LABEL: vscale_pos_scalable
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16m16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vm16, <vscale x 4 x i32>* %vm16m16
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16m16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vm16m16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %m16pv16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %m16pv16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16pv16, <vscale x 4 x i32>* %vm16m16
define void @vscale_pos_scalable(ptr %p) {
%v = call i64 @llvm.vscale.i64()
@@ -421,9 +421,9 @@ define void @vscale_pos_scalable(ptr %p) {
; CHECK-LABEL: vscale_v1v2types
; CHECK-DAG: MustAlias: <4 x i32>* %p, <vscale x 4 x i32>* %p
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
-; CHECK-DAG: MayAlias: <4 x i32>* %p, <vscale x 4 x i32>* %vm16
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <4 x i32>* %p, <vscale x 4 x i32>* %vm16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %p, <4 x i32>* %vm16
; CHECK-DAG: NoAlias: <4 x i32>* %p, <4 x i32>* %vm16
; CHECK-DAG: MustAlias: <4 x i32>* %vm16, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %p
@@ -435,8 +435,8 @@ define void @vscale_pos_scalable(ptr %p) {
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %vm16
; CHECK-DAG: MayAlias: <4 x i32>* %m16, <4 x i32>* %vm16
; CHECK-DAG: MustAlias: <4 x i32>* %m16, <vscale x 4 x i32>* %m16
-; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vp16
-; CHECK-DAG: MayAlias: <4 x i32>* %p, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %p, <vscale x 4 x i32>* %vp16
+; CHECK-DAG: NoAlias: <4 x i32>* %p, <vscale x 4 x i32>* %vp16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %vm16, <vscale x 4 x i32>* %vp16
; CHECK-DAG: MayAlias: <4 x i32>* %vm16, <vscale x 4 x i32>* %vp16
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %m16, <vscale x 4 x i32>* %vp16
More information about the llvm-commits
mailing list