Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIR-V] Support SPV_INTEL_arbitrary_precision_integers extension #250

Draft
wants to merge 3 commits into
base: feature/spirv-backend-llvm15_0_7
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 9 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am considering extracting generating all instructions relevant to extensions (decorations, capabilities, etc.) out to a separate pass. I will prepare a an experimental pull request.

If it works out, I will consider extracting emitting capabilities also to a separate pass. Then SPIRVModuleAnalysis would truly be "analysis only" pass.

Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,12 @@ void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
// TODO: verify if this needs some checks.
addAvailableCaps({Capability::Float16, Capability::Float64});

// Add capabilities enabled by extensions.
for (auto Extension : ST.getAllAvailableExtensions()) {
CapabilityList EnabledCapabilities =
getCapabilitiesEnabledByExtension(Extension);
addAvailableCaps(EnabledCapabilities);
}
// TODO: add OpenCL extensions.
}
} // namespace SPIRV
Expand Down
21 changes: 17 additions & 4 deletions llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ 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_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;
Expand Down Expand Up @@ -90,14 +103,14 @@ 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.
AvailableExtensions.insert(
SPIRV::Extension::SPV_KHR_no_integer_wrap_decoration);

for (auto Extension : Extensions) {
AvailableExtensions.insert(Extension);
}
}

// TODO: use command line args for this rather than just defaults.
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,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;

Expand Down Expand Up @@ -106,6 +110,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

Expand Down
52 changes: 52 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -243,6 +249,51 @@ 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_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>;

//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
Expand Down Expand Up @@ -396,6 +447,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]>;

//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
;;
Expand Down