#include <cstdint>
#include <limits>
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "test/test_fixture.h"
#include "test/unit_spirv.h"
namespace spvtools {
namespace {
using spvtest::Concatenate;
using spvtest::EnumCase;
using spvtest::MakeInstruction;
using ::testing::Eq;
using SamplerAddressingModeTest = spvtest::TextToBinaryTestBase<
::testing::TestWithParam<EnumCase<spv::SamplerAddressingMode>>>;
TEST_P(SamplerAddressingModeTest, AnySamplerAddressingMode) {
const std::string input =
"%result = OpConstantSampler %type " + GetParam().name() + " 0 Nearest";
EXPECT_THAT(CompiledInstructions(input),
Eq(MakeInstruction(spv::Op::OpConstantSampler,
{1, 2, uint32_t(GetParam().value()), 0, 0})));
}
#define CASE(NAME) { spv::SamplerAddressingMode::NAME, #NAME }
INSTANTIATE_TEST_SUITE_P(
TextToBinarySamplerAddressingMode, SamplerAddressingModeTest,
::testing::ValuesIn(std::vector<EnumCase<spv::SamplerAddressingMode>>{
CASE(None),
CASE(ClampToEdge),
CASE(Clamp),
CASE(Repeat),
CASE(RepeatMirrored),
}));
#undef CASE
TEST_F(SamplerAddressingModeTest, WrongMode) {
EXPECT_THAT(CompileFailure("%r = OpConstantSampler %t xxyyzz 0 Nearest"),
Eq("Invalid sampler addressing mode 'xxyyzz'."));
}
using SamplerFilterModeTest = spvtest::TextToBinaryTestBase<
::testing::TestWithParam<EnumCase<spv::SamplerFilterMode>>>;
TEST_P(SamplerFilterModeTest, AnySamplerFilterMode) {
const std::string input =
"%result = OpConstantSampler %type Clamp 0 " + GetParam().name();
EXPECT_THAT(CompiledInstructions(input),
Eq(MakeInstruction(spv::Op::OpConstantSampler,
{1, 2, 2, 0, uint32_t(GetParam().value())})));
}
#define CASE(NAME) { spv::SamplerFilterMode::NAME, #NAME}
INSTANTIATE_TEST_SUITE_P(
TextToBinarySamplerFilterMode, SamplerFilterModeTest,
::testing::ValuesIn(std::vector<EnumCase<spv::SamplerFilterMode>>{
CASE(Nearest),
CASE(Linear),
}));
#undef CASE
TEST_F(SamplerFilterModeTest, WrongMode) {
EXPECT_THAT(CompileFailure("%r = OpConstantSampler %t Clamp 0 xxyyzz"),
Eq("Invalid sampler filter mode 'xxyyzz'."));
}
struct ConstantTestCase {
std::string constant_type;
std::string constant_value;
std::vector<uint32_t> expected_instructions;
};
using OpConstantValidTest =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<ConstantTestCase>>;
TEST_P(OpConstantValidTest, ValidTypes) {
const std::string input = "%1 = " + GetParam().constant_type +
"\n"
"%2 = OpConstant %1 " +
GetParam().constant_value + "\n";
std::vector<uint32_t> instructions;
EXPECT_THAT(CompiledInstructions(input), Eq(GetParam().expected_instructions))
<< " type: " << GetParam().constant_type
<< " literal: " << GetParam().constant_value;
}
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpConstantValid, OpConstantValidTest,
::testing::ValuesIn(std::vector<ConstantTestCase>{
{"OpTypeInt 16 0", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234})})},
{"OpTypeInt 16 0", "0x8000",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x8000})})},
{"OpTypeInt 16 0", "0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 16 0", "65535",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 65535})})},
{"OpTypeInt 16 0", "0xffff",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 65535})})},
{"OpTypeInt 16 1", "0x8000", Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffff8000})})},
{"OpTypeInt 16 1", "-32",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32)})})},
{"OpTypeInt 16 1", "0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 16 1", "-0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 16 1", "-0x0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 16 1", "-32768",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32768)})})},
{"OpTypeInt 32 0", "42",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 42})})},
{"OpTypeInt 32 1", "-32",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32)})})},
{"OpTypeInt 32 1", "0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 32 1", "-0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 32 1", "-0x0",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})},
{"OpTypeInt 32 1", "-0x001",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-1)})})},
{"OpTypeInt 32 1", "2147483647",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7fffffffu})})},
{"OpTypeInt 32 1", "-2147483648",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x80000000u})})},
{"OpTypeFloat 32", "1.0",
Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x3f800000})})},
{"OpTypeFloat 32", "10.0",
Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x41200000})})},
{"OpTypeFloat 32", "-0x1p+128", Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFF800000})})},
{"OpTypeFloat 32", "0x1p+128", Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7F800000})})},
{"OpTypeFloat 32", "-0x1.8p+128", Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFFC00000})})},
{"OpTypeFloat 32", "-0x1.0002p+128", Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFF800100})})},
{"OpTypeInt 48 0", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})},
{"OpTypeInt 48 0", "0x800000000001",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 1, 0x00008000})})},
{"OpTypeInt 48 1", "0x800000000000", Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0, 0xffff8000})})},
{"OpTypeInt 48 1", "-32",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})},
{"OpTypeInt 64 0", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})},
{"OpTypeInt 64 0", "18446744073709551615",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})},
{"OpTypeInt 64 0", "0xffffffffffffffff",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})},
{"OpTypeInt 64 1", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})},
{"OpTypeInt 64 1", "-42",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})},
{"OpTypeInt 64 1", "-0x01",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})},
{"OpTypeInt 64 1", "9223372036854775807",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0x7fffffffu})})},
{"OpTypeInt 64 1", "0x7fffffff",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7fffffffu, 0})})},
}));
struct InvalidLeadingMinusCase {
std::string type;
std::string literal;
};
using OpConstantInvalidLeadingMinusTest = spvtest::TextToBinaryTestBase<
::testing::TestWithParam<InvalidLeadingMinusCase>>;
TEST_P(OpConstantInvalidLeadingMinusTest, InvalidCase) {
const std::string input = "%1 = " + GetParam().type +
"\n"
"%2 = OpConstant %1 " +
GetParam().literal;
EXPECT_THAT(CompileFailure(input),
Eq("Cannot put a negative number in an unsigned literal"));
}
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpConstantInvalidLeadingMinus, OpConstantInvalidLeadingMinusTest,
::testing::ValuesIn(std::vector<InvalidLeadingMinusCase>{
{"OpTypeInt 16 0", "-0"},
{"OpTypeInt 16 0", "-0x0"},
{"OpTypeInt 16 0", "-1"},
{"OpTypeInt 32 0", "-0"},
{"OpTypeInt 32 0", "-0x0"},
{"OpTypeInt 32 0", "-1"},
{"OpTypeInt 64 0", "-0"},
{"OpTypeInt 64 0", "-0x0"},
{"OpTypeInt 64 0", "-1"},
}));
struct InvalidFloatConstantCase {
uint32_t width;
std::string literal;
};
using OpConstantInvalidFloatConstant = spvtest::TextToBinaryTestBase<
::testing::TestWithParam<InvalidFloatConstantCase>>;
TEST_P(OpConstantInvalidFloatConstant, Samples) {
for (const auto& instruction : {"OpConstant", "OpSpecConstant"}) {
std::stringstream input;
input << "%1 = OpTypeFloat " << GetParam().width << "\n"
<< "%2 = " << instruction << " %1 " << GetParam().literal;
std::stringstream expected_error;
expected_error << "Invalid " << GetParam().width
<< "-bit float literal: " << GetParam().literal;
EXPECT_THAT(CompileFailure(input.str()), Eq(expected_error.str()));
}
}
INSTANTIATE_TEST_SUITE_P(
TextToBinaryInvalidFloatConstant, OpConstantInvalidFloatConstant,
::testing::ValuesIn(std::vector<InvalidFloatConstantCase>{
{16, "abc"},
{16, "--1"},
{16, "-+1"},
{16, "+-1"},
{16, "++1"},
{16, "1e30"}, {16, "-1e30"},
{16, "1e40"},
{16, "-1e40"},
{16, "1e400"},
{16, "-1e400"},
{32, "abc"},
{32, "--1"},
{32, "-+1"},
{32, "+-1"},
{32, "++1"},
{32, "1e40"}, {32, "-1e40"},
{32, "1e400"},
{32, "-1e400"},
{64, "abc"},
{64, "--1"},
{64, "-+1"},
{64, "+-1"},
{64, "++1"},
{32, "1e400"}, {32, "-1e400"},
}));
using OpConstantInvalidTypeTest =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>;
TEST_P(OpConstantInvalidTypeTest, InvalidTypes) {
const std::string input = "%1 = " + GetParam() +
"\n"
"%2 = OpConstant %1 0\n";
EXPECT_THAT(
CompileFailure(input),
Eq("Type for Constant must be a scalar floating point or integer type"));
}
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpConstantInvalidValidType, OpConstantInvalidTypeTest,
::testing::ValuesIn(std::vector<std::string>{
{"OpTypeVoid",
"OpTypeBool",
"OpTypeVector %a 32",
"OpTypeMatrix %a 32",
"OpTypeImage %a 1D 0 0 0 0 Unknown",
"OpTypeSampler",
"OpTypeSampledImage %a",
"OpTypeArray %a %b",
"OpTypeRuntimeArray %a",
"OpTypeStruct %a",
"OpTypeOpaque \"Foo\"",
"OpTypePointer UniformConstant %a",
"OpTypeFunction %a %b",
"OpTypeEvent",
"OpTypeDeviceEvent",
"OpTypeReserveId",
"OpTypeQueue",
"OpTypePipe ReadOnly",
"OpNot %a %b"
},
}));
using OpSpecConstantValidTest =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<ConstantTestCase>>;
TEST_P(OpSpecConstantValidTest, ValidTypes) {
const std::string input = "%1 = " + GetParam().constant_type +
"\n"
"%2 = OpSpecConstant %1 " +
GetParam().constant_value + "\n";
std::vector<uint32_t> instructions;
EXPECT_THAT(CompiledInstructions(input),
Eq(GetParam().expected_instructions));
}
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpSpecConstantValid, OpSpecConstantValidTest,
::testing::ValuesIn(std::vector<ConstantTestCase>{
{"OpTypeInt 16 0", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234})})},
{"OpTypeInt 16 0", "0x8000",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x8000})})},
{"OpTypeInt 16 1", "0x8000", Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0xffff8000})})},
{"OpTypeInt 16 1", "-32",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32)})})},
{"OpTypeInt 32 0", "42",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 42})})},
{"OpTypeInt 32 1", "-32",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32)})})},
{"OpTypeFloat 32", "1.0",
Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x3f800000})})},
{"OpTypeFloat 32", "10.0",
Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x41200000})})},
{"OpTypeInt 48 0", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})},
{"OpTypeInt 48 0", "0x800000000001",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 1, 0x00008000})})},
{"OpTypeInt 48 1", "0x800000000000", Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0, 0xffff8000})})},
{"OpTypeInt 48 1", "-32",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})},
{"OpTypeInt 64 0", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})},
{"OpTypeInt 64 1", "0x1234",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})},
{"OpTypeInt 64 1", "-42",
Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}),
MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})},
}));
using OpSpecConstantInvalidTypeTest =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>;
TEST_P(OpSpecConstantInvalidTypeTest, InvalidTypes) {
const std::string input = "%1 = " + GetParam() +
"\n"
"%2 = OpSpecConstant %1 0\n";
EXPECT_THAT(CompileFailure(input),
Eq("Type for SpecConstant must be a scalar floating point or "
"integer type"));
}
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpSpecConstantInvalidValidType, OpSpecConstantInvalidTypeTest,
::testing::ValuesIn(std::vector<std::string>{
{"OpTypeVoid",
"OpTypeBool",
"OpTypeVector %a 32",
"OpTypeMatrix %a 32",
"OpTypeImage %a 1D 0 0 0 0 Unknown",
"OpTypeSampler",
"OpTypeSampledImage %a",
"OpTypeArray %a %b",
"OpTypeRuntimeArray %a",
"OpTypeStruct %a",
"OpTypeOpaque \"Foo\"",
"OpTypePointer UniformConstant %a",
"OpTypeFunction %a %b",
"OpTypeEvent",
"OpTypeDeviceEvent",
"OpTypeReserveId",
"OpTypeQueue",
"OpTypePipe ReadOnly",
"OpNot %a %b"
},
}));
const int64_t kMaxUnsigned48Bit = (int64_t(1) << 48) - 1;
const int64_t kMaxSigned48Bit = (int64_t(1) << 47) - 1;
const int64_t kMinSigned48Bit = -kMaxSigned48Bit - 1;
using ConstantRoundTripTest = RoundTripTest;
TEST_P(ConstantRoundTripTest, DisassemblyEqualsAssemblyInput) {
const std::string assembly = GetParam();
EXPECT_THAT(EncodeAndDecodeSuccessfully(assembly), Eq(assembly)) << assembly;
}
INSTANTIATE_TEST_SUITE_P(
OpConstantRoundTrip, ConstantRoundTripTest,
::testing::ValuesIn(std::vector<std::string>{
"%1 = OpTypeInt 16 0\n%2 = OpConstant %1 0\n",
"%1 = OpTypeInt 16 0\n%2 = OpConstant %1 65535\n",
"%1 = OpTypeInt 16 1\n%2 = OpConstant %1 -32768\n",
"%1 = OpTypeInt 16 1\n%2 = OpConstant %1 32767\n",
"%1 = OpTypeInt 32 0\n%2 = OpConstant %1 0\n",
std::string("%1 = OpTypeInt 32 0\n%2 = OpConstant %1 0\n"),
std::string("%1 = OpTypeInt 32 0\n%2 = OpConstant %1 ") +
std::to_string(std::numeric_limits<uint32_t>::max()) + "\n",
std::string("%1 = OpTypeInt 32 1\n%2 = OpConstant %1 ") +
std::to_string(std::numeric_limits<int32_t>::max()) + "\n",
std::string("%1 = OpTypeInt 32 1\n%2 = OpConstant %1 ") +
std::to_string(std::numeric_limits<int32_t>::min()) + "\n",
std::string("%1 = OpTypeInt 48 0\n%2 = OpConstant %1 0\n"),
std::string("%1 = OpTypeInt 48 0\n%2 = OpConstant %1 ") +
std::to_string(kMaxUnsigned48Bit) + "\n",
std::string("%1 = OpTypeInt 48 1\n%2 = OpConstant %1 ") +
std::to_string(kMaxSigned48Bit) + "\n",
std::string("%1 = OpTypeInt 48 1\n%2 = OpConstant %1 ") +
std::to_string(kMinSigned48Bit) + "\n",
std::string("%1 = OpTypeInt 64 0\n%2 = OpConstant %1 0\n"),
std::string("%1 = OpTypeInt 64 0\n%2 = OpConstant %1 ") +
std::to_string(std::numeric_limits<uint64_t>::max()) + "\n",
std::string("%1 = OpTypeInt 64 1\n%2 = OpConstant %1 ") +
std::to_string(std::numeric_limits<int64_t>::max()) + "\n",
std::string("%1 = OpTypeInt 64 1\n%2 = OpConstant %1 ") +
std::to_string(std::numeric_limits<int64_t>::min()) + "\n",
"%1 = OpTypeFloat 32\n%2 = OpConstant %1 0\n",
"%1 = OpTypeFloat 32\n%2 = OpConstant %1 13.5\n",
"%1 = OpTypeFloat 32\n%2 = OpConstant %1 -12.5\n",
"%1 = OpTypeFloat 64\n%2 = OpConstant %1 0\n",
"%1 = OpTypeFloat 64\n%2 = OpConstant %1 1.79767e+308\n",
"%1 = OpTypeFloat 64\n%2 = OpConstant %1 -1.79767e+308\n",
}));
INSTANTIATE_TEST_SUITE_P(
OpConstantHalfRoundTrip, ConstantRoundTripTest,
::testing::ValuesIn(std::vector<std::string>{
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x0p+0\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x0p+0\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p+0\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.1p+0\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.01p-1\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.8p+1\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.ffcp+1\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1p+0\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.1p+0\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.01p-1\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.8p+1\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.ffcp+1\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p-16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p-24\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1p-24\n",
"%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.01p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.01p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.11p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.ffp+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.ffcp+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.004p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.01p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.11p+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.ffp+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.ffcp+16\n", "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.004p+16\n", }));
INSTANTIATE_TEST_SUITE_P(
OpConstantRoundTripNonFinite, ConstantRoundTripTest,
::testing::ValuesIn(std::vector<std::string>{
"%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.8p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.0002p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.0018p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.01ep+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.fffffep+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.8p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.0002p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.0018p+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.01ep+128\n", "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.fffffep+128\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.8p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.0fp+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.0000000000001p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.00003p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.fffffffffffffp+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.8p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.0fp+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.0000000000001p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.00003p+1024\n", "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.fffffffffffffp+1024\n", }));
INSTANTIATE_TEST_SUITE_P(
OpSpecConstantRoundTrip, ConstantRoundTripTest,
::testing::ValuesIn(std::vector<std::string>{
"%1 = OpTypeInt 16 0\n%2 = OpSpecConstant %1 0\n",
"%1 = OpTypeInt 16 0\n%2 = OpSpecConstant %1 65535\n",
"%1 = OpTypeInt 16 1\n%2 = OpSpecConstant %1 -32768\n",
"%1 = OpTypeInt 16 1\n%2 = OpSpecConstant %1 32767\n",
"%1 = OpTypeInt 32 0\n%2 = OpSpecConstant %1 0\n",
std::string("%1 = OpTypeInt 32 0\n%2 = OpSpecConstant %1 0\n"),
std::string("%1 = OpTypeInt 32 0\n%2 = OpSpecConstant %1 ") +
std::to_string(std::numeric_limits<uint32_t>::max()) + "\n",
std::string("%1 = OpTypeInt 32 1\n%2 = OpSpecConstant %1 ") +
std::to_string(std::numeric_limits<int32_t>::max()) + "\n",
std::string("%1 = OpTypeInt 32 1\n%2 = OpSpecConstant %1 ") +
std::to_string(std::numeric_limits<int32_t>::min()) + "\n",
std::string("%1 = OpTypeInt 48 0\n%2 = OpSpecConstant %1 0\n"),
std::string("%1 = OpTypeInt 48 0\n%2 = OpSpecConstant %1 ") +
std::to_string(kMaxUnsigned48Bit) + "\n",
std::string("%1 = OpTypeInt 48 1\n%2 = OpSpecConstant %1 ") +
std::to_string(kMaxSigned48Bit) + "\n",
std::string("%1 = OpTypeInt 48 1\n%2 = OpSpecConstant %1 ") +
std::to_string(kMinSigned48Bit) + "\n",
std::string("%1 = OpTypeInt 64 0\n%2 = OpSpecConstant %1 0\n"),
std::string("%1 = OpTypeInt 64 0\n%2 = OpSpecConstant %1 ") +
std::to_string(std::numeric_limits<uint64_t>::max()) + "\n",
std::string("%1 = OpTypeInt 64 1\n%2 = OpSpecConstant %1 ") +
std::to_string(std::numeric_limits<int64_t>::max()) + "\n",
std::string("%1 = OpTypeInt 64 1\n%2 = OpSpecConstant %1 ") +
std::to_string(std::numeric_limits<int64_t>::min()) + "\n",
"%1 = OpTypeFloat 32\n%2 = OpSpecConstant %1 0\n",
"%1 = OpTypeFloat 32\n%2 = OpSpecConstant %1 13.5\n",
"%1 = OpTypeFloat 32\n%2 = OpSpecConstant %1 -12.5\n",
"%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 0\n",
"%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 1.79767e+308\n",
"%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 -1.79767e+308\n",
}));
using OpSpecConstantOpTestWithIds =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<spv::Op>>>;
TEST_P(OpSpecConstantOpTestWithIds, Assembly) {
std::stringstream input;
input << "%2 = OpSpecConstantOp %1 " << GetParam().name();
for (auto id : GetParam().operands()) input << " %" << id;
input << "\n";
EXPECT_THAT(CompiledInstructions(input.str()),
Eq(MakeInstruction(spv::Op::OpSpecConstantOp,
{1, 2, uint32_t(GetParam().value())},
GetParam().operands())));
EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str());
}
#define CASE1(NAME) { spv::Op::Op##NAME, #NAME, {3} }
#define CASE2(NAME) { spv::Op::Op##NAME, #NAME, {3, 4} }
#define CASE3(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5} }
#define CASE4(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6} }
#define CASE5(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6, 7} }
#define CASE6(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6, 7, 8} }
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpSpecConstantOp, OpSpecConstantOpTestWithIds,
::testing::ValuesIn(std::vector<EnumCase<spv::Op>>{
CASE1(SConvert),
CASE1(FConvert),
CASE1(ConvertFToS),
CASE1(ConvertSToF),
CASE1(ConvertFToU),
CASE1(ConvertUToF),
CASE1(UConvert),
CASE1(ConvertPtrToU),
CASE1(ConvertUToPtr),
CASE1(GenericCastToPtr),
CASE1(PtrCastToGeneric),
CASE1(Bitcast),
CASE1(QuantizeToF16),
CASE1(SNegate),
CASE1(Not),
CASE2(IAdd),
CASE2(ISub),
CASE2(IMul),
CASE2(UDiv),
CASE2(SDiv),
CASE2(UMod),
CASE2(SRem),
CASE2(SMod),
CASE2(ShiftRightLogical),
CASE2(ShiftRightArithmetic),
CASE2(ShiftLeftLogical),
CASE2(BitwiseOr),
CASE2(BitwiseAnd),
CASE2(BitwiseXor),
CASE1(FNegate),
CASE2(FAdd),
CASE2(FSub),
CASE2(FMul),
CASE2(FDiv),
CASE2(FRem),
CASE2(FMod),
CASE2(LogicalOr),
CASE2(LogicalAnd),
CASE1(LogicalNot),
CASE2(LogicalEqual),
CASE2(LogicalNotEqual),
CASE3(Select),
CASE2(IEqual),
CASE2(INotEqual), CASE2(ULessThan),
CASE2(SLessThan),
CASE2(UGreaterThan),
CASE2(SGreaterThan),
CASE2(ULessThanEqual),
CASE2(SLessThanEqual),
CASE2(UGreaterThanEqual),
CASE2(SGreaterThanEqual),
CASE1(AccessChain),
CASE2(AccessChain),
CASE6(AccessChain),
CASE1(InBoundsAccessChain),
CASE2(InBoundsAccessChain),
CASE6(InBoundsAccessChain),
CASE2(PtrAccessChain),
CASE3(PtrAccessChain),
CASE6(PtrAccessChain),
CASE2(InBoundsPtrAccessChain),
CASE3(InBoundsPtrAccessChain),
CASE6(InBoundsPtrAccessChain),
}));
#undef CASE1
#undef CASE2
#undef CASE3
#undef CASE4
#undef CASE5
#undef CASE6
using OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<spv::Op>>>;
TEST_P(OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers, Assembly) {
std::stringstream input;
input << "%2 = OpSpecConstantOp %1 " << GetParam().name() << " %3 %4";
for (auto number : GetParam().operands()) input << " " << number;
input << "\n";
EXPECT_THAT(CompiledInstructions(input.str()),
Eq(MakeInstruction(spv::Op::OpSpecConstantOp,
{1, 2, uint32_t(GetParam().value()), 3, 4},
GetParam().operands())));
EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str());
}
#define CASE(NAME) spv::Op::Op##NAME, #NAME
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpSpecConstantOp,
OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers,
::testing::ValuesIn(std::vector<EnumCase<spv::Op>>{
{CASE(VectorShuffle), {0, 0}},
{CASE(VectorShuffle), {4, 3, 2, 1}},
{CASE(VectorShuffle), {0, 2, 4, 6, 1, 3, 5, 7}},
{CASE(VectorShuffle),
{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}},
{CASE(CompositeInsert), {0}},
{CASE(CompositeInsert), {4, 3, 99, 1}},
}));
using OpSpecConstantOpTestWithOneIdThenLiteralNumbers =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<spv::Op>>>;
TEST_P(OpSpecConstantOpTestWithOneIdThenLiteralNumbers, Assembly) {
std::stringstream input;
input << "%2 = OpSpecConstantOp %1 " << GetParam().name() << " %3";
for (auto number : GetParam().operands()) input << " " << number;
input << "\n";
EXPECT_THAT(CompiledInstructions(input.str()),
Eq(MakeInstruction(spv::Op::OpSpecConstantOp,
{1, 2, uint32_t(GetParam().value()), 3},
GetParam().operands())));
EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str());
}
#define CASE(NAME) spv::Op::Op##NAME, #NAME
INSTANTIATE_TEST_SUITE_P(
TextToBinaryOpSpecConstantOp,
OpSpecConstantOpTestWithOneIdThenLiteralNumbers,
::testing::ValuesIn(std::vector<EnumCase<spv::Op>>{
{CASE(CompositeExtract), {0}},
{CASE(CompositeExtract), {0, 99, 42, 16, 17, 12, 19}},
}));
} }