[llvm] efe0e10 - [SPIR-V] Support SPV_INTEL_arbitrary_precision_integers_extension, misc utils for other extensions

Michal Paszkowski via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 12 02:54:34 PDT 2023


Author: Michal Paszkowski
Date: 2023-09-12T02:45:15-07:00
New Revision: efe0e10718cb72986a561cd1e4bd8bb57763b143

URL: https://github.com/llvm/llvm-project/commit/efe0e10718cb72986a561cd1e4bd8bb57763b143
DIFF: https://github.com/llvm/llvm-project/commit/efe0e10718cb72986a561cd1e4bd8bb57763b143.diff

LOG: [SPIR-V] Support SPV_INTEL_arbitrary_precision_integers_extension, misc utils for other extensions

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

Added: 
    llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_arbitrary_precision_integers.ll
    llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll
    llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll

Modified: 
    llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp
    llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
    llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
    llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
    llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
    llvm/lib/Target/SPIRV/SPIRVSubtarget.h
    llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
    llvm/test/CodeGen/SPIRV/transcoding/NoSignedUnsignedWrap.ll

Removed: 
    llvm/test/CodeGen/SPIRV/extensions/no_wrap.ll
    llvm/test/CodeGen/SPIRV/optnone.ll


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp
index 0b7b0160dee745b..020cfa6ee20fa90 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp
@@ -129,6 +129,24 @@ getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
   return Capabilities;
 }
 
+CapabilityList
+getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension) {
+  const SPIRV::ExtensionEntry *Entry =
+      SPIRV::lookupSymbolicOperandsEnabledByExtension(
+          Extension, SPIRV::OperandCategory::CapabilityOperand);
+
+  CapabilityList Capabilities;
+  while (Entry &&
+         Entry->Category == SPIRV::OperandCategory::CapabilityOperand &&
+         Entry->ReqExtension == Extension) {
+    Capabilities.push_back(
+        static_cast<SPIRV::Capability::Capability>(Entry->Value));
+    ++Entry;
+  }
+
+  return Capabilities;
+}
+
 ExtensionList
 getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
                              uint32_t Value) {

diff  --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
index d6075f72e55c9fc..616d2ea71b39b1f 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
@@ -223,6 +223,8 @@ getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,
 CapabilityList
 getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
                                uint32_t Value);
+CapabilityList
+getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension);
 ExtensionList
 getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
                              uint32_t Value);

diff  --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index c77a7f860eda251..8ac90d3ed8574e0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -81,7 +81,15 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeInt(uint32_t Width,
                                              MachineIRBuilder &MIRBuilder,
                                              bool IsSigned) {
   assert(Width <= 64 && "Unsupported integer width!");
-  if (Width <= 8)
+  const SPIRVSubtarget &ST =
+      cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
+  if (ST.canUseExtension(
+          SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers)) {
+    MIRBuilder.buildInstr(SPIRV::OpExtension)
+        .addImm(SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers);
+    MIRBuilder.buildInstr(SPIRV::OpCapability)
+        .addImm(SPIRV::Capability::ArbitraryPrecisionIntegersINTEL);
+  } else if (Width <= 8)
     Width = 8;
   else if (Width <= 16)
     Width = 16;

diff  --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 89f198b8af52397..065eacf6ad1f1f7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -574,9 +574,12 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL(
   // TODO: verify if this needs some checks.
   addAvailableCaps({Capability::Float16, Capability::Float64});
 
-  // Add cap for SPV_INTEL_optnone.
-  // FIXME: this should be added only if the target has the extension.
-  addAvailableCaps({Capability::OptNoneINTEL});
+  // Add capabilities enabled by extensions.
+  for (auto Extension : ST.getAllAvailableExtensions()) {
+    CapabilityList EnabledCapabilities =
+        getCapabilitiesEnabledByExtension(Extension);
+    addAvailableCaps(EnabledCapabilities);
+  }
 
   // TODO: add OpenCL extensions.
 }

diff  --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
index d1d7a31dbaf48c9..ced17aaeb17fe14 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
@@ -27,6 +27,21 @@ using namespace llvm;
 #define GET_SUBTARGETINFO_CTOR
 #include "SPIRVGenSubtargetInfo.inc"
 
+cl::list<SPIRV::Extension::Extension> Extensions(
+    "spirv-extensions", cl::desc("SPIR-V extensions"), cl::ZeroOrMore,
+    cl::Hidden,
+    cl::values(
+        clEnumValN(SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers,
+                   "SPV_INTEL_arbitrary_precision_integers",
+                   "Allows generating arbitrary width integer types"),
+        clEnumValN(SPIRV::Extension::SPV_INTEL_optnone, "SPV_INTEL_optnone",
+                   "Adds OptNoneINTEL value for Function Control mask that "
+                   "indicates a request to not optimize the function"),
+        clEnumValN(SPIRV::Extension::SPV_KHR_no_integer_wrap_decoration,
+                   "SPV_KHR_no_integer_wrap_decoration",
+                   "Adds decorations to indicate that a given instruction does "
+                   "not cause integer wrapping")));
+
 // Compare version numbers, but allow 0 to mean unspecified.
 static bool isAtLeastVer(uint32_t Target, uint32_t VerToCompareTo) {
   return Target == 0 || Target >= VerToCompareTo;
@@ -100,17 +115,13 @@ bool SPIRVSubtarget::canDirectlyComparePointers() const {
   return isAtLeastVer(SPIRVVersion, 14);
 }
 
-// TODO: use command line args for this rather than defaults.
 void SPIRVSubtarget::initAvailableExtensions() {
   AvailableExtensions.clear();
   if (!isOpenCLEnv())
     return;
-  // A default extension for testing.
-  // FIXME: This should be changed when we can select extensions through a
-  // command line flag.
-  AvailableExtensions.insert(
-      SPIRV::Extension::SPV_KHR_no_integer_wrap_decoration);
-  AvailableExtensions.insert(SPIRV::Extension::SPV_INTEL_optnone);
+
+  for (auto Extension : Extensions)
+    AvailableExtensions.insert(Extension);
 }
 
 // TODO: use command line args for this rather than just defaults.

diff  --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.h b/llvm/lib/Target/SPIRV/SPIRVSubtarget.h
index f81d7a240480d35..62524ebfc9bf8c1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.h
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.h
@@ -86,6 +86,10 @@ class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
   // TODO: implement command line args or other ways to determine this.
   bool hasOpenCLFullProfile() const { return true; }
   bool hasOpenCLImageSupport() const { return true; }
+  const SmallSet<SPIRV::Extension::Extension, 4> &
+  getAllAvailableExtensions() const {
+    return AvailableExtensions;
+  }
   bool canUseExtension(SPIRV::Extension::Extension E) const;
   bool canUseExtInstSet(SPIRV::InstructionSet::InstructionSet E) const;
 
@@ -113,6 +117,10 @@ class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
   const SPIRVRegisterInfo *getRegisterInfo() const override {
     return &InstrInfo.getRegisterInfo();
   }
+
+  static bool classof(const TargetSubtargetInfo *ST) {
+    return ST->getTargetTriple().isSPIRV();
+  }
 };
 } // namespace llvm
 

diff  --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index a7d2a3fc41cf385..c27d2826c0159d1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -77,6 +77,12 @@ def ExtensionEntries : GenericTable {
   let PrimaryKeyName = "lookupExtensionByCategoryAndValue";
 }
 
+// Function to lookup symbolic operands enabled by a given extension.
+def lookupSymbolicOperandsEnabledByExtension : SearchIndex {
+  let Table = ExtensionEntries;
+  let Key = ["ReqExtension", "Category"];
+}
+
 //===----------------------------------------------------------------------===//
 // Lookup table for matching symbolic operands (category + 32-bit value) to
 // SPIR-V capabilities. If an operand requires more than one capability, there
@@ -243,7 +249,52 @@ defm SPV_KHR_shader_clock : ExtensionOperand<54>;
 defm SPV_INTEL_unstructured_loop_controls : ExtensionOperand<55>;
 defm SPV_EXT_demote_to_helper_invocation : ExtensionOperand<56>;
 defm SPV_INTEL_fpga_reg : ExtensionOperand<57>;
-defm SPV_INTEL_optnone : ExtensionOperand<58>;
+defm SPV_INTEL_blocking_pipes : ExtensionOperand<58>;
+defm SPV_GOOGLE_user_type : ExtensionOperand<59>;
+defm SPV_KHR_physical_storage_buffer : ExtensionOperand<60>;
+defm SPV_INTEL_kernel_attributes : ExtensionOperand<61>;
+defm SPV_KHR_non_semantic_info : ExtensionOperand<62>;
+defm SPV_INTEL_io_pipes : ExtensionOperand<63>;
+defm SPV_KHR_ray_tracing : ExtensionOperand<64>;
+defm SPV_KHR_ray_query : ExtensionOperand<65>;
+defm SPV_INTEL_fpga_memory_accesses : ExtensionOperand<66>;
+defm SPV_INTEL_arbitrary_precision_integers : ExtensionOperand<67>;
+defm SPV_EXT_shader_atomic_float_add : ExtensionOperand<68>;
+defm SPV_KHR_terminate_invocation : ExtensionOperand<69>;
+defm SPV_KHR_fragment_shading_rate : ExtensionOperand<70>;
+defm SPV_EXT_shader_image_int64 : ExtensionOperand<71>;
+defm SPV_INTEL_fp_fast_math_mode : ExtensionOperand<72>;
+defm SPV_INTEL_fpga_cluster_attributes : ExtensionOperand<73>;
+defm SPV_INTEL_loop_fuse : ExtensionOperand<74>;
+defm SPV_EXT_shader_atomic_float_min_max : ExtensionOperand<75>;
+defm SPV_KHR_workgroup_memory_explicit_layout : ExtensionOperand<76>;
+defm SPV_KHR_linkonce_odr : ExtensionOperand<77>;
+defm SPV_KHR_expect_assume : ExtensionOperand<78>;
+defm SPV_INTEL_fpga_dsp_control : ExtensionOperand<79>;
+defm SPV_NV_bindless_texture : ExtensionOperand<80>;
+defm SPV_INTEL_fpga_invocation_pipelining_attributes : ExtensionOperand<81>;
+defm SPV_KHR_subgroup_uniform_control_flow : ExtensionOperand<82>;
+defm SPV_HUAWEI_subpass_shading : ExtensionOperand<83>;
+defm SPV_KHR_integer_dot_product : ExtensionOperand<84>;
+defm SPV_EXT_shader_atomic_float16_add : ExtensionOperand<85>;
+defm SPV_INTEL_runtime_aligned : ExtensionOperand<86>;
+defm SPV_KHR_bit_instructions : ExtensionOperand<87>;
+defm SPV_NV_ray_tracing_motion_blur : ExtensionOperand<88>;
+defm SPV_KHR_uniform_group_instructions : ExtensionOperand<89>;
+defm SPV_KHR_subgroup_rotate : ExtensionOperand<90>;
+defm SPV_INTEL_split_barrier : ExtensionOperand<91>;
+defm SPV_KHR_ray_cull_mask : ExtensionOperand<92>;
+defm SPV_KHR_fragment_shader_barycentric : ExtensionOperand<93>;
+defm SPV_EXT_relaxed_printf_string_address_space : ExtensionOperand<94>;
+defm SPV_EXT_ycbcr_attachments : ExtensionOperand<95>;
+defm SPV_EXT_mesh_shader : ExtensionOperand<96>;
+defm SPV_ARM_core_builtins : ExtensionOperand<97>;
+defm SPV_EXT_opacity_micromap : ExtensionOperand<98>;
+defm SPV_NV_shader_invocation_reorder : ExtensionOperand<99>;
+defm SPV_INTEL_usm_storage_classes : ExtensionOperand<100>;
+defm SPV_INTEL_fpga_latency_control : ExtensionOperand<101>;
+defm SPV_INTEL_fpga_argument_interfaces : ExtensionOperand<102>;
+defm SPV_INTEL_optnone : ExtensionOperand<103>;
 
 //===----------------------------------------------------------------------===//
 // Multiclass used to define Capabilities enum values and at the same time
@@ -397,6 +448,7 @@ defm ComputeDerivativeGroupLinearNV : CapabilityOperand<5350, 0, 0, [], []>;
 defm FragmentDensityEXT : CapabilityOperand<5291, 0, 0, [], [Shader]>;
 defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shader]>;
 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], []>;
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_arbitrary_precision_integers.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_arbitrary_precision_integers.ll
new file mode 100644
index 000000000000000..b68fb363ad85f8b
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_arbitrary_precision_integers.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-extensions=SPV_INTEL_arbitrary_precision_integers %s -o - | FileCheck %s
+
+define i6 @getConstantI6() {
+  ret i6 2
+}
+
+define i13 @getConstantI13() {
+  ret i13 42
+}
+
+;; Capabilities:
+; CHECK-DAG: OpExtension "SPV_INTEL_arbitrary_precision_integers"
+; CHECK-DAG: OpCapability ArbitraryPrecisionIntegersINTEL
+
+; CHECK-NOT: DAG-FENCE
+
+;; Names:
+; CHECK-DAG: OpName %[[#GET_I6:]] "getConstantI6"
+; CHECK-DAG: OpName %[[#GET_I13:]] "getConstantI13"
+
+; CHECK-NOT: DAG-FENCE
+
+;; Types and Constants:
+; CHECK-DAG: %[[#I6:]] = OpTypeInt 6 0
+; CHECK-DAG: %[[#I13:]] = OpTypeInt 13 0
+; CHECK-DAG: %[[#CST_I6:]] = OpConstant %[[#I6]] 2
+; CHECK-DAG: %[[#CST_I13:]] = OpConstant %[[#I13]] 42
+
+; CHECK: %[[#GET_I6]] = OpFunction %[[#I6]]
+; CHECK: OpReturnValue %[[#CST_I6]]
+; CHECK: OpFunctionEnd
+
+; CHECK: %[[#GET_I13]] = OpFunction %[[#I13]]
+; CHECK: OpReturnValue %[[#CST_I13]]
+; CHECK: OpFunctionEnd

diff  --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll
new file mode 100644
index 000000000000000..99d22a4a2ee639a
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll
@@ -0,0 +1,19 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-extensions=SPV_INTEL_optnone %s -o - | FileCheck %s --check-prefix=CHECK-EXTENSION
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXTENSION
+
+; CHECK-EXTENSION: OpCapability OptNoneINTEL
+; CHECK-EXTENSION: OpExtension "SPV_INTEL_optnone"
+; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneINTEL
+; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_INTEL_optnone"
+
+;; Per SPIR-V spec:
+;; FunctionControlDontInlineMask = 0x2 (2)
+; CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] DontInline
+
+; Function Attrs: nounwind optnone noinline
+define spir_func void @_Z3foov() #0 {
+entry:
+  ret void
+}
+
+attributes #0 = { nounwind optnone noinline }

diff  --git a/llvm/test/CodeGen/SPIRV/extensions/no_wrap.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll
similarity index 90%
rename from llvm/test/CodeGen/SPIRV/extensions/no_wrap.ll
rename to llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll
index a988b0a3bfff79d..e74dd99617f91ae 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/no_wrap.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-extensions=SPV_KHR_no_integer_wrap_decoration %s -o - | FileCheck %s
 
 ; CHECK-DAG: OpExtension "SPV_KHR_no_integer_wrap_decoration"
 

diff  --git a/llvm/test/CodeGen/SPIRV/optnone.ll b/llvm/test/CodeGen/SPIRV/optnone.ll
deleted file mode 100644
index 238a8193173745b..000000000000000
--- a/llvm/test/CodeGen/SPIRV/optnone.ll
+++ /dev/null
@@ -1,17 +0,0 @@
-;; Check that optnone is correctly ignored when extension is not enabled
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
-
-; CHECK-SPIRV: OpCapability OptNoneINTEL
-; CHECK-SPIRV: OpExtension "SPV_INTEL_optnone"
-
-;; Per SPIR-V spec:
-;; FunctionControlDontInlineMask = 0x2 (2)
-; CHECK-SPIRV: %[[#]] = OpFunction %[[#]] DontInline
-
-; Function Attrs: nounwind optnone noinline
-define spir_func void @_Z3foov() #0 {
-entry:
-  ret void
-}
-
-attributes #0 = { nounwind optnone noinline }

diff  --git a/llvm/test/CodeGen/SPIRV/transcoding/NoSignedUnsignedWrap.ll b/llvm/test/CodeGen/SPIRV/transcoding/NoSignedUnsignedWrap.ll
index 5a67dc2599421de..02d1250399f9fcc 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/NoSignedUnsignedWrap.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/NoSignedUnsignedWrap.ll
@@ -7,7 +7,7 @@
 ;;
 ;; Positive tests:
 ;;
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-NEGATIVE
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-extensions=SPV_KHR_no_integer_wrap_decoration %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-NEGATIVE
 ;;
 ;; Negative tests:
 ;;


        


More information about the llvm-commits mailing list