mirror of
https://github.com/RPCSX/SPIRV-Tools.git
synced 2025-02-03 09:51:47 +00:00
Assembler support for OpSpecConstantOp
Adds SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER.
This commit is contained in:
parent
ce9cef71ac
commit
0f166be68d
@ -182,6 +182,10 @@ typedef enum spv_operand_type_t {
|
||||
// number indicating which instruction to use from an extended instruction
|
||||
// set.
|
||||
SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
|
||||
// The Opcode argument to OpSpecConstantOp. It determines the operation
|
||||
// to be performed on constant operands to compute a specialization constant
|
||||
// result.
|
||||
SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER,
|
||||
// A literal number whose format and size are determined by a previous operand
|
||||
// in the same instruction. It's a signed integer, an unsigned integer, or a
|
||||
// floating point number. It also has a specified bit width. The width
|
||||
@ -227,11 +231,11 @@ typedef enum spv_operand_type_t {
|
||||
#undef FIRST_CONCRETE
|
||||
#undef LAST_CONCRETE
|
||||
|
||||
// The remaining operand types are only used internally by the assembler.
|
||||
// There are two categories:
|
||||
// Optional : expands to 0 or 1 operand, like ? in regular expressions.
|
||||
// Variable : expands to 0, 1 or many operands or pairs of operands.
|
||||
// This is similar to * in regular expressions.
|
||||
// The remaining operand types are only used internally by the assembler.
|
||||
// There are two categories:
|
||||
// Optional : expands to 0 or 1 operand, like ? in regular expressions.
|
||||
// Variable : expands to 0, 1 or many operands or pairs of operands.
|
||||
// This is similar to * in regular expressions.
|
||||
|
||||
// Macros for defining bounds on optional and variable operand types.
|
||||
// Any variable operand type is also optional.
|
||||
|
@ -109,6 +109,89 @@ spv_ext_inst_table GetDefaultExtInstTable() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Associates an opcode with its name.
|
||||
struct SpecConstantOpcodeEntry {
|
||||
SpvOp opcode;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
// All the opcodes allowed as the operation for OpSpecConstantOp.
|
||||
// The name does not have the usual "Op" prefix. For example opcode SpvOpIAdd
|
||||
// is associated with the name "IAdd".
|
||||
//
|
||||
// clang-format off
|
||||
#define CASE(NAME) { SpvOp##NAME, #NAME }
|
||||
const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = {
|
||||
// Conversion
|
||||
CASE(SConvert),
|
||||
CASE(FConvert),
|
||||
CASE(ConvertFToS),
|
||||
CASE(ConvertSToF),
|
||||
CASE(ConvertFToU),
|
||||
CASE(ConvertUToF),
|
||||
CASE(UConvert),
|
||||
CASE(ConvertPtrToU),
|
||||
CASE(ConvertUToPtr),
|
||||
CASE(PtrCastToGeneric),
|
||||
CASE(Bitcast),
|
||||
CASE(QuantizeToF16),
|
||||
// Arithmetic
|
||||
CASE(SNegate),
|
||||
CASE(Not),
|
||||
CASE(IAdd),
|
||||
CASE(ISub),
|
||||
CASE(IMul),
|
||||
CASE(UDiv),
|
||||
CASE(SDiv),
|
||||
CASE(UMod),
|
||||
CASE(SRem),
|
||||
CASE(SMod),
|
||||
CASE(ShiftRightLogical),
|
||||
CASE(ShiftRightArithmetic),
|
||||
CASE(ShiftLeftLogical),
|
||||
CASE(BitwiseOr),
|
||||
CASE(BitwiseAnd),
|
||||
CASE(FNegate),
|
||||
CASE(FAdd),
|
||||
CASE(FSub),
|
||||
CASE(FMul),
|
||||
CASE(FDiv),
|
||||
CASE(FRem),
|
||||
CASE(FMod),
|
||||
// Composite
|
||||
CASE(VectorShuffle),
|
||||
CASE(CompositeExtract),
|
||||
CASE(CompositeInsert),
|
||||
// Logical
|
||||
CASE(LogicalOr),
|
||||
CASE(LogicalAnd),
|
||||
CASE(LogicalNot),
|
||||
CASE(LogicalEqual),
|
||||
CASE(LogicalNotEqual),
|
||||
CASE(Select),
|
||||
// Comparison
|
||||
CASE(IEqual),
|
||||
CASE(ULessThan),
|
||||
CASE(SLessThan),
|
||||
CASE(UGreaterThan),
|
||||
CASE(SGreaterThan),
|
||||
CASE(ULessThanEqual),
|
||||
CASE(SLessThanEqual),
|
||||
CASE(SLessThanEqual),
|
||||
CASE(UGreaterThanEqual),
|
||||
CASE(SGreaterThanEqual),
|
||||
// Memory
|
||||
CASE(AccessChain),
|
||||
CASE(InBoundsAccessChain),
|
||||
CASE(PtrAccessChain),
|
||||
CASE(InBoundsPtrAccessChain),
|
||||
};
|
||||
#undef CASE
|
||||
// clang-format on
|
||||
|
||||
const size_t kNumOpSpecConstantOpcodes =
|
||||
sizeof(kOpSpecConstantOpcodes) / sizeof(kOpSpecConstantOpcodes[0]);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace libspirv {
|
||||
@ -145,6 +228,19 @@ spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type,
|
||||
return spvOperandTableValueLookup(operandTable_, type, operand, desc);
|
||||
}
|
||||
|
||||
spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name,
|
||||
SpvOp* opcode) const {
|
||||
const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes;
|
||||
const auto* found =
|
||||
std::find_if(kOpSpecConstantOpcodes, last,
|
||||
[name](const SpecConstantOpcodeEntry& entry) {
|
||||
return 0 == strcmp(name, entry.name);
|
||||
});
|
||||
if (found == last) return SPV_ERROR_INVALID_LOOKUP;
|
||||
*opcode = found->opcode;
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t AssemblyGrammar::parseMaskOperand(const spv_operand_type_t type,
|
||||
const char* textValue,
|
||||
uint32_t* pValue) const {
|
||||
|
@ -71,6 +71,13 @@ class AssemblyGrammar {
|
||||
spv_result_t lookupOperand(spv_operand_type_t type, uint32_t operand,
|
||||
spv_operand_desc* desc) const;
|
||||
|
||||
// Finds the opcode for the given OpSpecConstantOp opcode name. The name
|
||||
// should not have the "Op" prefix. For example, "IAdd" corresponds to
|
||||
// the integer add opcode for OpSpecConstantOp. On success, returns
|
||||
// SPV_SUCCESS and sends the discovered operation code through the opcode
|
||||
// parameter. On failure, returns SPV_ERROR_INVALID_LOOKUP.
|
||||
spv_result_t lookupSpecConstantOpcode(const char* name, SpvOp* opcode) const;
|
||||
|
||||
// Parses a mask expression string for the given operand type.
|
||||
//
|
||||
// A mask expression is a sequence of one or more terms separated by '|',
|
||||
|
@ -75,7 +75,8 @@ bool opcodeTableInitialized = false;
|
||||
// Opcode API
|
||||
|
||||
// Converts the given operand class enum (from the SPIR-V document generation
|
||||
// logic) to the operand type required by the parser.
|
||||
// logic) to the operand type required by the parser. The SPV_OPERAND_TYPE_NONE
|
||||
// value indicates there is no current operand and no further operands.
|
||||
// This only applies to logical operands.
|
||||
spv_operand_type_t convertOperandClassToType(SpvOp opcode,
|
||||
OperandClass operandClass) {
|
||||
@ -113,6 +114,13 @@ spv_operand_type_t convertOperandClassToType(SpvOp opcode,
|
||||
case OperandOptionalImage:
|
||||
return SPV_OPERAND_TYPE_OPTIONAL_IMAGE;
|
||||
case OperandVariableIds:
|
||||
if (opcode == SpvOpSpecConstantOp) {
|
||||
// These are the operands to the specialization constant opcode.
|
||||
// The assembler and binary parser set up the extra Id and literal
|
||||
// arguments when processing the opcode operand. So don't add
|
||||
// an operand type for them here.
|
||||
return SPV_OPERAND_TYPE_NONE;
|
||||
}
|
||||
return SPV_OPERAND_TYPE_VARIABLE_ID;
|
||||
// The spec only uses OptionalLiteral for an optional literal number.
|
||||
case OperandOptionalLiteral:
|
||||
@ -131,6 +139,12 @@ spv_operand_type_t convertOperandClassToType(SpvOp opcode,
|
||||
// TODO(dneto): Use a function to confirm the assumption, and to verify
|
||||
// that the index into the operandClass is 1, as expected.
|
||||
return SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER;
|
||||
} else if (opcode == SpvOpSpecConstantOp) {
|
||||
// Use a special operand type for the opcode operand, so we can
|
||||
// use mnemonic names instead of the numbers. For example, the
|
||||
// assembler should accept "IAdd" instead of the numeric value of
|
||||
// SpvOpIAdd.
|
||||
return SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER;
|
||||
}
|
||||
return SPV_OPERAND_TYPE_LITERAL_INTEGER;
|
||||
case OperandLiteralString:
|
||||
@ -245,16 +259,20 @@ void spvOpcodeTableInitialize() {
|
||||
opcode.numTypes < maxNumOperands && classIndex < maxNumClasses;
|
||||
classIndex++) {
|
||||
const OperandClass operandClass = opcode.operandClass[classIndex];
|
||||
opcode.operandTypes[opcode.numTypes++] =
|
||||
const auto operandType =
|
||||
convertOperandClassToType(opcode.opcode, operandClass);
|
||||
opcode.operandTypes[opcode.numTypes++] = operandType;
|
||||
// The OperandNone value is not explicitly represented in the .inc file.
|
||||
// However, it is the zero value, and is created via implicit value
|
||||
// initialization.
|
||||
if (operandClass == OperandNone) {
|
||||
// initialization. It converts to SPV_OPERAND_TYPE_NONE.
|
||||
// The SPV_OPERAND_TYPE_NONE operand type indicates no current or futher
|
||||
// operands.
|
||||
if (operandType == SPV_OPERAND_TYPE_NONE) {
|
||||
opcode.numTypes--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We should have written the terminating SPV_OPERAND_TYPE_NONE entry, but
|
||||
// also without overflowing.
|
||||
assert((opcode.numTypes < maxNumOperands) &&
|
||||
|
@ -1191,6 +1191,8 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
|
||||
return "possibly multi-word literal number";
|
||||
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
|
||||
return "extension instruction number";
|
||||
case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
|
||||
return "OpSpecConstantOp opcode";
|
||||
case SPV_OPERAND_TYPE_LITERAL_STRING:
|
||||
case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
|
||||
return "literal string";
|
||||
|
@ -38,12 +38,12 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <libspirv/libspirv.h>
|
||||
#include "assembly_grammar.h"
|
||||
#include "binary.h"
|
||||
#include "diagnostic.h"
|
||||
#include "ext_inst.h"
|
||||
#include "instruction.h"
|
||||
#include <libspirv/libspirv.h>
|
||||
#include "opcode.h"
|
||||
#include "operand.h"
|
||||
#include "text_handler.h"
|
||||
@ -245,7 +245,6 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar,
|
||||
}
|
||||
pInst->extInstType = ext_inst_type;
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
|
||||
@ -260,8 +259,30 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar,
|
||||
|
||||
// Prepare to parse the operands for the extended instructions.
|
||||
spvPrependOperandTypes(extInst->operandTypes, pExpectedOperands);
|
||||
} break;
|
||||
|
||||
return SPV_SUCCESS;
|
||||
case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
|
||||
// The assembler accepts the symbolic name for the opcode, but without
|
||||
// the "Op" prefix. For example, "IAdd" is accepted. The number
|
||||
// of the opcode is emitted.
|
||||
SpvOp opcode;
|
||||
if (grammar.lookupSpecConstantOpcode(textValue, &opcode)) {
|
||||
return context->diagnostic() << "Invalid " << spvOperandTypeStr(type)
|
||||
<< " '" << textValue << "'.";
|
||||
}
|
||||
spv_opcode_desc opcodeEntry = nullptr;
|
||||
if (grammar.lookupOpcode(opcode, &opcodeEntry)) {
|
||||
return context->diagnostic(SPV_ERROR_INTERNAL)
|
||||
<< "OpSpecConstant opcode table out of sync";
|
||||
}
|
||||
spvInstructionAddWord(pInst, uint32_t(opcodeEntry->opcode));
|
||||
|
||||
// Prepare to parse the operands for the opcode. Except skip the
|
||||
// type Id and result Id, since they've already been processed.
|
||||
assert(opcodeEntry->hasType);
|
||||
assert(opcodeEntry->hasResult);
|
||||
assert(opcodeEntry->numTypes >= 2);
|
||||
spvPrependOperandTypes(opcodeEntry->operandTypes + 2, pExpectedOperands);
|
||||
} break;
|
||||
|
||||
case SPV_OPERAND_TYPE_LITERAL_INTEGER:
|
||||
@ -348,7 +369,8 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar,
|
||||
<< "Invalid extended instruction import '" << literal.value.str
|
||||
<< "'";
|
||||
}
|
||||
if (auto error = context->recordIdAsExtInstImport(pInst->words[1], ext_inst_type))
|
||||
if (auto error = context->recordIdAsExtInstImport(pInst->words[1],
|
||||
ext_inst_type))
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -471,6 +471,177 @@ INSTANTIATE_TEST_CASE_P(
|
||||
"%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 -1.79769e+308\n",
|
||||
}));
|
||||
|
||||
// Test OpSpecConstantOp
|
||||
|
||||
using OpSpecConstantOpTestWithIds =
|
||||
spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<SpvOp>>>;
|
||||
|
||||
// The operands to the OpSpecConstantOp opcode are all Ids.
|
||||
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(SpvOpSpecConstantOp,
|
||||
{1, 2, uint32_t(GetParam().value())},
|
||||
GetParam().operands())));
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#define CASE1(NAME) { SpvOp##NAME, #NAME, {3} }
|
||||
#define CASE2(NAME) { SpvOp##NAME, #NAME, {3, 4} }
|
||||
#define CASE3(NAME) { SpvOp##NAME, #NAME, {3, 4, 5} }
|
||||
#define CASE4(NAME) { SpvOp##NAME, #NAME, {3, 4, 5, 6} }
|
||||
#define CASE5(NAME) { SpvOp##NAME, #NAME, {3, 4, 5, 6, 7} }
|
||||
#define CASE6(NAME) { SpvOp##NAME, #NAME, {3, 4, 5, 6, 7, 8} }
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
TextToBinaryOpSpecConstantOp, OpSpecConstantOpTestWithIds,
|
||||
::testing::ValuesIn(std::vector<EnumCase<SpvOp>>{
|
||||
// Conversion
|
||||
CASE1(SConvert),
|
||||
CASE1(FConvert),
|
||||
CASE1(ConvertFToS),
|
||||
CASE1(ConvertSToF),
|
||||
CASE1(ConvertFToU),
|
||||
CASE1(ConvertUToF),
|
||||
CASE1(UConvert),
|
||||
CASE1(ConvertPtrToU),
|
||||
CASE1(ConvertUToPtr),
|
||||
CASE1(PtrCastToGeneric),
|
||||
CASE1(Bitcast),
|
||||
CASE1(QuantizeToF16),
|
||||
// Arithmetic
|
||||
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),
|
||||
CASE1(FNegate),
|
||||
CASE2(FAdd),
|
||||
CASE2(FSub),
|
||||
CASE2(FMul),
|
||||
CASE2(FDiv),
|
||||
CASE2(FRem),
|
||||
CASE2(FMod),
|
||||
// Composite operations use literal numbers. So they're in another test.
|
||||
// Logical
|
||||
CASE2(LogicalOr),
|
||||
CASE2(LogicalAnd),
|
||||
CASE1(LogicalNot),
|
||||
CASE2(LogicalEqual),
|
||||
CASE2(LogicalNotEqual),
|
||||
CASE3(Select),
|
||||
// Comparison
|
||||
CASE2(IEqual),
|
||||
CASE2(ULessThan),
|
||||
CASE2(SLessThan),
|
||||
CASE2(UGreaterThan),
|
||||
CASE2(SGreaterThan),
|
||||
CASE2(ULessThanEqual),
|
||||
CASE2(SLessThanEqual),
|
||||
CASE2(SLessThanEqual),
|
||||
CASE2(UGreaterThanEqual),
|
||||
CASE2(SGreaterThanEqual),
|
||||
// Memory
|
||||
// For AccessChain, there is a base Id, then a sequence of index Ids.
|
||||
// Having no index Ids is a corner case.
|
||||
CASE1(AccessChain),
|
||||
CASE2(AccessChain),
|
||||
CASE6(AccessChain),
|
||||
CASE1(InBoundsAccessChain),
|
||||
CASE2(InBoundsAccessChain),
|
||||
CASE6(InBoundsAccessChain),
|
||||
// PtrAccessChain also has an element Id.
|
||||
CASE2(PtrAccessChain),
|
||||
CASE3(PtrAccessChain),
|
||||
CASE6(PtrAccessChain),
|
||||
CASE2(InBoundsPtrAccessChain),
|
||||
CASE3(InBoundsPtrAccessChain),
|
||||
CASE6(InBoundsPtrAccessChain),
|
||||
}));
|
||||
#undef CASE1
|
||||
#undef CASE2
|
||||
#undef CASE3
|
||||
#undef CASE4
|
||||
#undef CASE5
|
||||
#undef CASE6
|
||||
// clang-format on
|
||||
|
||||
using OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers =
|
||||
spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<SpvOp>>>;
|
||||
|
||||
// The operands to the OpSpecConstantOp opcode are two Ids followed by a
|
||||
// sequence of literal numbers.
|
||||
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(SpvOpSpecConstantOp,
|
||||
{1, 2, uint32_t(GetParam().value()), 3, 4},
|
||||
GetParam().operands())));
|
||||
}
|
||||
|
||||
#define CASE(NAME) SpvOp##NAME, #NAME
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
TextToBinaryOpSpecConstantOp,
|
||||
OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers,
|
||||
::testing::ValuesIn(std::vector<EnumCase<SpvOp>>{
|
||||
// For VectorShuffle, there are two vector operands, and at least
|
||||
// two selector Ids. OpenCL can have up to 16-element vectors.
|
||||
{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}},
|
||||
// For CompositeInsert, there is an object to insert, the target
|
||||
// composite, and then literal indices.
|
||||
{CASE(CompositeInsert), {0}},
|
||||
{CASE(CompositeInsert), {4, 3, 99, 1}},
|
||||
}));
|
||||
|
||||
using OpSpecConstantOpTestWithOneIdThenLiteralNumbers =
|
||||
spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<SpvOp>>>;
|
||||
|
||||
// The operands to the OpSpecConstantOp opcode are one Id followed by a
|
||||
// sequence of literal numbers.
|
||||
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(SpvOpSpecConstantOp,
|
||||
{1, 2, uint32_t(GetParam().value()), 3},
|
||||
GetParam().operands())));
|
||||
}
|
||||
|
||||
#define CASE(NAME) SpvOp##NAME, #NAME
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
TextToBinaryOpSpecConstantOp,
|
||||
OpSpecConstantOpTestWithOneIdThenLiteralNumbers,
|
||||
::testing::ValuesIn(std::vector<EnumCase<SpvOp>>{
|
||||
// For CompositeExtract, the universal limit permits up to 255 literal
|
||||
// indices. Let's only test a few.
|
||||
{CASE(CompositeExtract), {0}},
|
||||
{CASE(CompositeExtract), {0, 99, 42, 16, 17, 12, 19}},
|
||||
}));
|
||||
|
||||
// TODO(dneto): OpConstantTrue
|
||||
// TODO(dneto): OpConstantFalse
|
||||
// TODO(dneto): OpConstantComposite
|
||||
@ -479,6 +650,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
// TODO(dneto): OpSpecConstantTrue
|
||||
// TODO(dneto): OpSpecConstantFalse
|
||||
// TODO(dneto): OpSpecConstantComposite
|
||||
// TODO(dneto): OpSpecConstantOp
|
||||
// TODO(dneto): Negative tests for OpSpecConstantOp
|
||||
|
||||
} // anonymous namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user