Assembly test for OpSwitch

Removes old weak and fragile tests for OpSwitch.

Adds spvtest::TextToBinaryTest::CompileWithFormatFailure
This commit is contained in:
David Neto 2015-09-28 15:02:21 -04:00
parent e77a7dd821
commit 42bfd4bfab
3 changed files with 74 additions and 54 deletions

View File

@ -84,17 +84,25 @@ class TextToBinaryTestBase : public T {
return code_copy;
}
// Compiles SPIR-V text, asserting compilation failure. Returns the error
// message(s).
std::string CompileFailure(const std::string& text) {
// Compiles SPIR-V text with the given format, asserting compilation failure.
// Returns the error message(s).
std::string CompileWithFormatFailure(const std::string& text,
spv_assembly_syntax_format_t format) {
EXPECT_NE(SPV_SUCCESS,
spvTextToBinary(text.c_str(), text.size(), opcodeTable,
operandTable, extInstTable, &binary, &diagnostic))
spvTextWithFormatToBinary(text.c_str(), text.size(), format,
opcodeTable, operandTable, extInstTable,
&binary, &diagnostic))
<< text;
DestroyBinary();
return diagnostic->error;
}
// Compiles SPIR-V text using the default format, asserting compilation failure.
// Returns the error message(s).
std::string CompileFailure(const std::string& text) {
return CompileWithFormatFailure(text, SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT);
}
// Encodes SPIR-V text into binary and then decodes the binary. Returns the
// decoded text.
std::string EncodeAndDecodeSuccessfully(const std::string& text) {

View File

@ -35,6 +35,7 @@
namespace {
using spvtest::MakeInstruction;
using spvtest::TextToBinaryTest;
using ::testing::Eq;
// Test OpSelectionMerge
@ -99,6 +100,66 @@ TEST_F(OpLoopMergeTest, CombinedLoopControlMask) {
Eq(MakeInstruction(spv::OpLoopMerge, {1, 2, expected_mask})));
}
// Test OpSwitch
TEST_F(TextToBinaryTest, SwitchGoodZeroTargets) {
EXPECT_THAT(CompiledInstructions("OpSwitch %selector %default"),
Eq(MakeInstruction(spv::OpSwitch, {1, 2})));
}
TEST_F(TextToBinaryTest, SwitchGoodOneTarget) {
EXPECT_THAT(CompiledInstructions("OpSwitch %selector %default 12 %target0"),
Eq(MakeInstruction(spv::OpSwitch, {1, 2, 12, 3})));
}
TEST_F(TextToBinaryTest, SwitchGoodTwoTargets) {
EXPECT_THAT(CompiledInstructions(
"OpSwitch %selector %default 12 %target0 42 %target1"),
Eq(MakeInstruction(spv::OpSwitch, {1, 2, 12, 3, 42, 4})));
}
TEST_F(TextToBinaryTest, SwitchBadMissingSelector) {
EXPECT_THAT(CompileFailure("OpSwitch"),
Eq("Expected operand, found end of stream."));
}
TEST_F(TextToBinaryTest, SwitchBadInvalidSelector) {
EXPECT_THAT(CompileFailure("OpSwitch 12"),
Eq("Expected id to start with %."));
}
TEST_F(TextToBinaryTest, SwitchBadMissingDefault) {
EXPECT_THAT(CompileFailure("OpSwitch %selector"),
Eq("Expected operand, found end of stream."));
}
TEST_F(TextToBinaryTest, SwitchBadInvalidDefault) {
EXPECT_THAT(CompileFailure("OpSwitch %selector 12"),
Eq("Expected id to start with %."));
}
TEST_F(TextToBinaryTest, SwitchBadInvalidLiteralDefaultFormat) {
// The assembler recognizes "OpSwitch %selector %default" as a complete
// instruction. Then it tries to parse "%abc" as the start of an
// assignment form instruction, but can't since it hits the end
// of stream.
EXPECT_THAT(CompileFailure("OpSwitch %selector %default %abc"),
Eq("Expected '=', found end of stream."));
}
TEST_F(TextToBinaryTest, SwitchBadInvalidLiteralCanonicalFormat) {
EXPECT_THAT(CompileWithFormatFailure("OpSwitch %selector %default %abc",
SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL),
Eq("Expected <opcode> at the beginning of an instruction, found "
"'%abc'."));
}
TEST_F(TextToBinaryTest, SwitchBadMissingTarget) {
EXPECT_THAT(CompileFailure("OpSwitch %selector %default 12"),
Eq("Expected operand, found end of stream."));
}
// TODO(dneto): OpPhi
// TODO(dneto): OpLoopMerge
// TODO(dneto): OpLabel

View File

@ -420,55 +420,6 @@ TEST_F(TextToBinaryTest, WrongOpCode) {
EXPECT_STREQ("Invalid Opcode prefix 'Wahahaha'.", diagnostic->error);
}
TEST_F(TextToBinaryTest, GoodSwitch) {
const SpirvVector code = CompileSuccessfully(R"(
%i32 = OpTypeInt 32 0
%fortytwo = OpConstant %i32 42
%twelve = OpConstant %i32 12
%entry = OpLabel
OpSwitch %fortytwo %default 42 %go42 12 %go12
%go42 = OpLabel
OpBranch %default
%go12 = OpLabel
OpBranch %default
%default = OpLabel
)");
// Minimal check: The OpSwitch opcode word is correct.
EXPECT_EQ((int(spv::OpSwitch) | (7 << 16)), code[14 + SPV_INDEX_INSTRUCTION]);
}
TEST_F(TextToBinaryTest, GoodSwitchZeroCasesOneDefault) {
const SpirvVector code = CompileSuccessfully(R"(
%i32 = OpTypeInt 32 0
%fortytwo = OpConstant %i32 42
%entry = OpLabel
OpSwitch %fortytwo %default
%default = OpLabel
)");
// Minimal check: The OpSwitch opcode word is correct.
EXPECT_EQ((int(spv::OpSwitch) | (3 << 16)), code[10 + SPV_INDEX_INSTRUCTION]);
}
TEST_F(TextToBinaryTest, BadSwitchTruncatedCase) {
SetText(R"(
%i32 = OpTypeInt 32 0
%fortytwo = OpConstant %i32 42
%entry = OpLabel
OpSwitch %fortytwo %default 42 ; missing target!
%default = OpLabel
)");
EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
spvTextToBinary(text.str, text.length, opcodeTable, operandTable,
extInstTable, &binary, &diagnostic));
EXPECT_EQ(6, diagnostic->position.line + 1);
EXPECT_EQ(1, diagnostic->position.column + 1);
EXPECT_STREQ("Expected operand, found next instruction instead.",
diagnostic->error);
}
using TextToBinaryFloatValueTest = spvtest::TextToBinaryTestBase<
::testing::TestWithParam<std::pair<std::string, uint32_t>>>;