[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:
|
||||
return spvContext.getSIntType(32);
|
||||
case BuiltinType::UInt:
|
||||
case BuiltinType::ULong:
|
||||
return spvContext.getUIntType(32);
|
||||
|
||||
// void and bool
|
||||
|
|
|
@ -760,6 +760,8 @@ SpirvInstruction *SpirvEmitter::doExpr(const Expr *expr) {
|
|||
result = curThis;
|
||||
} else if (isa<CXXConstructExpr>(expr)) {
|
||||
result = curThis;
|
||||
} else if (const auto *unaryExpr = dyn_cast<UnaryExprOrTypeTraitExpr>(expr)) {
|
||||
result = doUnaryExprOrTypeTraitExpr(unaryExpr);
|
||||
} else {
|
||||
emitError("expression class '%0' unimplemented", expr->getExprLoc())
|
||||
<< 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);
|
||||
}
|
||||
|
||||
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 clang
|
||||
|
|
|
@ -106,6 +106,8 @@ private:
|
|||
SpirvInstruction *doInitListExpr(const InitListExpr *expr);
|
||||
SpirvInstruction *doMemberExpr(const MemberExpr *expr);
|
||||
SpirvInstruction *doUnaryOperator(const UnaryOperator *expr);
|
||||
SpirvInstruction *
|
||||
doUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *expr);
|
||||
|
||||
/// 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");
|
||||
}
|
||||
|
||||
// For sizeof()
|
||||
TEST_F(FileTest, UnaryOpSizeof) { runFileTest("unary-op.sizeof.hlsl"); }
|
||||
|
||||
// For assignments
|
||||
TEST_F(FileTest, BinaryOpAssign) { runFileTest("binary-op.assign.hlsl"); }
|
||||
TEST_F(FileTest, BinaryOpAssignImage) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче