Skip to content

Commit

Permalink
[SPIR-V] Reland SPV_KHR_untyped_pointers commits (#15507)
Browse files Browse the repository at this point in the history
They were reverted in pulldown PR #15464 because of the regressions.
Don't use this extension in the SYCL tests as the extension is not fully
implemented yet.

Commits:

KhronosGroup/SPIRV-LLVM-Translator@7dacb7cdedc9c01

KhronosGroup/SPIRV-LLVM-Translator@484e4070adb0a95
  • Loading branch information
vmaksimo authored Oct 2, 2024
1 parent e58e17b commit ce0dc32
Show file tree
Hide file tree
Showing 29 changed files with 696 additions and 124 deletions.
1 change: 1 addition & 0 deletions llvm-spirv/include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ EXT(SPV_KHR_subgroup_rotate)
EXT(SPV_KHR_non_semantic_info)
EXT(SPV_KHR_shader_clock)
EXT(SPV_KHR_cooperative_matrix)
EXT(SPV_KHR_untyped_pointers)
EXT(SPV_INTEL_subgroups)
EXT(SPV_INTEL_media_block_io)
EXT(SPV_INTEL_device_side_avc_motion_estimation)
Expand Down
31 changes: 23 additions & 8 deletions llvm-spirv/lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ Type *SPIRVToLLVM::transType(SPIRVType *T, bool UseTPT) {
return TypedPointerType::get(ElementTy, AS);
return mapType(T, PointerType::get(ElementTy, AS));
}
case OpTypeUntypedPointerKHR: {
const unsigned AS =
SPIRSPIRVAddrSpaceMap::rmap(T->getPointerStorageClass());
return mapType(T, PointerType::get(*Context, AS));
}
case OpTypeVector:
return mapType(T,
FixedVectorType::get(transType(T->getVectorComponentType()),
Expand Down Expand Up @@ -560,6 +565,8 @@ std::string SPIRVToLLVM::transTypeToOCLTypeName(SPIRVType *T, bool IsSigned) {
}
return transTypeToOCLTypeName(ET) + "*";
}
case OpTypeUntypedPointerKHR:
return "int*";
case OpTypeVector:
return transTypeToOCLTypeName(T->getVectorComponentType()) +
T->getVectorComponentCount();
Expand Down Expand Up @@ -1522,9 +1529,15 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
case OpUndef:
return mapValue(BV, UndefValue::get(transType(BV->getType())));

case OpVariable: {
auto *BVar = static_cast<SPIRVVariable *>(BV);
auto *PreTransTy = BVar->getType()->getPointerElementType();
case OpVariable:
case OpUntypedVariableKHR: {
auto *BVar = static_cast<SPIRVVariableBase *>(BV);
SPIRVType *PreTransTy = BVar->getType()->getPointerElementType();
if (BVar->getType()->isTypeUntypedPointerKHR()) {
auto *UntypedVar = static_cast<SPIRVUntypedVariableKHR *>(BVar);
if (SPIRVType *DT = UntypedVar->getDataType())
PreTransTy = DT;
}
auto *Ty = transType(PreTransTy);
bool IsConst = BVar->isConstant();
llvm::GlobalValue::LinkageTypes LinkageTy = transLinkageType(BVar);
Expand Down Expand Up @@ -4055,7 +4068,7 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
return true;
}

void SPIRVToLLVM::transGlobalCtorDtors(SPIRVVariable *BV) {
void SPIRVToLLVM::transGlobalCtorDtors(SPIRVVariableBase *BV) {
if (BV->getName() != "llvm.global_ctors" &&
BV->getName() != "llvm.global_dtors")
return;
Expand Down Expand Up @@ -4900,15 +4913,17 @@ SPIRVToLLVM::transLinkageType(const SPIRVValue *V) {
return GlobalValue::ExternalLinkage;
}
// Variable declaration
if (V->getOpCode() == OpVariable) {
if (static_cast<const SPIRVVariable *>(V)->getInitializer() == 0)
if (V->getOpCode() == OpVariable ||
V->getOpCode() == OpUntypedVariableKHR) {
if (static_cast<const SPIRVVariableBase *>(V)->getInitializer() == 0)
return GlobalValue::ExternalLinkage;
}
// Definition
return GlobalValue::AvailableExternallyLinkage;
case LinkageTypeExport:
if (V->getOpCode() == OpVariable) {
if (static_cast<const SPIRVVariable *>(V)->getInitializer() == 0)
if (V->getOpCode() == OpVariable ||
V->getOpCode() == OpUntypedVariableKHR) {
if (static_cast<const SPIRVVariableBase *>(V)->getInitializer() == 0)
// Tentative definition
return GlobalValue::CommonLinkage;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm-spirv/lib/SPIRV/SPIRVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class SPIRVToLLVM : private BuiltinCallHelper {

void transUserSemantic(SPIRV::SPIRVFunction *Fun);
void transGlobalAnnotations();
void transGlobalCtorDtors(SPIRVVariable *BV);
void transGlobalCtorDtors(SPIRVVariableBase *BV);
void createCXXStructor(const char *ListName,
SmallVectorImpl<Function *> &Funcs);
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
Expand Down
117 changes: 81 additions & 36 deletions llvm-spirv/lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,8 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
// A pointer to image or pipe type in LLVM is translated to a SPIRV
// (non-pointer) image or pipe type.
if (T->isPointerTy()) {
auto *ET = Type::getInt8Ty(T->getContext());
auto AddrSpc = T->getPointerAddressSpace();
auto *ET = Type::getInt8Ty(T->getContext());
return transPointerType(ET, AddrSpc);
}

Expand Down Expand Up @@ -720,7 +720,6 @@ SPIRVType *LLVMToSPIRVBase::transPointerType(Type *ET, unsigned AddrSpc) {
transType(ET)));
}
} else {
SPIRVType *ElementType = transType(ET);
// ET, as a recursive type, may contain exactly the same pointer T, so it
// may happen that after translation of ET we already have translated T,
// added the translated pointer to the SPIR-V module and mapped T to this
Expand All @@ -729,7 +728,17 @@ SPIRVType *LLVMToSPIRVBase::transPointerType(Type *ET, unsigned AddrSpc) {
if (Loc != PointeeTypeMap.end()) {
return Loc->second;
}
SPIRVType *TranslatedTy = transPointerType(ElementType, AddrSpc);

SPIRVType *ElementType = nullptr;
SPIRVType *TranslatedTy = nullptr;
if (ET->isPointerTy() &&
BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_untyped_pointers)) {
TranslatedTy = BM->addUntypedPointerKHRType(
SPIRSPIRVAddrSpaceMap::map(static_cast<SPIRAddressSpace>(AddrSpc)));
} else {
ElementType = transType(ET);
TranslatedTy = transPointerType(ElementType, AddrSpc);
}
PointeeTypeMap[TypeKey] = TranslatedTy;
return TranslatedTy;
}
Expand All @@ -744,8 +753,16 @@ SPIRVType *LLVMToSPIRVBase::transPointerType(SPIRVType *ET, unsigned AddrSpc) {
if (Loc != PointeeTypeMap.end())
return Loc->second;

SPIRVType *TranslatedTy = BM->addPointerType(
SPIRSPIRVAddrSpaceMap::map(static_cast<SPIRAddressSpace>(AddrSpc)), ET);
SPIRVType *TranslatedTy = nullptr;
if (BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_untyped_pointers) &&
!(ET->isTypeArray() || ET->isTypeVector() || ET->isTypeStruct() ||
ET->isTypeImage() || ET->isTypeSampler() || ET->isTypePipe())) {
TranslatedTy = BM->addUntypedPointerKHRType(
SPIRSPIRVAddrSpaceMap::map(static_cast<SPIRAddressSpace>(AddrSpc)));
} else {
TranslatedTy = BM->addPointerType(
SPIRSPIRVAddrSpaceMap::map(static_cast<SPIRAddressSpace>(AddrSpc)), ET);
}
PointeeTypeMap[TypeKey] = TranslatedTy;
return TranslatedTy;
}
Expand Down Expand Up @@ -1312,7 +1329,8 @@ SPIRVValue *LLVMToSPIRVBase::transConstantUse(Constant *C,
if (Trans->getType() == ExpectedType || Trans->getType()->isTypePipeStorage())
return Trans;

assert(C->getType()->isPointerTy() &&
assert((C->getType()->isPointerTy() ||
ExpectedType->isTypeUntypedPointerKHR()) &&
"Only pointer type mismatches should be possible");
// In the common case of strings ([N x i8] GVs), see if we can emit a GEP
// instruction.
Expand Down Expand Up @@ -2050,8 +2068,12 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
}
}
}
SPIRVType *TransTy = transType(Ty);
BVarInit = transConstantUse(Init, TransTy->getPointerElementType());
if (BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_untyped_pointers)) {
BVarInit = transConstantUse(Init, transType(Init->getType()));
} else {
SPIRVType *TransTy = transType(Ty);
BVarInit = transConstantUse(Init, TransTy->getPointerElementType());
}
}

SPIRVStorageClassKind StorageClass;
Expand Down Expand Up @@ -2084,9 +2106,12 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
}

SPIRVType *TranslatedTy = transType(Ty);
auto *BVar = static_cast<SPIRVVariable *>(
BM->addVariable(TranslatedTy, GV->isConstant(), transLinkageType(GV),
BVarInit, GV->getName().str(), StorageClass, nullptr));
auto *BVar = static_cast<SPIRVVariableBase *>(BM->addVariable(
TranslatedTy,
TranslatedTy->isTypeUntypedPointerKHR() ? transType(GV->getValueType())
: nullptr,
GV->isConstant(), transLinkageType(GV), BVarInit, GV->getName().str(),
StorageClass, nullptr));

if (IsVectorCompute) {
BVar->addDecorate(DecorationVectorComputeVariableINTEL);
Expand Down Expand Up @@ -2196,8 +2221,13 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
MemoryAccessNoAliasINTELMaskMask);
if (MemoryAccess.front() == 0)
MemoryAccess.clear();
return mapValue(V, BM->addLoadInst(transValue(LD->getPointerOperand(), BB),
MemoryAccess, BB));
return mapValue(
V,
BM->addLoadInst(
transValue(LD->getPointerOperand(), BB), MemoryAccess, BB,
BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_untyped_pointers)
? transType(LD->getType())
: nullptr));
}

if (BinaryOperator *B = dyn_cast<BinaryOperator>(V)) {
Expand Down Expand Up @@ -2270,8 +2300,9 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
StorageClassFunction,
BM->addArrayType(transType(Alc->getAllocatedType()), Length));
SPIRVValue *Arr = BM->addVariable(
AllocationType, false, spv::internal::LinkageTypeInternal, nullptr,
Alc->getName().str() + "_alloca", StorageClassFunction, BB);
AllocationType, nullptr, false, spv::internal::LinkageTypeInternal,
nullptr, Alc->getName().str() + "_alloca", StorageClassFunction,
BB);
// Manually set alignment. OpBitcast created below will be decorated as
// that's the SPIR-V value mapped to the original LLVM one.
transAlign(Alc, Arr);
Expand All @@ -2295,7 +2326,10 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
TranslatedTy->getPointerElementType())
: TranslatedTy;
SPIRVValue *Var = BM->addVariable(
VarTy, false, spv::internal::LinkageTypeInternal, nullptr,
VarTy,
VarTy->isTypeUntypedPointerKHR() ? transType(Alc->getAllocatedType())
: nullptr,
false, spv::internal::LinkageTypeInternal, nullptr,
Alc->getName().str(), StorageClassFunction, BB);
if (V->getType()->getPointerAddressSpace() == SPIRAS_Generic) {
SPIRVValue *Cast =
Expand Down Expand Up @@ -2407,14 +2441,17 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,

if (auto *Phi = dyn_cast<PHINode>(V)) {
std::vector<SPIRVValue *> IncomingPairs;
SPIRVType *Ty = transScavengedType(Phi);

for (size_t I = 0, E = Phi->getNumIncomingValues(); I != E; ++I) {
IncomingPairs.push_back(transValue(Phi->getIncomingValue(I), BB, true,
FuncTransMode::Pointer));
SPIRVValue *Val = transValue(Phi->getIncomingValue(I), BB, true,
FuncTransMode::Pointer);
if (Val->getType() != Ty)
Val = BM->addUnaryInst(OpBitcast, Ty, Val, BB);
IncomingPairs.push_back(Val);
IncomingPairs.push_back(transValue(Phi->getIncomingBlock(I), nullptr));
}
return mapValue(V,
BM->addPhiInst(transScavengedType(Phi), IncomingPairs, BB));
return mapValue(V, BM->addPhiInst(Ty, IncomingPairs, BB));
}

if (auto *Ext = dyn_cast<ExtractValueInst>(V)) {
Expand Down Expand Up @@ -2737,7 +2774,7 @@ void checkIsGlobalVar(SPIRVEntry *E, Decoration Dec) {
E->getErrorLog().checkError(E->isVariable(), SPIRVEC_InvalidModule, ErrStr);

auto AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(
static_cast<SPIRVVariable *>(E)->getStorageClass());
static_cast<SPIRVVariableBase *>(E)->getStorageClass());
ErrStr += " in a global (module) scope";
E->getErrorLog().checkError(AddrSpace == SPIRAS_Global, SPIRVEC_InvalidModule,
ErrStr);
Expand Down Expand Up @@ -2885,10 +2922,11 @@ static void transMetadataDecorations(Metadata *MD, SPIRVValue *Target) {
case spv::internal::DecorationInitModeINTEL:
case DecorationInitModeINTEL: {
checkIsGlobalVar(Target, DecoKind);
ErrLog.checkError(static_cast<SPIRVVariable *>(Target)->getInitializer(),
SPIRVEC_InvalidLlvmModule,
"InitModeINTEL only be applied to a global (module "
"scope) variable which has an Initializer operand");
ErrLog.checkError(
static_cast<SPIRVVariableBase *>(Target)->getInitializer(),
SPIRVEC_InvalidLlvmModule,
"InitModeINTEL only be applied to a global (module "
"scope) variable which has an Initializer operand");

ErrLog.checkError(NumOperands == 2, SPIRVEC_InvalidLlvmModule,
"InitModeINTEL requires exactly 1 extra operand");
Expand Down Expand Up @@ -4130,14 +4168,18 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
SPIRVType *FTy = transType(II->getType()->getStructElementType(0));
SPIRVTypePointer *ITy = static_cast<SPIRVTypePointer *>(transPointerType(
II->getType()->getStructElementType(1), SPIRAS_Private));

unsigned BitWidth = ITy->getElementType()->getBitWidth();
BM->getErrorLog().checkError(BitWidth == 32, SPIRVEC_InvalidBitWidth,
std::to_string(BitWidth));

if (!ITy->isTypeUntypedPointerKHR()) {
unsigned BitWidth = ITy->getElementType()->getBitWidth();
BM->getErrorLog().checkError(BitWidth == 32, SPIRVEC_InvalidBitWidth,
std::to_string(BitWidth));
}
SPIRVValue *IntVal =
BM->addVariable(ITy, false, spv::internal::LinkageTypeInternal, nullptr,
"", ITy->getStorageClass(), BB);
BM->addVariable(ITy,
ITy->isTypeUntypedPointerKHR()
? transType(II->getType()->getStructElementType(1))
: nullptr,
false, spv::internal::LinkageTypeInternal, nullptr, "",
ITy->getStorageClass(), BB);

std::vector<SPIRVValue *> Ops{transValue(II->getArgOperand(0), BB), IntVal};

Expand Down Expand Up @@ -4559,7 +4601,7 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
Init = BM->addCompositeConstant(CompositeTy, Elts);
}
SPIRVType *VarTy = transPointerType(AT, SPIRV::SPIRAS_Constant);
SPIRVValue *Var = BM->addVariable(VarTy, /*isConstant*/ true,
SPIRVValue *Var = BM->addVariable(VarTy, nullptr, /*isConstant*/ true,
spv::internal::LinkageTypeInternal, Init,
"", StorageClassUniformConstant, nullptr);
SPIRVType *SourceTy =
Expand Down Expand Up @@ -6671,9 +6713,12 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
assert((Pointee == Args[I] || !isa<Function>(Pointee)) &&
"Illegal use of a function pointer type");
}
SPArgs.push_back(SPI->isOperandLiteral(I)
? cast<ConstantInt>(Args[I])->getZExtValue()
: transValue(Args[I], BB)->getId());
if (!SPI->isOperandLiteral(I)) {
SPIRVValue *Val = transValue(Args[I], BB);
SPArgs.push_back(Val->getId());
} else {
SPArgs.push_back(cast<ConstantInt>(Args[I])->getZExtValue());
}
}
BM->addInstTemplate(SPI, SPArgs, BB, SPRetTy);
if (!SPRetTy || !SPRetTy->isTypeStruct())
Expand Down
2 changes: 1 addition & 1 deletion llvm-spirv/lib/SPIRV/libSPIRV/SPIRVBasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ SPIRVInstruction *SPIRVBasicBlock::getVariableInsertionPoint() const {
isa<OpNoLine>(Inst) ||
// Note: OpVariable and OpPhi instructions do not belong to the
// same block in a valid SPIR-V module.
isa<OpPhi>(Inst));
isa<OpPhi>(Inst) || isa<OpUntypedVariableKHR>(Inst));
});
if (IP == InstVec.end())
return nullptr;
Expand Down
4 changes: 2 additions & 2 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVBasicBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ class SPIRVBasicBlock : public SPIRVValue {
const SPIRVInstruction *getTerminateInstr() const {
return InstVec.empty() ? nullptr : InstVec.back();
}
// OpVariable instructions must be the first instructions in the block,
// Variables must be the first instructions in the block,
// intermixed with OpLine and OpNoLine instructions. Return first instruction
// not being an OpVariable, OpLine or OpNoLine.
// not being an OpVariable, OpUntypedVariableKHR, OpLine or OpNoLine.
SPIRVInstruction *getVariableInsertionPoint() const;

void setScope(SPIRVEntry *Scope) override;
Expand Down
3 changes: 2 additions & 1 deletion llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,8 @@ SPIRVEntry::getDecorationIds(Decoration Kind) const {
}

bool SPIRVEntry::hasLinkageType() const {
return OpCode == OpFunction || OpCode == OpVariable;
return OpCode == OpFunction || OpCode == OpVariable ||
OpCode == OpUntypedVariableKHR;
}

bool SPIRVEntry::isExtInst(const SPIRVExtInstSetKind InstSet) const {
Expand Down
4 changes: 3 additions & 1 deletion llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,9 @@ class SPIRVEntry {
bool isUndef() const { return OpCode == OpUndef; }
bool isControlBarrier() const { return OpCode == OpControlBarrier; }
bool isMemoryBarrier() const { return OpCode == OpMemoryBarrier; }
bool isVariable() const { return OpCode == OpVariable; }
bool isVariable() const {
return OpCode == OpVariable || OpCode == OpUntypedVariableKHR;
}
bool isEndOfBlock() const;
virtual bool isInst() const { return false; }
virtual bool isOperandLiteral(unsigned Index) const {
Expand Down
Loading

0 comments on commit ce0dc32

Please sign in to comment.