Skip to content

Commit f6fe3ec

Browse files
wenju-hejsji
authored andcommitted
Translate nonsemantic attribute and metadata of GlobalVariable (#2944)
Motivations is similar as f729c49. This PR addresses SYCL device global which may have attributes "sycl-device-image-scope", "sycl-host-access" and "sycl-unique-id". Failure to preserve "sycl-unique-id" after llvm-spirv translation triggers assert at https://github.com/intel/llvm/blob/2824f61dd36790448a224cd596985bd01cbcd0f3/llvm/lib/SYCLLowerIR/DeviceGlobals.cpp#L85 Also preserve GlobalVariable metadata as an improvement, though there is no test to show this is really needed. Original commit: KhronosGroup/SPIRV-LLVM-Translator@f2d913cb1a22cb3
1 parent 81e5cee commit f6fe3ec

File tree

7 files changed

+165
-37
lines changed

7 files changed

+165
-37
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5209,36 +5209,53 @@ void SPIRVToLLVM::transAuxDataInst(SPIRVExtInst *BC) {
52095209
return;
52105210
auto Args = BC->getArguments();
52115211
// Args 0 and 1 are common between attributes and metadata.
5212-
// 0 is the function, 1 is the name of the attribute/metadata as a string
5213-
auto *SpvFcn = BC->getModule()->getValue(Args[0]);
5214-
auto *F = static_cast<Function *>(getTranslatedValue(SpvFcn));
5215-
assert(F && "Function should already have been translated!");
5212+
// 0 is the global object, 1 is the name of the attribute/metadata as a string
5213+
auto *Arg0 = BC->getModule()->getValue(Args[0]);
5214+
auto *GO = cast<GlobalObject>(getTranslatedValue(Arg0));
5215+
auto *F = dyn_cast<Function>(GO);
5216+
auto *GV = dyn_cast<GlobalVariable>(GO);
5217+
assert((F || GV) && "Value should already have been translated!");
52165218
auto AttrOrMDName = BC->getModule()->get<SPIRVString>(Args[1])->getStr();
52175219
switch (BC->getExtOp()) {
5218-
case NonSemanticAuxData::FunctionAttribute: {
5220+
case NonSemanticAuxData::FunctionAttribute:
5221+
case NonSemanticAuxData::GlobalVariableAttribute: {
52195222
assert(Args.size() < 4 && "Unexpected FunctionAttribute Args");
52205223
// If this attr was specially handled and added elsewhere, skip it.
52215224
Attribute::AttrKind AsKind = Attribute::getAttrKindFromName(AttrOrMDName);
5222-
if (AsKind != Attribute::None && F->hasFnAttribute(AsKind))
5223-
return;
5224-
if (AsKind == Attribute::None && F->hasFnAttribute(AttrOrMDName))
5225-
return;
5225+
if (AsKind != Attribute::None)
5226+
if ((F && F->hasFnAttribute(AsKind)) || (GV && GV->hasAttribute(AsKind)))
5227+
return;
5228+
if (AsKind == Attribute::None)
5229+
if ((F && F->hasFnAttribute(AttrOrMDName)) ||
5230+
(GV && GV->hasAttribute(AttrOrMDName)))
5231+
return;
52265232
// For attributes, arg 2 is the attribute value as a string, which may not
52275233
// exist.
52285234
if (Args.size() == 3) {
52295235
auto AttrValue = BC->getModule()->get<SPIRVString>(Args[2])->getStr();
5230-
F->addFnAttr(AttrOrMDName, AttrValue);
5231-
} else {
5232-
if (AsKind != Attribute::None)
5233-
F->addFnAttr(AsKind);
5236+
if (F)
5237+
F->addFnAttr(AttrOrMDName, AttrValue);
52345238
else
5235-
F->addFnAttr(AttrOrMDName);
5239+
GV->addAttribute(AttrOrMDName, AttrValue);
5240+
} else {
5241+
if (AsKind != Attribute::None) {
5242+
if (F)
5243+
F->addFnAttr(AsKind);
5244+
else
5245+
GV->addAttribute(AsKind);
5246+
} else {
5247+
if (F)
5248+
F->addFnAttr(AttrOrMDName);
5249+
else
5250+
GV->addAttribute(AttrOrMDName);
5251+
}
52365252
}
52375253
break;
52385254
}
5239-
case NonSemanticAuxData::FunctionMetadata: {
5255+
case NonSemanticAuxData::FunctionMetadata:
5256+
case NonSemanticAuxData::GlobalVariableMetadata: {
52405257
// If this metadata was specially handled and added elsewhere, skip it.
5241-
if (F->hasMetadata(AttrOrMDName))
5258+
if (GO->hasMetadata(AttrOrMDName))
52425259
return;
52435260
SmallVector<Metadata *> MetadataArgs;
52445261
// Process the metadata values.
@@ -5248,14 +5265,14 @@ void SPIRVToLLVM::transAuxDataInst(SPIRVExtInst *BC) {
52485265
if (Arg->getOpCode() == OpString) {
52495266
auto *ArgAsStr = static_cast<SPIRVString *>(Arg);
52505267
MetadataArgs.push_back(
5251-
MDString::get(F->getContext(), ArgAsStr->getStr()));
5268+
MDString::get(GO->getContext(), ArgAsStr->getStr()));
52525269
} else {
52535270
auto *ArgAsVal = static_cast<SPIRVValue *>(Arg);
5254-
auto *TranslatedMD = transValue(ArgAsVal, F, nullptr);
5271+
auto *TranslatedMD = transValue(ArgAsVal, nullptr, nullptr);
52555272
MetadataArgs.push_back(ValueAsMetadata::get(TranslatedMD));
52565273
}
52575274
}
5258-
F->setMetadata(AttrOrMDName, MDNode::get(*Context, MetadataArgs));
5275+
GO->setMetadata(AttrOrMDName, MDNode::get(*Context, MetadataArgs));
52595276
break;
52605277
}
52615278
default:

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,23 +1230,27 @@ void LLVMToSPIRVBase::transFunctionMetadataAsUserSemanticDecoration(
12301230
}
12311231
}
12321232

1233-
void LLVMToSPIRVBase::transAuxDataInst(SPIRVFunction *BF, Function *F) {
1234-
auto *BM = BF->getModule();
1233+
void LLVMToSPIRVBase::transAuxDataInst(SPIRVValue *BV, Value *V) {
1234+
auto *GO = cast<GlobalObject>(V);
1235+
auto *F = dyn_cast<Function>(GO);
1236+
auto *GV = dyn_cast<GlobalVariable>(GO);
1237+
assert((F || GV) && "Invalid value type");
1238+
auto *BM = BV->getModule();
12351239
if (!BM->preserveAuxData())
12361240
return;
12371241
if (!BM->isAllowedToUseVersion(VersionNumber::SPIRV_1_6))
12381242
BM->addExtension(SPIRV::ExtensionID::SPV_KHR_non_semantic_info);
12391243
else
12401244
BM->setMinSPIRVVersion(VersionNumber::SPIRV_1_6);
1241-
const auto &FnAttrs = F->getAttributes().getFnAttrs();
1242-
for (const auto &Attr : FnAttrs) {
1245+
const auto &Attrs = F ? F->getAttributes().getFnAttrs() : GV->getAttributes();
1246+
for (const auto &Attr : Attrs) {
12431247
std::vector<SPIRVWord> Ops;
1244-
Ops.push_back(BF->getId());
1248+
Ops.push_back(BV->getId());
12451249
if (Attr.isStringAttribute()) {
12461250
// Format for String attributes is:
1247-
// NonSemanticAuxDataFunctionAttribute Fcn AttrName AttrValue
1251+
// NonSemanticAuxData*Attribute ValueName AttrName AttrValue
12481252
// or, if no value:
1249-
// NonSemanticAuxDataFunctionAttribute Fcn AttrName
1253+
// NonSemanticAuxData*Attribute ValueName AttrName
12501254
//
12511255
// AttrName and AttrValue are always Strings
12521256
StringRef AttrKind = Attr.getKindAsString();
@@ -1259,19 +1263,20 @@ void LLVMToSPIRVBase::transAuxDataInst(SPIRVFunction *BF, Function *F) {
12591263
}
12601264
} else {
12611265
// Format for other types is:
1262-
// NonSemanticAuxDataFunctionAttribute Fcn AttrStr
1266+
// NonSemanticAuxData*Attribute ValueName AttrStr
12631267
// AttrStr is always a String.
12641268
std::string AttrStr = Attr.getAsString();
12651269
auto *AttrSpvString = BM->getString(AttrStr);
12661270
Ops.push_back(AttrSpvString->getId());
12671271
}
1268-
BM->addAuxData(NonSemanticAuxData::FunctionAttribute,
1269-
transType(Type::getVoidTy(F->getContext())), Ops);
1272+
BM->addAuxData(F ? NonSemanticAuxData::FunctionAttribute
1273+
: NonSemanticAuxData::GlobalVariableAttribute,
1274+
transType(Type::getVoidTy(V->getContext())), Ops);
12701275
}
12711276
SmallVector<std::pair<unsigned, MDNode *>> AllMD;
12721277
SmallVector<StringRef> MDNames;
1273-
F->getContext().getMDKindNames(MDNames);
1274-
F->getAllMetadata(AllMD);
1278+
V->getContext().getMDKindNames(MDNames);
1279+
GO->getAllMetadata(AllMD);
12751280
for (const auto &MD : AllMD) {
12761281
std::string MDName = MDNames[MD.first].str();
12771282

@@ -1284,11 +1289,11 @@ void LLVMToSPIRVBase::transAuxDataInst(SPIRVFunction *BF, Function *F) {
12841289
continue;
12851290

12861291
// Format for metadata is:
1287-
// NonSemanticAuxDataFunctionMetadata Fcn MDName MDVals...
1292+
// NonSemanticAuxData*Metadata ValueName MDName MDVals...
12881293
// MDName is always a String, MDVals have different types as explained
12891294
// below. Also note this instruction has a variable number of operands
12901295
std::vector<SPIRVWord> Ops;
1291-
Ops.push_back(BF->getId());
1296+
Ops.push_back(BV->getId());
12921297
Ops.push_back(BM->getString(MDName)->getId());
12931298
for (unsigned int OpIdx = 0; OpIdx < MD.second->getNumOperands(); OpIdx++) {
12941299
const auto &CurOp = MD.second->getOperand(OpIdx);
@@ -1304,8 +1309,9 @@ void LLVMToSPIRVBase::transAuxDataInst(SPIRVFunction *BF, Function *F) {
13041309
assert(false && "Unsupported metadata type");
13051310
}
13061311
}
1307-
BM->addAuxData(NonSemanticAuxData::FunctionMetadata,
1308-
transType(Type::getVoidTy(F->getContext())), Ops);
1312+
BM->addAuxData(F ? NonSemanticAuxData::FunctionMetadata
1313+
: NonSemanticAuxData::GlobalVariableMetadata,
1314+
transType(Type::getVoidTy(V->getContext())), Ops);
13091315
}
13101316
}
13111317

@@ -2023,6 +2029,7 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
20232029
if (ST && ST->hasName() && isSPIRVConstantName(ST->getName())) {
20242030
auto *BV = transConstant(Init);
20252031
assert(BV);
2032+
transAuxDataInst(BV, V);
20262033
return mapValue(V, BV);
20272034
}
20282035
if (isa_and_nonnull<ConstantExpr>(Init)) {
@@ -2122,6 +2129,8 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
21222129
GV->getAttribute(kVCMetadata::VCSingleElementVector), BVar);
21232130
}
21242131

2132+
transAuxDataInst(BVar, V);
2133+
21252134
mapValue(V, BVar);
21262135
spv::BuiltIn Builtin = spv::BuiltInPosition;
21272136
if (!GV->hasName() || !getSPIRVBuiltin(GV->getName().str(), Builtin))

llvm-spirv/lib/SPIRV/SPIRVWriter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class LLVMToSPIRVBase : protected BuiltinCallHelper {
138138
void transFunctionMetadataAsExecutionMode(SPIRVFunction *BF, Function *F);
139139
void transFunctionMetadataAsUserSemanticDecoration(SPIRVFunction *BF,
140140
Function *F);
141-
void transAuxDataInst(SPIRVFunction *BF, Function *F);
141+
void transAuxDataInst(SPIRVValue *BV, Value *V);
142142

143143
bool transGlobalVariables();
144144

llvm-spirv/lib/SPIRV/libSPIRV/NonSemantic.AuxData.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace NonSemanticAuxData {
2828
enum Instruction {
2929
FunctionMetadata = 0,
3030
FunctionAttribute = 1,
31-
PreserveCount = 2
31+
GlobalVariableMetadata = 2,
32+
GlobalVariableAttribute = 3
3233
};
3334
} // namespace NonSemanticAuxData

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVExtInst.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ inline void SPIRVMap<NonSemanticAuxDataOpKind, std::string>::init() {
278278
"NonSemanticAuxDataFunctionMetadata");
279279
add(NonSemanticAuxData::FunctionAttribute,
280280
"NonSemanticAuxDataFunctionAttribute");
281+
add(NonSemanticAuxData::GlobalVariableMetadata,
282+
"NonSemanticAuxDataGlobalVariableMetadata");
283+
add(NonSemanticAuxData::GlobalVariableAttribute,
284+
"NonSemanticAuxDataGlobalVariableAttribute");
281285
}
282286
SPIRV_DEF_NAMEMAP(NonSemanticAuxDataOpKind, NonSemanticAuxDataOpMap)
283287

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
; RUN: llvm-as < %s -o %t.bc
2+
; RUN: not llvm-spirv %t.bc -spirv-text --spirv-preserve-auxdata --spirv-max-version=1.5 --spirv-ext=-SPV_KHR_non_semantic_info,+SPV_INTEL_global_variable_decorations -o - 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-EXT-DISABLED
3+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-preserve-auxdata --spirv-max-version=1.5 --spirv-ext=+SPV_INTEL_global_variable_decorations
4+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-EXT
5+
; RUN: llvm-spirv -r --spirv-preserve-auxdata %t.spv -o %t.rev.bc
6+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
7+
; RUN: llvm-spirv -r %t.spv -o %t.rev.without.bc
8+
; RUN: llvm-dis %t.rev.without.bc -o - | FileCheck %s --implicit-check-not="{{foo|bar|baz}}"
9+
10+
; RUN: llvm-spirv %t.bc -spirv-text --spirv-preserve-auxdata --spirv-ext=+SPV_KHR_non_semantic_info,+SPV_INTEL_global_variable_decorations -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-NOEXT
11+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-preserve-auxdata --spirv-ext=+SPV_INTEL_global_variable_decorations
12+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-NOEXT
13+
; RUN: llvm-spirv -r --spirv-preserve-auxdata %t.spv -o %t.rev.bc
14+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
15+
; RUN: llvm-spirv -r %t.spv -o %t.rev.without.bc
16+
; RUN: llvm-dis %t.rev.without.bc -o - | FileCheck %s --implicit-check-not="{{foo|bar|baz}}"
17+
18+
; Check SPIR-V versions in a format magic number + version
19+
; CHECK-SPIRV-EXT: 119734787 65536
20+
; CHECK-SPIRV-EXT: Extension "SPV_KHR_non_semantic_info"
21+
; CHECK-SPIRV-NOEXT: 119734787 67072
22+
23+
; CHECK-SPIRV: ExtInstImport [[#Import:]] "NonSemantic.AuxData"
24+
25+
; CHECK-SPIRV: String [[#Attr0LHS:]] "sycl-device-global-size"
26+
; CHECK-SPIRV: String [[#Attr0RHS:]] "32"
27+
; CHECK-SPIRV: String [[#Attr1:]] "sycl-device-image-scope"
28+
; CHECK-SPIRV: String [[#Attr2LHS:]] "sycl-host-access"
29+
; CHECK-SPIRV: String [[#Attr2RHS:]] "0"
30+
; CHECK-SPIRV: String [[#Attr3LHS:]] "sycl-unique-id"
31+
; CHECK-SPIRV: String [[#Attr3RHS:]] "_Z20__AsanKernelMetadata"
32+
33+
; CHECK-SPIRV: Name [[#GVName:]] "__AsanKernelMetadata"
34+
35+
; CHECK-SPIRV: TypeVoid [[#VoidT:]]
36+
37+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#Attr0Inst:]] [[#Import]] NonSemanticAuxDataGlobalVariableAttribute [[#GVName]] [[#Attr0LHS]] [[#Attr0RHS]] {{$}}
38+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#Attr1Inst:]] [[#Import]] NonSemanticAuxDataGlobalVariableAttribute [[#GVName]] [[#Attr1]] {{$}}
39+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#Attr1Inst:]] [[#Import]] NonSemanticAuxDataGlobalVariableAttribute [[#GVName]] [[#Attr2LHS]] [[#Attr2RHS]] {{$}}
40+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#Attr1Inst:]] [[#Import]] NonSemanticAuxDataGlobalVariableAttribute [[#GVName]] [[#Attr3LHS]] [[#Attr3RHS]] {{$}}
41+
42+
target triple = "spir64-unknown-unknown"
43+
44+
; CHECK-LLVM: @__AsanKernelMetadata = addrspace(1) global [1 x %structtype] [%structtype { i64 0, i64 92 }] #[[#GVIRAttr:]]
45+
%structtype = type { i64, i64 }
46+
47+
@__AsanKernelMetadata = addrspace(1) global [1 x %structtype] [%structtype { i64 ptrtoint (ptr addrspace(2) null to i64), i64 92 }], !spirv.Decorations !0 #0
48+
49+
; CHECK-LLVM: attributes #[[#GVIRAttr]] = { "sycl-device-global-size"="32" "sycl-device-image-scope" "sycl-host-access"="0" "sycl-unique-id"="_Z20__AsanKernelMetadata" }
50+
attributes #0 = { "sycl-device-global-size"="32" "sycl-device-image-scope" "sycl-host-access"="0" "sycl-unique-id"="_Z20__AsanKernelMetadata" }
51+
52+
!0 = !{!1}
53+
!1 = !{i32 6147, i32 0, !"_Z20__AsanKernelMetadata"}
54+
55+
; CHECK-SPIRV-EXT-DISABLED: RequiresExtension: Feature requires the following SPIR-V extension:
56+
; CHECK-SPIRV-EXT-DISABLED-NEXT: SPV_KHR_non_semantic_info
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: llvm-as < %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-preserve-auxdata --spirv-max-version=1.5
3+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-EXT
4+
; RUN: llvm-spirv -r --spirv-preserve-auxdata %t.spv -o %t.rev.bc
5+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.without.bc
7+
; RUN: llvm-dis %t.rev.without.bc -o - | FileCheck %s --implicit-check-not="{{foo|bar|baz}}"
8+
9+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-preserve-auxdata
10+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-NOEXT
11+
; RUN: llvm-spirv -r --spirv-preserve-auxdata %t.spv -o %t.rev.bc
12+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
13+
; RUN: llvm-spirv -r %t.spv -o %t.rev.without.bc
14+
; RUN: llvm-dis %t.rev.without.bc -o - | FileCheck %s --implicit-check-not="{{foo|bar|baz}}"
15+
16+
; Check SPIR-V versions in a format magic number + version
17+
; CHECK-SPIRV-EXT: 119734787 65536
18+
; CHECK-SPIRV-EXT: Extension "SPV_KHR_non_semantic_info"
19+
; CHECK-SPIRV-NOEXT: 119734787 67072
20+
21+
; CHECK-SPIRV: ExtInstImport [[#Import:]] "NonSemantic.AuxData"
22+
23+
; CHECK-SPIRV: String [[#MDName:]] "absolute_symbol"
24+
25+
; CHECK-SPIRV: Name [[#GVName:]] "a"
26+
27+
; CHECK-SPIRV: TypeInt [[#Int32T:]] 64 0
28+
; CHECK-SPIRV: Constant [[#Int32T]] [[#MDValue0:]] 0
29+
; CHECK-SPIRV: Constant [[#Int32T]] [[#MDValue1:]] 16
30+
31+
; CHECK-SPIRV: TypeVoid [[#VoidT:]]
32+
33+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#ValInst:]] [[#Import]] NonSemanticAuxDataGlobalVariableMetadata [[#GVName]] [[#MDName]] [[#MDValue0]] [[#MDValue1]] {{$}}
34+
35+
target triple = "spir64-unknown-unknown"
36+
37+
; CHECK-LLVM: @a = external addrspace(1) global i8, !absolute_symbol ![[#LLVMVal:]]
38+
@a = external addrspace(1) global i8, !absolute_symbol !0
39+
40+
; CHECK-LLVM: ![[#LLVMVal]] = !{i64 0, i64 16}
41+
!0 = !{i64 0, i64 16}

0 commit comments

Comments
 (0)