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] Add Float16 support when targeting Vulkan #77115

Merged
merged 4 commits into from
Jan 12, 2024

Conversation

sudonatalie
Copy link
Member

@sudonatalie sudonatalie commented Jan 5, 2024

Add Float16 to Vulkan's available capabilities, and guard Float16Buffer (Kernel-only capability) against being added outside OpenCL environments.

Add tests to verify half and half vector types, and validate with spirv-val.

Fixes #66398

Add Float16 to Vulkan's available capabilities, and guard Float16Buffer
(Kernel-only capability) against being added outside OpenCL
environments.

Add tests to verify half and half vector types, and validate with
spirv-val.
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 5, 2024

@llvm/pr-subscribers-backend-spir-v

Author: Natalie Chouinard (sudonatalie)

Changes

Add Float16 to Vulkan's available capabilities, and guard Float16Buffer (Kernel-only capability) against being added outside OpenCL environments.

Add tests to verify half and half vector types, and validate with spirv-val.


Full diff: https://github.com/llvm/llvm-project/pull/77115.diff

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp (+6-4)
  • (modified) llvm/test/CodeGen/SPIRV/basic_float_types.ll (+22)
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 2a830535a2aa13..2222241d51b2e6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -597,8 +597,9 @@ void RequirementHandler::initAvailableCapabilitiesForVulkan(
     const SPIRVSubtarget &ST) {
   addAvailableCaps({Capability::Shader, Capability::Linkage});
 
-  // Provided by Vulkan version 1.0.
-  addAvailableCaps({Capability::Int16, Capability::Int64, Capability::Float64});
+  // Provided by all supported Vulkan versions.
+  addAvailableCaps({Capability::Int16, Capability::Int64, Capability::Float16,
+                    Capability::Float64});
 }
 
 } // namespace SPIRV
@@ -733,11 +734,12 @@ void addInstrRequirements(const MachineInstr &MI,
     auto SC = MI.getOperand(1).getImm();
     Reqs.getAndAddRequirements(SPIRV::OperandCategory::StorageClassOperand, SC,
                                ST);
-    // If it's a type of pointer to float16, add Float16Buffer capability.
+    // If it's a type of pointer to float16 targeting OpenCL, add Float16Buffer
+    // capability.
     assert(MI.getOperand(2).isReg());
     const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
     SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(2).getReg());
-    if (TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
+    if (ST.isOpenCLEnv() && TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
         TypeDef->getOperand(1).getImm() == 16)
       Reqs.addCapability(SPIRV::Capability::Float16Buffer);
     break;
diff --git a/llvm/test/CodeGen/SPIRV/basic_float_types.ll b/llvm/test/CodeGen/SPIRV/basic_float_types.ll
index 4287adc85cfd84..8d2641b6a34f0e 100644
--- a/llvm/test/CodeGen/SPIRV/basic_float_types.ll
+++ b/llvm/test/CodeGen/SPIRV/basic_float_types.ll
@@ -1,12 +1,18 @@
 ; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
 ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
 ; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 define void @main() {
 entry:
+; CHECK-DAG:     %[[#half:]] = OpTypeFloat 16
 ; CHECK-DAG:    %[[#float:]] = OpTypeFloat 32
 ; CHECK-DAG:   %[[#double:]] = OpTypeFloat 64
 
+; CHECK-DAG:   %[[#v2half:]] = OpTypeVector %[[#half]] 2
+; CHECK-DAG:   %[[#v3half:]] = OpTypeVector %[[#half]] 3
+; CHECK-DAG:   %[[#v4half:]] = OpTypeVector %[[#half]] 4
+
 ; CHECK-DAG:  %[[#v2float:]] = OpTypeVector %[[#float]] 2
 ; CHECK-DAG:  %[[#v3float:]] = OpTypeVector %[[#float]] 3
 ; CHECK-DAG:  %[[#v4float:]] = OpTypeVector %[[#float]] 4
@@ -15,8 +21,12 @@ entry:
 ; CHECK-DAG: %[[#v3double:]] = OpTypeVector %[[#double]] 3
 ; CHECK-DAG: %[[#v4double:]] = OpTypeVector %[[#double]] 4
 
+; CHECK-DAG:     %[[#ptr_Function_half:]] = OpTypePointer Function %[[#half]]
 ; CHECK-DAG:    %[[#ptr_Function_float:]] = OpTypePointer Function %[[#float]]
 ; CHECK-DAG:   %[[#ptr_Function_double:]] = OpTypePointer Function %[[#double]]
+; CHECK-DAG:   %[[#ptr_Function_v2half:]] = OpTypePointer Function %[[#v2half]]
+; CHECK-DAG:   %[[#ptr_Function_v3half:]] = OpTypePointer Function %[[#v3half]]
+; CHECK-DAG:   %[[#ptr_Function_v4half:]] = OpTypePointer Function %[[#v4half]]
 ; CHECK-DAG:  %[[#ptr_Function_v2float:]] = OpTypePointer Function %[[#v2float]]
 ; CHECK-DAG:  %[[#ptr_Function_v3float:]] = OpTypePointer Function %[[#v3float]]
 ; CHECK-DAG:  %[[#ptr_Function_v4float:]] = OpTypePointer Function %[[#v4float]]
@@ -24,12 +34,24 @@ entry:
 ; CHECK-DAG: %[[#ptr_Function_v3double:]] = OpTypePointer Function %[[#v3double]]
 ; CHECK-DAG: %[[#ptr_Function_v4double:]] = OpTypePointer Function %[[#v4double]]
 
+; CHECK: %[[#]] = OpVariable %[[#ptr_Function_half]] Function
+  %half_Val = alloca half, align 2
+
 ; CHECK: %[[#]] = OpVariable %[[#ptr_Function_float]] Function
   %float_Val = alloca float, align 4
 
 ; CHECK: %[[#]] = OpVariable %[[#ptr_Function_double]] Function
   %double_Val = alloca double, align 8
 
+; CHECK: %[[#]] = OpVariable %[[#ptr_Function_v2half]] Function
+  %half2_Val = alloca <2 x half>, align 4
+
+; CHECK: %[[#]] = OpVariable %[[#ptr_Function_v3half]] Function
+  %half3_Val = alloca <3 x half>, align 8
+
+; CHECK: %[[#]] = OpVariable %[[#ptr_Function_v4half]] Function
+  %half4_Val = alloca <4 x half>, align 8
+
 ; CHECK: %[[#]] = OpVariable %[[#ptr_Function_v2float]] Function
   %float2_Val = alloca <2 x float>, align 8
 

Comment on lines 734 to 740
if (!ST.isOpenCLEnv())
break;
auto SC = MI.getOperand(1).getImm();
Reqs.getAndAddRequirements(SPIRV::OperandCategory::StorageClassOperand, SC,
ST);
// If it's a type of pointer to float16, add Float16Buffer capability.
// If it's a type of pointer to float16 targeting OpenCL, add Float16Buffer
// capability.
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm... it looks like you don't want to execute these lines for Vulkan:

auto SC = MI.getOperand(1).getImm();
Reqs.getAndAddRequirements(SPIRV::OperandCategory::StorageClassOperand, SC, ST);

however, in the previous patch, you were going to disable only the code after the comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, good catch, fixed!

Copy link
Contributor

@iliya-diyachkov iliya-diyachkov left a comment

Choose a reason for hiding this comment

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

The changes look good to me.

@sudonatalie sudonatalie merged commit 4f47372 into llvm:main Jan 12, 2024
5 checks passed
@sudonatalie sudonatalie deleted the half branch January 12, 2024 15:03
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
Add Float16 to Vulkan's available capabilities, and guard Float16Buffer
(Kernel-only capability) against being added outside OpenCL
environments.

Add tests to verify half and half vector types, and validate with
spirv-val.

Fixes llvm#66398
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SPIRV] Implement and test half type from HLSL
5 participants