[llvm] [SPIR-V] Order alias-decl instructions so definitions precede uses (PR #203699)
Dmitry Sidorov via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 13 05:53:33 PDT 2026
https://github.com/MrSidims created https://github.com/llvm/llvm-project/pull/203699
The SPV_INTEL_memory_access_aliasing decl instructions are built at the insertion point of the memory operation being selected. Because selection is bottom-up, an alias domain shared between scopes that are built at different memory operations could be emitted after a scope that references it.
Sort the collected aliasing instructions by dependency tier.
>From e826fed234a09003c7befd3c3b36e4a33ddad1b4 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Sat, 13 Jun 2026 01:16:28 +0200
Subject: [PATCH] [SPIR-V] Order alias-decl instructions so definitions precede
uses
The SPV_INTEL_memory_access_aliasing decl instructions
are built at the insertion point of the memory operation being selected. Because
selection is bottom-up, an alias domain shared between scopes that are built at
different memory operations could be emitted after a scope that references it.
Sort the collected aliasing instructions by dependency tier.
---
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 19 ++++++++++++++
.../alias-domain-order.ll | 25 +++++++++++++++++++
.../alias-load-store.ll | 10 ++++----
.../alias-masked-load-store.ll | 10 ++++----
4 files changed, 54 insertions(+), 10 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-domain-order.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 4c3084e12b4d8..a37d8e93d2706 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -754,6 +754,25 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
}
}
}
+ // Selection order can place a scope/list ahead of a domain/scope it
+ // references. The dependency meanwhile is domain -> scope -> list, so sort
+ // the def before its uses.
+ auto AliasingTier = [](const MachineInstr *MI) {
+ switch (MI->getOpcode()) {
+ case SPIRV::OpAliasDomainDeclINTEL:
+ return 0;
+ case SPIRV::OpAliasScopeDeclINTEL:
+ return 1;
+ case SPIRV::OpAliasScopeListDeclINTEL:
+ return 2;
+ default:
+ llvm_unreachable("unexpected aliasing instruction");
+ }
+ };
+ stable_sort(MAI.MS[SPIRV::MB_AliasingInsts],
+ [&](const MachineInstr *LHS, const MachineInstr *RHS) {
+ return AliasingTier(LHS) < AliasingTier(RHS);
+ });
}
// Number registers in all functions globally from 0 onwards and store
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-domain-order.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-domain-order.ll
new file mode 100644
index 0000000000000..26f8e1aed422f
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-domain-order.ll
@@ -0,0 +1,25 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+; TODO: add spirv-val once SPV_INTEL_memory_access_aliasing is supported by it.
+
+; Two noalias scopes sharing a single alias domain. Check order correctness.
+
+; CHECK: OpCapability MemoryAccessAliasingINTEL
+; CHECK: OpExtension "SPV_INTEL_memory_access_aliasing"
+; CHECK: %[[#Domain:]] = OpAliasDomainDeclINTEL
+; CHECK: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain]]
+; CHECK: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain]]
+; CHECK: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
+; CHECK: %[[#List2:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+
+define spir_kernel void @foo(ptr addrspace(4) %a, ptr addrspace(4) %b) {
+entry:
+ %v = load i32, ptr addrspace(4) %a, align 4, !alias.scope !0, !noalias !3
+ store i32 %v, ptr addrspace(4) %b, align 4, !noalias !0
+ ret void
+}
+
+!0 = !{!1}
+!1 = distinct !{!1, !2, !"foo: %a"}
+!2 = distinct !{!2, !"foo"}
+!3 = !{!4}
+!4 = distinct !{!4, !2, !"foo: %b"}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
index f8e8364eda642..0f00f812f9f2d 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
@@ -7,14 +7,14 @@
; CHECK-EXT: OpCapability MemoryAccessAliasingINTEL
; CHECK-EXT: OpExtension "SPV_INTEL_memory_access_aliasing"
; CHECK-EXT: %[[#Domain1:]] = OpAliasDomainDeclINTEL
-; CHECK-EXT: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
-; CHECK-EXT: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
; CHECK-EXT: %[[#Domain2:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Domain3:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain2]]
+; CHECK-EXT: %[[#Scope3:]] = OpAliasScopeDeclINTEL %[[#Domain3]]
+; CHECK-EXT: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
; CHECK-EXT: %[[#List2:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
-; CHECK-EXT: %[[#Domain3:]] = OpAliasDomainDeclINTEL
-; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain3]]
-; CHECK-EXT: %[[#List3:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+; CHECK-EXT: %[[#List3:]] = OpAliasScopeListDeclINTEL %[[#Scope3]]
; CHECK-EXT: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask 4 %[[#List2]]
; CHECK-EXT: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask|NoAliasINTELMask 4 %[[#List2]] %[[#List1]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
index 729a85ea888b5..bb7c90eae3ecd 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
@@ -7,14 +7,14 @@
; CHECK-EXT: OpCapability MemoryAccessAliasingINTEL
; CHECK-EXT: OpExtension "SPV_INTEL_memory_access_aliasing"
; CHECK-EXT: %[[#Domain1:]] = OpAliasDomainDeclINTEL
-; CHECK-EXT: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
-; CHECK-EXT: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
; CHECK-EXT: %[[#Domain2:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Domain3:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain2]]
+; CHECK-EXT: %[[#Scope3:]] = OpAliasScopeDeclINTEL %[[#Domain3]]
+; CHECK-EXT: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
; CHECK-EXT: %[[#List2:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
-; CHECK-EXT: %[[#Domain3:]] = OpAliasDomainDeclINTEL
-; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain3]]
-; CHECK-EXT: %[[#List3:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+; CHECK-EXT: %[[#List3:]] = OpAliasScopeListDeclINTEL %[[#Scope3]]
; CHECK-EXT: OpDecorateId %[[#Fun1:]] AliasScopeINTEL %[[#List1]]
; CHECK-EXT: OpDecorateId %[[#Fun2:]] AliasScopeINTEL %[[#List1]]
; CHECK-EXT: OpDecorateId %[[#Fun2]] NoAliasINTEL %[[#List2]]
More information about the llvm-commits
mailing list