[llvm] [SPIRV] Add support for SPV_KHR_bit_instructions (PR #66215)

Paulo Matos via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 13 07:54:51 PDT 2023


https://github.com/pmatos created https://github.com/llvm/llvm-project/pull/66215:

Draft version of patch to add support for SPV_KHR_bit_instructions.

Created revision so we can discuss how to proceed here.
SPV_KHR_bit_instructions (http://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_bit_instructions.html),
adds support for instructions that we already support through
the Shader capability but without requiring the shader cap.

However we currently have no way to disable the shader cap afaiu.
On the other hand, SPV_KHR_bit_instructions was one of the
extensions @mpaszkowski listed that we need to implement.

So what does it mean at the moment the need to implement this?
Is it just the ability to issue the extension and capabilities
instructions without issuing the Shader capability? If so,
then I will need to add here a way to disable the Shader
capability. What do you think?

Differential Revision: https://reviews.llvm.org/D156661

>From dca825bc6345738446d6287328b1f2680a124aaf Mon Sep 17 00:00:00 2001
From: Paulo Matos <pmatos at igalia.com>
Date: Wed, 13 Sep 2023 16:38:35 +0200
Subject: [PATCH] [SPIRV] Add support for SPV_KHR_bit_instructions

Draft version of patch to add support for SPV_KHR_bit_instructions.

Created revision so we can discuss how to proceed here.
SPV_KHR_bit_instructions (http://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_bit_instructions.html),
adds support for instructions that we already support through
the Shader capability but without requiring the shader cap.

However we currently have no way to disable the shader cap afaiu.
On the other hand, SPV_KHR_bit_instructions was one of the
extensions @mpaszkowski listed that we need to implement.

So what does it mean at the moment the need to implement this?
Is it just the ability to issue the extension and capabilities
instructions without issuing the Shader capability? If so,
then I will need to add here a way to disable the Shader
capability. What do you think?

Differential Revision: https://reviews.llvm.org/D156661
---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 19 +++++++++++++++++++
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h   |  4 ++++
 llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp      |  1 +
 .../lib/Target/SPIRV/SPIRVSymbolicOperands.td |  1 +
 .../SPIRV/transcoding/OpBitReverse_i32.ll     |  3 +++
 5 files changed, 28 insertions(+)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 065eacf6ad1f1f7..b522eac44fe1741 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -15,6 +15,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "SPIRVModuleAnalysis.h"
+#include "MCTargetDesc/SPIRVBaseInfo.h"
+#include "MCTargetDesc/SPIRVMCTargetDesc.h"
 #include "SPIRV.h"
 #include "SPIRVSubtarget.h"
 #include "SPIRVTargetMachine.h"
@@ -523,6 +525,12 @@ void SPIRV::RequirementHandler::addAvailableCaps(const CapabilityList &ToAdd) {
           SPIRV::OperandCategory::CapabilityOperand, Cap));
 }
 
+void SPIRV::RequirementHandler::removeCapabilityIf(const Capability::Capability ToRemove, 
+                                                   const Capability::Capability IfPresent) {
+  if (AvailableCaps.contains(IfPresent))
+    AvailableCaps.erase(ToRemove);
+}
+
 namespace llvm {
 namespace SPIRV {
 void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
@@ -731,6 +739,11 @@ void addInstrRequirements(const MachineInstr &MI,
     break;
   }
   case SPIRV::OpBitReverse:
+  case SPIRV::OpBitFieldInsert:
+  case SPIRV::OpBitFieldSExtract:
+  case SPIRV::OpBitFieldUExtract:
+    Reqs.addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
+    break;
   case SPIRV::OpTypeRuntimeArray:
     Reqs.addCapability(SPIRV::Capability::Shader);
     break;
@@ -884,6 +897,12 @@ void addInstrRequirements(const MachineInstr &MI,
   default:
     break;
   }
+
+  // If we require capability Shader, then we can remove the requirement for
+  // the BitInstructions capability, since Shader is a superset capability
+  // of BitInstructions.
+  Reqs.removeCapabilityIf(SPIRV::Capability::Shader,
+                          SPIRV::Capability::BitInstructions);
 }
 
 static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index b57a5f4c28278ac..9eea9ac5bda5b08 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
@@ -113,6 +113,10 @@ struct RequirementHandler {
   bool isCapabilityAvailable(Capability::Capability Cap) const {
     return AvailableCaps.contains(Cap);
   }
+
+  // Remove capability ToRemove, but only if IfPresent is present.
+  void removeCapabilityIf(const Capability::Capability ToRemove,
+                          const Capability::Capability IfPresent);
 };
 
 using InstrList = SmallVector<MachineInstr *>;
diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
index 1bad1d8109623b6..fdf103941f4b95e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SPIRVSubtarget.h"
+#include "MCTargetDesc/SPIRVBaseInfo.h"
 #include "SPIRV.h"
 #include "SPIRVGlobalRegistry.h"
 #include "SPIRVLegalizerInfo.h"
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index c27d2826c0159d1..ab06f5308700bc5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -450,6 +450,7 @@ defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shad
 defm CooperativeMatrixNV : CapabilityOperand<5357, 0, 0, [], [Shader]>;
 defm ArbitraryPrecisionIntegersINTEL : CapabilityOperand<5844, 0, 0, [SPV_INTEL_arbitrary_precision_integers], [Int8, Int16]>;
 defm OptNoneINTEL : CapabilityOperand<6094, 0, 0, [SPV_INTEL_optnone], []>;
+defm BitInstructions : CapabilityOperand<6025, 0, 0, [SPV_KHR_bit_instructions], []>;
 
 //===----------------------------------------------------------------------===//
 // Multiclass used to define SourceLanguage enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpBitReverse_i32.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpBitReverse_i32.ll
index f396b5a01ae91c1..4f95c4770780432 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpBitReverse_i32.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpBitReverse_i32.ll
@@ -1,5 +1,8 @@
 ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
 
+; CHECK-SPIRV:      OpCapability BitInstructions
+; CHECK-SPIRV-NEXT: OpExtension "SPV_KHR_bit_instructions"
+
 ; CHECK-SPIRV: %[[#int:]] = OpTypeInt 32
 ; CHECK-SPIRV: OpBitReverse %[[#int]]
 



More information about the llvm-commits mailing list