[spirv] support sizeof() (#3080)
* [spirv] support sizeof() * Code review
This commit is contained in:
Родитель
bb0295fcf7
Коммит
0fb58c61ad
|
@ -253,6 +253,7 @@ const SpirvType *LowerTypeVisitor::lowerType(QualType type,
|
||||||
case BuiltinType::Int:
|
case BuiltinType::Int:
|
||||||
return spvContext.getSIntType(32);
|
return spvContext.getSIntType(32);
|
||||||
case BuiltinType::UInt:
|
case BuiltinType::UInt:
|
||||||
|
case BuiltinType::ULong:
|
||||||
return spvContext.getUIntType(32);
|
return spvContext.getUIntType(32);
|
||||||
|
|
||||||
// void and bool
|
// void and bool
|
||||||
|
|
|
@ -760,6 +760,8 @@ SpirvInstruction *SpirvEmitter::doExpr(const Expr *expr) {
|
||||||
result = curThis;
|
result = curThis;
|
||||||
} else if (isa<CXXConstructExpr>(expr)) {
|
} else if (isa<CXXConstructExpr>(expr)) {
|
||||||
result = curThis;
|
result = curThis;
|
||||||
|
} else if (const auto *unaryExpr = dyn_cast<UnaryExprOrTypeTraitExpr>(expr)) {
|
||||||
|
result = doUnaryExprOrTypeTraitExpr(unaryExpr);
|
||||||
} else {
|
} else {
|
||||||
emitError("expression class '%0' unimplemented", expr->getExprLoc())
|
emitError("expression class '%0' unimplemented", expr->getExprLoc())
|
||||||
<< expr->getStmtClassName() << expr->getSourceRange();
|
<< expr->getStmtClassName() << expr->getSourceRange();
|
||||||
|
@ -11675,5 +11677,25 @@ bool SpirvEmitter::spirvToolsLegalize(std::vector<uint32_t> *mod,
|
||||||
return optimizer.Run(mod->data(), mod->size(), mod, options);
|
return optimizer.Run(mod->data(), mod->size(), mod, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpirvInstruction *
|
||||||
|
SpirvEmitter::doUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *expr) {
|
||||||
|
// TODO: We support only `sizeof()`. Support other kinds.
|
||||||
|
if (expr->getKind() != clang::UnaryExprOrTypeTrait::UETT_SizeOf) {
|
||||||
|
emitError("expression class '%0' unimplemented", expr->getExprLoc())
|
||||||
|
<< expr->getStmtClassName();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlignmentSizeCalculator alignmentCalc(astContext, spirvOptions);
|
||||||
|
uint32_t size = 0, stride = 0;
|
||||||
|
std::tie(std::ignore, size) = alignmentCalc.getAlignmentAndSize(
|
||||||
|
expr->getArgumentType(), SpirvLayoutRule::Void,
|
||||||
|
/*isRowMajor*/ llvm::None, &stride);
|
||||||
|
auto *sizeConst = spvBuilder.getConstantInt(astContext.UnsignedIntTy,
|
||||||
|
llvm::APInt(32, size));
|
||||||
|
sizeConst->setRValue();
|
||||||
|
return sizeConst;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace spirv
|
} // end namespace spirv
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
|
@ -106,6 +106,8 @@ private:
|
||||||
SpirvInstruction *doInitListExpr(const InitListExpr *expr);
|
SpirvInstruction *doInitListExpr(const InitListExpr *expr);
|
||||||
SpirvInstruction *doMemberExpr(const MemberExpr *expr);
|
SpirvInstruction *doMemberExpr(const MemberExpr *expr);
|
||||||
SpirvInstruction *doUnaryOperator(const UnaryOperator *expr);
|
SpirvInstruction *doUnaryOperator(const UnaryOperator *expr);
|
||||||
|
SpirvInstruction *
|
||||||
|
doUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *expr);
|
||||||
|
|
||||||
/// Overload with pre computed SpirvEvalInfo.
|
/// Overload with pre computed SpirvEvalInfo.
|
||||||
///
|
///
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Run: %dxc -T ps_6_2 -E main -HV 2018 -enable-16bit-types
|
||||||
|
|
||||||
|
struct PSInput
|
||||||
|
{
|
||||||
|
int4 color : COLOR;
|
||||||
|
};
|
||||||
|
ByteAddressBuffer g_meshData[] : register(t0, space3);
|
||||||
|
|
||||||
|
struct EmptyStruct {};
|
||||||
|
struct SimpleStruct { int x; };
|
||||||
|
|
||||||
|
int3 main(PSInput input) : SV_TARGET
|
||||||
|
{
|
||||||
|
int foo;
|
||||||
|
|
||||||
|
// CHECK: OpStore %foo %int_4
|
||||||
|
foo = sizeof(int);
|
||||||
|
// CHECK: OpStore %foo %int_4
|
||||||
|
foo = sizeof((int)0);
|
||||||
|
// CHECK: OpStore %foo %int_4
|
||||||
|
foo = sizeof(int);
|
||||||
|
// CHECK: OpStore %foo %int_8
|
||||||
|
foo = sizeof(int2);
|
||||||
|
// CHECK: OpStore %foo %int_16
|
||||||
|
foo = sizeof(int2x2);
|
||||||
|
// CHECK: OpStore %foo %int_8
|
||||||
|
foo = sizeof(int[2]);
|
||||||
|
// CHECK: OpStore %foo %int_4
|
||||||
|
foo = sizeof(SimpleStruct);
|
||||||
|
// CHECK: OpStore %foo %int_0
|
||||||
|
foo = sizeof(EmptyStruct);
|
||||||
|
// CHECK: OpStore %foo %int_12
|
||||||
|
foo = sizeof(int16_t3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_12
|
||||||
|
foo = sizeof(half3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_24
|
||||||
|
foo = sizeof(int3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_24
|
||||||
|
foo = sizeof(float3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_24
|
||||||
|
foo = sizeof(bool3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_48
|
||||||
|
foo = sizeof(int64_t3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_48
|
||||||
|
foo = sizeof(double3[2]);
|
||||||
|
// CHECK: OpStore %foo %int_0
|
||||||
|
foo = sizeof(EmptyStruct[2]);
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int16_t i16;
|
||||||
|
// 2-byte padding
|
||||||
|
struct { float f32; } s; // Nested type
|
||||||
|
struct {} _; // Zero-sized field.
|
||||||
|
} complexStruct;
|
||||||
|
// CHECK: OpStore %foo %int_8
|
||||||
|
foo = sizeof(complexStruct);
|
||||||
|
|
||||||
|
// CHECK: OpIMul %uint {{%\d+}} %uint_12
|
||||||
|
return g_meshData[input.color.x].Load3(input.color.y * sizeof(float3));
|
||||||
|
}
|
|
@ -243,6 +243,9 @@ TEST_F(FileTest, UnaryOpLogicalNot) {
|
||||||
runFileTest("unary-op.logical-not.hlsl");
|
runFileTest("unary-op.logical-not.hlsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For sizeof()
|
||||||
|
TEST_F(FileTest, UnaryOpSizeof) { runFileTest("unary-op.sizeof.hlsl"); }
|
||||||
|
|
||||||
// For assignments
|
// For assignments
|
||||||
TEST_F(FileTest, BinaryOpAssign) { runFileTest("binary-op.assign.hlsl"); }
|
TEST_F(FileTest, BinaryOpAssign) { runFileTest("binary-op.assign.hlsl"); }
|
||||||
TEST_F(FileTest, BinaryOpAssignImage) {
|
TEST_F(FileTest, BinaryOpAssignImage) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче