[SPIR-V] Add support for empty string (#4363)

Fixes #4360
This commit is contained in:
Greg Fischer 2022-05-03 11:19:27 -06:00 коммит произвёл GitHub
Родитель 21773f157c
Коммит b71bfeac6a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 46 добавлений и 10 удалений

Просмотреть файл

@ -754,6 +754,7 @@ public:
bool specConst = false);
SpirvConstant *getConstantNull(QualType);
SpirvString *createString(llvm::StringRef str);
SpirvString *getString(llvm::StringRef str);
const HybridPointerType *getPhysicalStorageBufferType(QualType pointee);
@ -855,8 +856,12 @@ private:
SpirvDebugExpression *nullDebugExpr;
// To avoid generating multiple OpStrings for the same string literal
// the SpirvBuilder will generate and reuse them.
// the SpirvBuilder will generate and reuse them. The empty string is
// kept track of separately. This is because the empty string is used
// as the EmptyKey and TombstoneKey for the map, prohibiting insertion
// of the empty string as a contained value.
llvm::DenseMap<llvm::StringRef, SpirvString *, StringMapInfo> stringLiterals;
SpirvString *emptyString;
/// Mapping of CTBuffers including matrix 1xN with FXC memory layout to their
/// clone variables. We need it to avoid multiple clone variables for the same

Просмотреть файл

@ -32,7 +32,7 @@ SpirvBuilder::SpirvBuilder(ASTContext &ac, SpirvContext &ctx,
mod(llvm::make_unique<SpirvModule>()), function(nullptr),
moduleInit(nullptr), moduleInitInsertPoint(nullptr), spirvOptions(opt),
builtinVars(), debugNone(nullptr), nullDebugExpr(nullptr),
stringLiterals() {}
stringLiterals(), emptyString(nullptr) {}
SpirvBuilder::SpirvBuilder(SpirvContext &ctx, const SpirvCodeGenOptions &opt,
FeatureManager &featureMg)
@ -40,7 +40,7 @@ SpirvBuilder::SpirvBuilder(SpirvContext &ctx, const SpirvCodeGenOptions &opt,
mod(llvm::make_unique<SpirvModule>()), function(nullptr),
moduleInit(nullptr), moduleInitInsertPoint(nullptr), spirvOptions(opt),
builtinVars(), debugNone(nullptr), nullDebugExpr(nullptr),
stringLiterals() {}
stringLiterals(), emptyString(nullptr) {}
SpirvFunction *SpirvBuilder::createSpirvFunction(QualType returnType,
SourceLocation loc,
@ -1708,20 +1708,31 @@ SpirvConstant *SpirvBuilder::getConstantNull(QualType type) {
return nullConst;
}
SpirvString *SpirvBuilder::getString(llvm::StringRef str) {
// Reuse an existing instruction if possible.
auto iter = stringLiterals.find(str.str());
if (iter != stringLiterals.end())
return iter->second;
SpirvString *SpirvBuilder::createString(llvm::StringRef str) {
// Create a SpirvString instruction
auto *instr = new (context) SpirvString(/* SourceLocation */ {}, str);
instr->setRValue();
stringLiterals[str.str()] = instr;
if (str.empty())
emptyString = instr;
else
stringLiterals[str.str()] = instr;
mod->addString(instr);
return instr;
}
SpirvString *SpirvBuilder::getString(llvm::StringRef str) {
// Reuse an existing instruction if possible.
if (str.empty()) {
if (emptyString)
return emptyString;
} else {
auto iter = stringLiterals.find(str.str());
if (iter != stringLiterals.end())
return iter->second;
}
return createString(str);
}
const HybridPointerType *
SpirvBuilder::getPhysicalStorageBufferType(QualType pointee) {
return context.getPointerType(pointee,

Просмотреть файл

@ -0,0 +1,16 @@
// RUN: %dxc -Wno-effects-syntax -E MainPs -T ps_6_0
string g_renderState_FillMode < string arg1 = "WIREFRAME" ; > = "" ;
struct PS_OUTPUT
{
float4 vColor0 : SV_Target0 ;
} ;
// CHECK: {{%\d+}} = OpString ""
PS_OUTPUT MainPs ( )
{
PS_OUTPUT o ;
o . vColor0 = float4( 0, 0, 0, 1 );
return o ;
}

Просмотреть файл

@ -1548,6 +1548,10 @@ TEST_F(FileTest, WaveOpNoTargetEnvError) {
// SPIR-V specific
TEST_F(FileTest, SpirvStorageClass) { runFileTest("spirv.storage-class.hlsl"); }
TEST_F(FileTest, SpirvString) {
runFileTest("spirv.string.hlsl");
}
TEST_F(FileTest, SpirvControlFlowMissingReturn) {
runFileTest("spirv.cf.ret-missing.hlsl");
}