Skip to content

Commit f2d913c

Browse files
authored
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.
1 parent b33ca8d commit f2d913c

File tree

7 files changed

+165
-37
lines changed

7 files changed

+165
-37
lines changed

lib/SPIRV/SPIRVReader.cpp

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5176,36 +5176,53 @@ void SPIRVToLLVM::transAuxDataInst(SPIRVExtInst *BC) {
51765176
return;
51775177
auto Args = BC->getArguments();
51785178
// Args 0 and 1 are common between attributes and metadata.
5179-
// 0 is the function, 1 is the name of the attribute/metadata as a string
5180-
auto *SpvFcn = BC->getModule()->getValue(Args[0]);
5181-
auto *F = static_cast<Function *>(getTranslatedValue(SpvFcn));
5182-
assert(F && "Function should already have been translated!");
5179+
// 0 is the global object, 1 is the name of the attribute/metadata as a string
5180+
auto *Arg0 = BC->getModule()->getValue(Args[0]);
5181+
auto *GO = cast<GlobalObject>(getTranslatedValue(Arg0));
5182+
auto *F = dyn_cast<Function>(GO);
5183+
auto *GV = dyn_cast<GlobalVariable>(GO);
5184+
assert((F || GV) && "Value should already have been translated!");
51835185
auto AttrOrMDName = BC->getModule()->get<SPIRVString>(Args[1])->getStr();
51845186
switch (BC->getExtOp()) {
5185-
case NonSemanticAuxData::FunctionAttribute: {
5187+
case NonSemanticAuxData::FunctionAttribute:
5188+
case NonSemanticAuxData::GlobalVariableAttribute: {
51865189
assert(Args.size() < 4 && "Unexpected FunctionAttribute Args");
51875190
// If this attr was specially handled and added elsewhere, skip it.
51885191
Attribute::AttrKind AsKind = Attribute::getAttrKindFromName(AttrOrMDName);
5189-
if (AsKind != Attribute::None && F->hasFnAttribute(AsKind))
5190-
return;
5191-
if (AsKind == Attribute::None && F->hasFnAttribute(AttrOrMDName))
5192-
return;
5192+
if (AsKind != Attribute::None)
5193+
if ((F && F->hasFnAttribute(AsKind)) || (GV && GV->hasAttribute(AsKind)))
5194+
return;
5195+
if (AsKind == Attribute::None)
5196+
if ((F && F->hasFnAttribute(AttrOrMDName)) ||
5197+
(GV && GV->hasAttribute(AttrOrMDName)))
5198+
return;
51935199
// For attributes, arg 2 is the attribute value as a string, which may not
51945200
// exist.
51955201
if (Args.size() == 3) {
51965202
auto AttrValue = BC->getModule()->get<SPIRVString>(Args[2])->getStr();
5197-
F->addFnAttr(AttrOrMDName, AttrValue);
5198-
} else {
5199-
if (AsKind != Attribute::None)
5200-
F->addFnAttr(AsKind);
5203+
if (F)
5204+
F->addFnAttr(AttrOrMDName, AttrValue);
52015205
else
5202-
F->addFnAttr(AttrOrMDName);
5206+
GV->addAttribute(AttrOrMDName, AttrValue);
5207+
} else {
5208+
if (AsKind != Attribute::None) {
5209+
if (F)
5210+
F->addFnAttr(AsKind);
5211+
else
5212+
GV->addAttribute(AsKind);
5213+
} else {
5214+
if (F)
5215+
F->addFnAttr(AttrOrMDName);
5216+
else
5217+
GV->addAttribute(AttrOrMDName);
5218+
}
52035219
}
52045220
break;
52055221
}
5206-
case NonSemanticAuxData::FunctionMetadata: {
5222+
case NonSemanticAuxData::FunctionMetadata:
5223+
case NonSemanticAuxData::GlobalVariableMetadata: {
52075224
// If this metadata was specially handled and added elsewhere, skip it.
5208-
if (F->hasMetadata(AttrOrMDName))
5225+
if (GO->hasMetadata(AttrOrMDName))
52095226
return;
52105227
SmallVector<Metadata *> MetadataArgs;
52115228
// Process the metadata values.
@@ -5215,14 +5232,14 @@ void SPIRVToLLVM::transAuxDataInst(SPIRVExtInst *BC) {
52155232
if (Arg->getOpCode() == OpString) {
52165233
auto *ArgAsStr = static_cast<SPIRVString *>(Arg);
52175234
MetadataArgs.push_back(
5218-
MDString::get(F->getContext(), ArgAsStr->getStr()));
5235+
MDString::get(GO->getContext(), ArgAsStr->getStr()));
52195236
} else {
52205237
auto *ArgAsVal = static_cast<SPIRVValue *>(Arg);
5221-
auto *TranslatedMD = transValue(ArgAsVal, F, nullptr);
5238+
auto *TranslatedMD = transValue(ArgAsVal, nullptr, nullptr);
52225239
MetadataArgs.push_back(ValueAsMetadata::get(TranslatedMD));
52235240
}
52245241
}
5225-
F->setMetadata(AttrOrMDName, MDNode::get(*Context, MetadataArgs));
5242+
GO->setMetadata(AttrOrMDName, MDNode::get(*Context, MetadataArgs));
52265243
break;
52275244
}
52285245
default:

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

@@ -2028,6 +2034,7 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
20282034
if (ST && ST->hasName() && isSPIRVConstantName(ST->getName())) {
20292035
auto *BV = transConstant(Init);
20302036
assert(BV);
2037+
transAuxDataInst(BV, V);
20312038
return mapValue(V, BV);
20322039
}
20332040
if (isa_and_nonnull<ConstantExpr>(Init)) {
@@ -2127,6 +2134,8 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
21272134
GV->getAttribute(kVCMetadata::VCSingleElementVector), BVar);
21282135
}
21292136

2137+
transAuxDataInst(BVar, V);
2138+
21302139
mapValue(V, BVar);
21312140
spv::BuiltIn Builtin = spv::BuiltInPosition;
21322141
if (!GV->hasName() || !getSPIRVBuiltin(GV->getName().str(), Builtin))

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

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

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)