Skip to content

Commit

Permalink
Translate function attributes (incl. parameter attrs) for entry point…
Browse files Browse the repository at this point in the history
… kernels

Original commit: KhronosGroup/SPIRV-LLVM-Translator@aded5af
  • Loading branch information
vmaksimo committed Jul 4, 2024
1 parent 86aa271 commit f5f4cc5
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 50 deletions.
98 changes: 55 additions & 43 deletions llvm-spirv/lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2970,12 +2970,65 @@ bool SPIRVToLLVM::foreachFuncCtlMask(SourceTy Source, FuncTy Func) {
return true;
}

void SPIRVToLLVM::transFunctionAttrs(SPIRVFunction *BF, Function *F) {
if (BF->hasDecorate(DecorationReferencedIndirectlyINTEL))
F->addFnAttr("referenced-indirectly");
if (isFuncNoUnwind())
F->addFnAttr(Attribute::NoUnwind);
foreachFuncCtlMask(BF, [&](Attribute::AttrKind Attr) { F->addFnAttr(Attr); });

for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
++I) {
auto *BA = BF->getArgument(I->getArgNo());
mapValue(BA, &(*I));
setName(&(*I), BA);
AttributeMask IllegalAttrs = AttributeFuncs::typeIncompatible(I->getType());
BA->foreachAttr([&](SPIRVFuncParamAttrKind Kind) {
// Skip this function parameter attribute as it will translated among
// OpenCL metadata
if (Kind == FunctionParameterAttributeRuntimeAlignedINTEL)
return;
Attribute::AttrKind LLVMKind = SPIRSPIRVFuncParamAttrMap::rmap(Kind);
if (IllegalAttrs.contains(LLVMKind))
return;
Type *AttrTy = nullptr;
switch (LLVMKind) {
case Attribute::AttrKind::ByVal:
case Attribute::AttrKind::StructRet:
AttrTy = transType(BA->getType()->getPointerElementType());
break;
default:
break; // do nothing
}
// Make sure to use a correct constructor for a typed/typeless attribute
auto A = AttrTy ? Attribute::get(*Context, LLVMKind, AttrTy)
: Attribute::get(*Context, LLVMKind);
I->addAttr(A);
});

AttrBuilder Builder(*Context);
SPIRVWord MaxOffset = 0;
if (BA->hasDecorate(DecorationMaxByteOffset, 0, &MaxOffset))
Builder.addDereferenceableAttr(MaxOffset);
SPIRVWord AlignmentBytes = 0;
if (BA->hasDecorate(DecorationAlignment, 0, &AlignmentBytes))
Builder.addAlignmentAttr(AlignmentBytes);
I->addAttrs(Builder);
}
BF->foreachReturnValueAttr([&](SPIRVFuncParamAttrKind Kind) {
if (Kind == FunctionParameterAttributeNoWrite)
return;
F->addRetAttr(SPIRSPIRVFuncParamAttrMap::rmap(Kind));
});
}

Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
auto Loc = FuncMap.find(BF);
if (Loc != FuncMap.end())
return Loc->second;

auto IsKernel = isKernel(BF);

if (IsKernel) {
// search for a previous function with the same name
// upgrade it to a kernel and drop this if it's found
Expand All @@ -2988,6 +3041,7 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
F->setDSOLocal(false);
F = cast<Function>(mapValue(BF, F));
mapFunction(BF, F);
transFunctionAttrs(BF, F);
return F;
}
}
Expand Down Expand Up @@ -3036,49 +3090,7 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) {

F->setCallingConv(IsKernel ? CallingConv::SPIR_KERNEL
: CallingConv::SPIR_FUNC);
if (BF->hasDecorate(DecorationReferencedIndirectlyINTEL))
F->addFnAttr("referenced-indirectly");
if (isFuncNoUnwind())
F->addFnAttr(Attribute::NoUnwind);
foreachFuncCtlMask(BF, [&](Attribute::AttrKind Attr) { F->addFnAttr(Attr); });

for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
++I) {
auto BA = BF->getArgument(I->getArgNo());
mapValue(BA, &(*I));
setName(&(*I), BA);
BA->foreachAttr([&](SPIRVFuncParamAttrKind Kind) {
Attribute::AttrKind LLVMKind = SPIRSPIRVFuncParamAttrMap::rmap(Kind);
Type *AttrTy = nullptr;
switch (LLVMKind) {
case Attribute::AttrKind::ByVal:
case Attribute::AttrKind::StructRet:
AttrTy = transType(BA->getType()->getPointerElementType());
break;
default:
break; // do nothing
}
// Make sure to use a correct constructor for a typed/typeless attribute
auto A = AttrTy ? Attribute::get(*Context, LLVMKind, AttrTy)
: Attribute::get(*Context, LLVMKind);
I->addAttr(A);
});

AttrBuilder Builder(*Context);
SPIRVWord MaxOffset = 0;
if (BA->hasDecorate(DecorationMaxByteOffset, 0, &MaxOffset))
Builder.addDereferenceableAttr(MaxOffset);
SPIRVWord AlignmentBytes = 0;
if (BA->hasDecorate(DecorationAlignment, 0, &AlignmentBytes))
Builder.addAlignmentAttr(AlignmentBytes);
I->addAttrs(Builder);
}
BF->foreachReturnValueAttr([&](SPIRVFuncParamAttrKind Kind) {
if (Kind == FunctionParameterAttributeNoWrite)
return;
F->addRetAttr(SPIRSPIRVFuncParamAttrMap::rmap(Kind));
});

transFunctionAttrs(BF, F);
// Creating all basic blocks before creating instructions.
for (size_t I = 0, E = BF->getNumBasicBlock(); I != E; ++I) {
transValue(BF->getBasicBlock(I), F, nullptr);
Expand Down
1 change: 1 addition & 0 deletions llvm-spirv/lib/SPIRV/SPIRVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class SPIRVToLLVM : private BuiltinCallHelper {
std::vector<Value *> transValue(const std::vector<SPIRVValue *> &,
Function *F, BasicBlock *);
Function *transFunction(SPIRVFunction *F);
void transFunctionAttrs(SPIRVFunction *BF, Function *F);
Value *transBlockInvoke(SPIRVValue *Invoke, BasicBlock *BB);
Instruction *transWGSizeQueryBI(SPIRVInstruction *BI, BasicBlock *BB);
Instruction *transSGSizeQueryBI(SPIRVInstruction *BI, BasicBlock *BB);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ entry:
; CHECK-SPIRV: Capability FPGAArgumentInterfacesINTEL
; CHECK-SPIRV: Extension "SPV_INTEL_fpga_argument_interfaces"
; CHECK-SPIRV: Extension "SPV_INTEL_fpga_buffer_location"
; CHECK-SPIRV-DAG: Name [[IDS:[0-9]+]] "_arg_p"
; CHECK-SPIRV-DAG: Name [[ID:[0-9]+]] "_arg_p"
; CHECK-SPIRV: Decorate [[ID]] Alignment 4
; CHECK-SPIRV: Decorate [[ID]] MMHostInterfaceAddressWidthINTEL 32
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
; XFAIL: *

; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv -spirv-ext=+SPV_INTEL_function_pointers -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv -spirv-ext=+SPV_INTEL_function_pointers %t.bc -o %t.spv
Expand Down Expand Up @@ -34,7 +32,7 @@ target triple = "spir64-unknown-unknown"

; CHECK-LLVM: define spir_func i32 @foo(i32 %x)

; CHECK-LLVM: define spir_func void @bar(ptr %y)
; CHECK-LLVM: define spir_kernel void @bar(ptr %y)
; CHECK-LLVM: [[PTRTOINT:%.*]] = ptrtoint ptr @foo to i64
; CHECK-LLVM: store i64 [[PTRTOINT]], ptr %y, align 8

Expand Down
2 changes: 0 additions & 2 deletions llvm-spirv/test/image.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
; XFAIL: *

; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv %t.bc -o %t.spv
Expand Down
2 changes: 1 addition & 1 deletion llvm-spirv/test/transcoding/kernel_arg_type_qual.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
target triple = "spir64-unknown-unknown."

; CHECK-SPIRV: String [[#]] "kernel_arg_type_qual.test.volatile,const,,"
; CHECK-SPIRV: Name [[ARG:[0-9]+]] "g"
; CHECK-SPIRV: Name [[ARG:1[0-9]+]] "g"
; CHECK-SPIRV: Decorate [[ARG]] Volatile
; CHECK-SPIRV-NEGATIVE-NOT: String [[#]] "kernel_arg_type_qual.test.volatile,const,,"

Expand Down
5 changes: 4 additions & 1 deletion llvm-spirv/test/transcoding/registerallocmode.ll
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
; CHECK-LLVM: @[[FLAG0:[0-9]+]] = private unnamed_addr constant [20 x i8] c"num-thread-per-eu 4\00", section "llvm.metadata"
; CHECK-LLVM: @[[FLAG1:[0-9]+]] = private unnamed_addr constant [20 x i8] c"num-thread-per-eu 8\00", section "llvm.metadata"
; CHECK-LLVM: @[[FLAG2:[0-9]+]] = private unnamed_addr constant [20 x i8] c"num-thread-per-eu 0\00", section "llvm.metadata"
; CHECK-LLVM: @[[FLAG3:[0-9]+]] = private unnamed_addr constant [20 x i8] c"num-thread-per-eu 4\00", section "llvm.metadata"
; CHECK-LLVM: @[[FLAG4:[0-9]+]] = private unnamed_addr constant [20 x i8] c"num-thread-per-eu 8\00", section "llvm.metadata"
; CHECK-LLVM: @[[FLAG5:[0-9]+]] = private unnamed_addr constant [20 x i8] c"num-thread-per-eu 0\00", section "llvm.metadata"

; CHECK-LLVM: @llvm.global.annotations = appending global [3 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @main_l3, ptr @[[FLAG0]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l6, ptr @[[FLAG1]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l9, ptr @[[FLAG2]], ptr undef, i32 undef, ptr undef }], section "llvm.metadata"
; CHECK-LLVM: @llvm.global.annotations = appending global [6 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @main_l3, ptr @[[FLAG0]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l6, ptr @[[FLAG1]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l9, ptr @[[FLAG2]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l3, ptr @[[FLAG3]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l6, ptr @[[FLAG4]], ptr undef, i32 undef, ptr undef }, { ptr, ptr, ptr, i32, ptr } { ptr @main_l9, ptr @[[FLAG5]], ptr undef, i32 undef, ptr undef }], section "llvm.metadata"

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir64"
Expand Down

0 comments on commit f5f4cc5

Please sign in to comment.