-
Notifications
You must be signed in to change notification settings - Fork 12.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SPIR-V] Cast ptr kernel args to i8* when used as Store's value opera…
…nd (#78603) Handle a special case when StoreInst's value operand is a kernel argument of a pointer type. Since these arguments could have either a basic element type (e.g. float*) or OpenCL builtin type (sampler_t), bitcast the StoreInst's value operand to default pointer element type (i8). This pull request addresses the issue #72864
- Loading branch information
1 parent
07dfa61
commit 0fbaf03
Showing
9 changed files
with
219 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
//===--- SPIRVMetadata.cpp ---- IR Metadata Parsing Funcs -------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains functions needed for parsing LLVM IR metadata relevant | ||
// to the SPIR-V target. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "SPIRVMetadata.h" | ||
|
||
using namespace llvm; | ||
|
||
static MDString *getOCLKernelArgAttribute(const Function &F, unsigned ArgIdx, | ||
const StringRef AttributeName) { | ||
assert( | ||
F.getCallingConv() == CallingConv::SPIR_KERNEL && | ||
"Kernel attributes are attached/belong only to OpenCL kernel functions"); | ||
|
||
// Lookup the argument attribute in metadata attached to the kernel function. | ||
MDNode *Node = F.getMetadata(AttributeName); | ||
if (Node && ArgIdx < Node->getNumOperands()) | ||
return cast<MDString>(Node->getOperand(ArgIdx)); | ||
|
||
// Sometimes metadata containing kernel attributes is not attached to the | ||
// function, but can be found in the named module-level metadata instead. | ||
// For example: | ||
// !opencl.kernels = !{!0} | ||
// !0 = !{void ()* @someKernelFunction, !1, ...} | ||
// !1 = !{!"kernel_arg_addr_space", ...} | ||
// In this case the actual index of searched argument attribute is ArgIdx + 1, | ||
// since the first metadata node operand is occupied by attribute name | ||
// ("kernel_arg_addr_space" in the example above). | ||
unsigned MDArgIdx = ArgIdx + 1; | ||
NamedMDNode *OpenCLKernelsMD = | ||
F.getParent()->getNamedMetadata("opencl.kernels"); | ||
if (!OpenCLKernelsMD || OpenCLKernelsMD->getNumOperands() == 0) | ||
return nullptr; | ||
|
||
// KernelToMDNodeList contains kernel function declarations followed by | ||
// corresponding MDNodes for each attribute. Search only MDNodes "belonging" | ||
// to the currently lowered kernel function. | ||
MDNode *KernelToMDNodeList = OpenCLKernelsMD->getOperand(0); | ||
bool FoundLoweredKernelFunction = false; | ||
for (const MDOperand &Operand : KernelToMDNodeList->operands()) { | ||
ValueAsMetadata *MaybeValue = dyn_cast<ValueAsMetadata>(Operand); | ||
if (MaybeValue && | ||
dyn_cast<Function>(MaybeValue->getValue())->getName() == F.getName()) { | ||
FoundLoweredKernelFunction = true; | ||
continue; | ||
} | ||
if (MaybeValue && FoundLoweredKernelFunction) | ||
return nullptr; | ||
|
||
MDNode *MaybeNode = dyn_cast<MDNode>(Operand); | ||
if (FoundLoweredKernelFunction && MaybeNode && | ||
cast<MDString>(MaybeNode->getOperand(0))->getString() == | ||
AttributeName && | ||
MDArgIdx < MaybeNode->getNumOperands()) | ||
return cast<MDString>(MaybeNode->getOperand(MDArgIdx)); | ||
} | ||
return nullptr; | ||
} | ||
|
||
namespace llvm { | ||
|
||
MDString *getOCLKernelArgAccessQual(const Function &F, unsigned ArgIdx) { | ||
assert( | ||
F.getCallingConv() == CallingConv::SPIR_KERNEL && | ||
"Kernel attributes are attached/belong only to OpenCL kernel functions"); | ||
return getOCLKernelArgAttribute(F, ArgIdx, "kernel_arg_access_qual"); | ||
} | ||
|
||
MDString *getOCLKernelArgTypeQual(const Function &F, unsigned ArgIdx) { | ||
assert( | ||
F.getCallingConv() == CallingConv::SPIR_KERNEL && | ||
"Kernel attributes are attached/belong only to OpenCL kernel functions"); | ||
return getOCLKernelArgAttribute(F, ArgIdx, "kernel_arg_type_qual"); | ||
} | ||
|
||
MDString *getOCLKernelArgType(const Function &F, unsigned ArgIdx) { | ||
assert( | ||
F.getCallingConv() == CallingConv::SPIR_KERNEL && | ||
"Kernel attributes are attached/belong only to OpenCL kernel functions"); | ||
return getOCLKernelArgAttribute(F, ArgIdx, "kernel_arg_type"); | ||
} | ||
|
||
} // namespace llvm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
//===--- SPIRVMetadata.h ---- IR Metadata Parsing Funcs ---------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains functions needed for parsing LLVM IR metadata relevant | ||
// to the SPIR-V target. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVMETADATA_H | ||
#define LLVM_LIB_TARGET_SPIRV_SPIRVMETADATA_H | ||
|
||
#include "llvm/IR/Metadata.h" | ||
#include "llvm/IR/Module.h" | ||
|
||
namespace llvm { | ||
|
||
//===----------------------------------------------------------------------===// | ||
// OpenCL Metadata | ||
// | ||
|
||
MDString *getOCLKernelArgAccessQual(const Function &F, unsigned ArgIdx); | ||
MDString *getOCLKernelArgTypeQual(const Function &F, unsigned ArgIdx); | ||
MDString *getOCLKernelArgType(const Function &F, unsigned ArgIdx); | ||
|
||
} // namespace llvm | ||
#endif // LLVM_LIB_TARGET_SPIRV_METADATA_H |
11 changes: 11 additions & 0 deletions
11
llvm/test/CodeGen/SPIRV/pointers/kernel-argument-ptr-i8-default-element-type.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s | ||
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} | ||
|
||
; CHECK-DAG: %[[#CHAR:]] = OpTypeInt 8 | ||
; CHECK-DAG: %[[#GLOBAL_PTR_CHAR:]] = OpTypePointer CrossWorkgroup %[[#CHAR]] | ||
|
||
define spir_kernel void @foo(ptr addrspace(1) %arg) { | ||
ret void | ||
} | ||
|
||
; CHECK: %[[#]] = OpFunctionParameter %[[#GLOBAL_PTR_CHAR]] |
14 changes: 14 additions & 0 deletions
14
llvm/test/CodeGen/SPIRV/pointers/kernel-argument-ptr-no-bitcast.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s | ||
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} | ||
|
||
; CHECK-DAG: %[[#CHAR:]] = OpTypeInt 8 | ||
; CHECK-DAG: %[[#GLOBAL_PTR_CHAR:]] = OpTypePointer CrossWorkgroup %[[#CHAR]] | ||
|
||
define spir_kernel void @foo(i8 %a, ptr addrspace(1) %p) { | ||
store i8 %a, ptr addrspace(1) %p | ||
ret void | ||
} | ||
|
||
; CHECK: %[[#A:]] = OpFunctionParameter %[[#CHAR]] | ||
; CHECK: %[[#P:]] = OpFunctionParameter %[[#GLOBAL_PTR_CHAR]] | ||
; CHECK: OpStore %[[#P]] %[[#A]] |
18 changes: 18 additions & 0 deletions
18
llvm/test/CodeGen/SPIRV/pointers/store-kernel-arg-i8-ptr-as-value-operand.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s | ||
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} | ||
|
||
; CHECK-DAG: %[[#CHAR:]] = OpTypeInt 8 | ||
; CHECK-DAG: %[[#GLOBAL_PTR_CHAR:]] = OpTypePointer CrossWorkgroup %[[#CHAR]] | ||
|
||
define spir_kernel void @foo(ptr addrspace(1) %arg) !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 { | ||
%var = alloca ptr addrspace(1), align 8 | ||
; CHECK: %[[#]] = OpFunctionParameter %[[#GLOBAL_PTR_CHAR]] | ||
; CHECK-NOT: %[[#]] = OpBitcast %[[#]] %[[#]] | ||
store ptr addrspace(1) %arg, ptr %var, align 8 | ||
ret void | ||
} | ||
|
||
!1 = !{i32 1} | ||
!2 = !{!"none"} | ||
!3 = !{!"char*"} | ||
!4 = !{!""} |
19 changes: 19 additions & 0 deletions
19
llvm/test/CodeGen/SPIRV/pointers/store-kernel-arg-ptr-as-value-operand.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s | ||
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} | ||
|
||
define spir_kernel void @foo(ptr addrspace(1) %arg) !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 { | ||
%var = alloca ptr addrspace(1), align 8 | ||
; CHECK: %[[#VAR:]] = OpVariable %[[#]] Function | ||
store ptr addrspace(1) %arg, ptr %var, align 8 | ||
; The test itends to verify that OpStore uses OpVariable result directly (without a bitcast). | ||
; Other type checking is done by spirv-val. | ||
; CHECK: OpStore %[[#VAR]] %[[#]] Aligned 8 | ||
%lod = load ptr addrspace(1), ptr %var, align 8 | ||
%idx = getelementptr inbounds i64, ptr addrspace(1) %lod, i64 0 | ||
ret void | ||
} | ||
|
||
!1 = !{i32 1} | ||
!2 = !{!"none"} | ||
!3 = !{!"ulong*"} | ||
!4 = !{!""} |