Skip to content

Commit 2800b4b

Browse files
MochalovaAnvladimirlaz
authored andcommitted
Support UserSemantic decoration on functions (#666)
Added support of SPIR-V -> LLVM IR translation for UserSemantic decoration applied to functions. Having that decoration on functions is against SPIR-V spec, but it is useful for prototyping different features: you can easily propagate custom annotation string through SPIR-V to see if your idea works or not without adding new code to the translator Signed-off-by: amochalo <[email protected]>
1 parent ed7d999 commit 2800b4b

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3244,7 +3244,6 @@ bool SPIRVToLLVM::translate() {
32443244
if (BV->getStorageClass() != StorageClassFunction)
32453245
transValue(BV, nullptr, nullptr);
32463246
}
3247-
transGlobalAnnotations();
32483247

32493248
// Compile unit might be needed during translation of debug intrinsics.
32503249
for (SPIRVExtInst *EI : BM->getDebugInstVec()) {
@@ -3263,8 +3262,11 @@ bool SPIRVToLLVM::translate() {
32633262

32643263
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
32653264
transFunction(BM->getFunction(I));
3265+
transUserSemantic(BM->getFunction(I));
32663266
}
32673267

3268+
transGlobalAnnotations();
3269+
32683270
if (!transMetadata())
32693271
return false;
32703272
if (!transFPContractMetadata())
@@ -3528,6 +3530,38 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) {
35283530
}
35293531
}
35303532

3533+
// Having UserSemantic decoration on Function is against the spec, but we allow
3534+
// this for various purposes (like prototyping new features when we need to
3535+
// attach some information on function and propagate that through SPIR-V and
3536+
// ect.)
3537+
void SPIRVToLLVM::transUserSemantic(SPIRV::SPIRVFunction *Fun) {
3538+
auto TransFun = transFunction(Fun);
3539+
for (auto UsSem : Fun->getDecorationStringLiteral(DecorationUserSemantic)) {
3540+
auto V = cast<Value>(TransFun);
3541+
Constant *StrConstant =
3542+
ConstantDataArray::getString(*Context, StringRef(UsSem));
3543+
auto *GS = new GlobalVariable(
3544+
*TransFun->getParent(), StrConstant->getType(),
3545+
/*IsConstant*/ true, GlobalValue::PrivateLinkage, StrConstant, "");
3546+
3547+
GS->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
3548+
GS->setSection("llvm.metadata");
3549+
3550+
Type *ResType = PointerType::getInt8PtrTy(
3551+
V->getContext(), V->getType()->getPointerAddressSpace());
3552+
Constant *C =
3553+
ConstantExpr::getPointerBitCastOrAddrSpaceCast(TransFun, ResType);
3554+
3555+
Type *Int8PtrTyPrivate = Type::getInt8PtrTy(*Context, SPIRAS_Private);
3556+
IntegerType *Int32Ty = Type::getInt32Ty(*Context);
3557+
3558+
llvm::Constant *Fields[4] = {
3559+
C, ConstantExpr::getBitCast(GS, Int8PtrTyPrivate),
3560+
UndefValue::get(Int8PtrTyPrivate), UndefValue::get(Int32Ty)};
3561+
GlobalAnnotations.push_back(ConstantStruct::getAnon(Fields));
3562+
}
3563+
}
3564+
35313565
void SPIRVToLLVM::transGlobalAnnotations() {
35323566
if (!GlobalAnnotations.empty()) {
35333567
Constant *Array =

llvm-spirv/lib/SPIRV/SPIRVReader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class SPIRVToLLVM {
267267
Instruction *transOCLAllAny(SPIRVInstruction *BI, BasicBlock *BB);
268268
Instruction *transOCLRelational(SPIRVInstruction *BI, BasicBlock *BB);
269269

270+
void transUserSemantic(SPIRV::SPIRVFunction *Fun);
270271
void transGlobalAnnotations();
271272
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
272273
}; // class SPIRVToLLVM
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
;RUN: llvm-as %s -o %t.bc
2+
;RUN: llvm-spirv %t.bc -o %t.spv
3+
;RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
4+
;RUN: llvm-spirv -r %t.spv -o %t.rev.bc
5+
;RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
6+
7+
;CHECK-SPIRV: Decorate {{[0-9]+}} UserSemantic "annotation_on_function"
8+
9+
;CHECK-LLVM: @0 = private unnamed_addr constant [23 x i8] c"annotation_on_function\00", section "llvm.metadata"
10+
;CHECK-LLVM: @llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (void ()* @foo to i8*), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @0, i32 0, i32 0), i8* undef, i32 undef }], section "llvm.metadata"
11+
12+
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"
13+
target triple = "spir64-unknown-linux-sycldevice"
14+
15+
@.str = private unnamed_addr constant [23 x i8] c"annotation_on_function\00", section "llvm.metadata"
16+
@.str.1 = private unnamed_addr constant [6 x i8] c"an.cl\00", section "llvm.metadata"
17+
@llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (void ()* @foo to i8*), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 2 }], section "llvm.metadata"
18+
19+
; Function Attrs: convergent norecurse nounwind
20+
define dso_local spir_func void @foo() #0 {
21+
entry:
22+
ret void
23+
}
24+
25+
attributes #0 = { convergent norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
26+
27+
!llvm.module.flags = !{!0}
28+
!opencl.ocl.version = !{!1}
29+
!opencl.spir.version = !{!2, !2}
30+
!spirv.Source = !{!3}
31+
!llvm.ident = !{!4}
32+
33+
!0 = !{i32 1, !"wchar_size", i32 4}
34+
!1 = !{i32 1, i32 0}
35+
!2 = !{i32 1, i32 2}
36+
!3 = !{i32 4, i32 100000}
37+
!4 = !{!"clang version 12.0.0 (https://github.com/c199914007/llvm.git 074e97d48896b959dfc832e2f1dd806796cde390)"}

0 commit comments

Comments
 (0)