[llvm] [SPIRV] Add OpAccessChain to instruction selector (PR #66111)

Nathan Gauër via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 12 09:54:04 PDT 2023


https://github.com/Keenuts created https://github.com/llvm/llvm-project/pull/66111:

Graphical SPIR-V cannot use OpPtrAccessChain, so we need to add support for OpAccessChain.

We generate the InBounds variant depending on the LLVM IR.

TODO: figure out if I can only rely on the IR's InBounds marker, or if the SPIR-V spec has is more restrictive.

TODO(66107): fix pointer types, as I cannot test this with valid SPIR-V until it is done.

>From a5954895e3ee5acc1c0722744be7ac6a44e5076b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Tue, 12 Sep 2023 18:40:28 +0200
Subject: [PATCH] [SPIRV] Add OpAccessChain to instruction selector
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Graphical SPIR-V cannot use OpPtrAccessChain, so we need
to add support for OpAccessChain.

We generate the InBounds variant depending on the LLVM IR.

TODO: figure out if I can only rely on the IR's InBounds marker,
or if the SPIR-V spec has is more restrictive.

TODO(66107): fix pointer types, as I cannot test this with valid SPIR-V
until it is done.

Signed-off-by: Nathan Gauër <brioche at google.com>
---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 14 +++++----
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp |  2 +-
 .../CodeGen/SPIRV/logical-access-chain.ll     | 12 ++++++++
 .../CodeGen/SPIRV/logical-struct-access.ll    | 30 +++++++++++++++++++
 4 files changed, 52 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/logical-access-chain.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/logical-struct-access.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index bd3b9b0228434a3..d1d690c674e7ee8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1298,11 +1298,15 @@ bool SPIRVInstructionSelector::selectExtractElt(Register ResVReg,
 bool SPIRVInstructionSelector::selectGEP(Register ResVReg,
                                          const SPIRVType *ResType,
                                          MachineInstr &I) const {
-  // In general we should also support OpAccessChain instrs here (i.e. not
-  // PtrAccessChain) but SPIRV-LLVM Translator doesn't emit them at all and so
-  // do we to stay compliant with its test and more importantly consumers.
-  unsigned Opcode = I.getOperand(2).getImm() ? SPIRV::OpInBoundsPtrAccessChain
-                                             : SPIRV::OpPtrAccessChain;
+  const bool isGEPInBounds = I.getOperand(2).getImm();
+
+  // OpAccessChain could be used for OpenCL, but the SPIRV-LLVM Translator only relies
+  // on PtrAccessChain, so we'll try not to deviate. For Vulkan however, we have to use
+  // Op[InBounds]AccessChain.
+  const unsigned Opcode = STI.isVulkanEnv()
+                   ? (isGEPInBounds ? SPIRV::OpInBoundsAccessChain    : SPIRV::OpAccessChain)
+                   : (isGEPInBounds ? SPIRV::OpInBoundsPtrAccessChain : SPIRV::OpPtrAccessChain);
+
   auto Res = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode))
                  .addDef(ResVReg)
                  .addUse(GR.getSPIRVTypeID(ResType))
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 065eacf6ad1f1f7..3cb184ab1f5b23e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -586,7 +586,7 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL(
 
 void RequirementHandler::initAvailableCapabilitiesForVulkan(
     const SPIRVSubtarget &ST) {
-  addAvailableCaps({Capability::Shader, Capability::Linkage});
+  addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8});
 }
 
 } // namespace SPIRV
diff --git a/llvm/test/CodeGen/SPIRV/logical-access-chain.ll b/llvm/test/CodeGen/SPIRV/logical-access-chain.ll
new file mode 100644
index 000000000000000..742b22d2d928f65
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/logical-access-chain.ll
@@ -0,0 +1,12 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+
+define void @main() #1 {
+entry:
+  %0 = alloca <2 x i8>, align 4
+  %1 = getelementptr i8, ptr %0, i32 0
+
+  ret void
+}
+
+attributes #1 = { "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" }
+
diff --git a/llvm/test/CodeGen/SPIRV/logical-struct-access.ll b/llvm/test/CodeGen/SPIRV/logical-struct-access.ll
new file mode 100644
index 000000000000000..d4d1a2f22fdfe7f
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/logical-struct-access.ll
@@ -0,0 +1,30 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+
+%A = type {
+  i32,
+  i32
+}
+
+%B = type {
+  %A,
+  i32,
+  %A
+}
+
+define void @main() #1 {
+entry:
+  %0 = alloca %B, align 4
+
+  %1 = getelementptr %B, ptr %0, i32 1
+  %2 = getelementptr inbounds %B, ptr %0, i32 1
+
+  %3 = getelementptr %B, ptr %0, i32 0, i32 0
+  %4 = getelementptr inbounds %B, ptr %0, i32 0, i32 0
+
+  %5 = getelementptr %B, ptr %0, i32 2, i32 1
+  %6 = getelementptr inbounds %B, ptr %0, i32 2, i32 1
+
+  ret void
+}
+
+attributes #1 = { "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" }



More information about the llvm-commits mailing list