spirv-fuzz: Avoid invalidating analyses in various transformations (#4205)

Avoids invalidating all analyses in transformations that add
constants, OpUndef and global and local variables.
This commit is contained in:
Alastair Donaldson 2021-03-20 22:48:02 +00:00 committed by GitHub
parent 6578899781
commit 6382cbb497
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 195 additions and 93 deletions

View File

@ -837,9 +837,10 @@ void AddVariableIdToEntryPointInterfaces(opt::IRContext* context, uint32_t id) {
}
}
void AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id, SpvStorageClass storage_class,
uint32_t initializer_id) {
opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id,
SpvStorageClass storage_class,
uint32_t initializer_id) {
// Check various preconditions.
assert(result_id != 0 && "Result id can't be 0");
@ -874,16 +875,20 @@ void AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
operands.push_back({SPV_OPERAND_TYPE_ID, {initializer_id}});
}
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
context, SpvOpVariable, type_id, result_id, std::move(operands)));
auto new_instruction = MakeUnique<opt::Instruction>(
context, SpvOpVariable, type_id, result_id, std::move(operands));
auto result = new_instruction.get();
context->module()->AddGlobalValue(std::move(new_instruction));
AddVariableIdToEntryPointInterfaces(context, result_id);
UpdateModuleIdBound(context, result_id);
return result;
}
void AddLocalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id, uint32_t function_id,
uint32_t initializer_id) {
opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id, uint32_t function_id,
uint32_t initializer_id) {
// Check various preconditions.
assert(result_id != 0 && "Result id can't be 0");
@ -904,13 +909,17 @@ void AddLocalVariable(opt::IRContext* context, uint32_t result_id,
auto* function = FindFunction(context, function_id);
assert(function && "Function id is invalid");
function->begin()->begin()->InsertBefore(MakeUnique<opt::Instruction>(
auto new_instruction = MakeUnique<opt::Instruction>(
context, SpvOpVariable, type_id, result_id,
opt::Instruction::OperandList{
{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}},
{SPV_OPERAND_TYPE_ID, {initializer_id}}}));
{SPV_OPERAND_TYPE_ID, {initializer_id}}});
auto result = new_instruction.get();
function->begin()->begin()->InsertBefore(std::move(new_instruction));
UpdateModuleIdBound(context, result_id);
return result;
}
bool HasDuplicates(const std::vector<uint32_t>& arr) {

View File

@ -303,9 +303,12 @@ void AddVariableIdToEntryPointInterfaces(opt::IRContext* context, uint32_t id);
// - |initializer_id| must be 0 if |storage_class| is Workgroup, and otherwise
// may either be 0 or the id of a constant whose type is the pointee type of
// |type_id|.
void AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id, SpvStorageClass storage_class,
uint32_t initializer_id);
//
// Returns a pointer to the new global variable instruction.
opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id,
SpvStorageClass storage_class,
uint32_t initializer_id);
// Adds an instruction to the start of |function_id|, of the form:
// |result_id| = OpVariable |type_id| Function |initializer_id|.
@ -315,9 +318,11 @@ void AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
// - |initializer_id| must be the id of a constant with the same type as the
// pointer's pointee type.
// - |function_id| must be the id of a function.
void AddLocalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id, uint32_t function_id,
uint32_t initializer_id);
//
// Returns a pointer to the new local variable instruction.
opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id, uint32_t function_id,
uint32_t initializer_id);
// Returns true if the vector |arr| has duplicates.
bool HasDuplicates(const std::vector<uint32_t>& arr);

View File

@ -21,8 +21,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddConstantBoolean::TransformationAddConstantBoolean(
const protobufs::TransformationAddConstantBoolean& message)
: message_(message) {}
protobufs::TransformationAddConstantBoolean message)
: message_(std::move(message)) {}
TransformationAddConstantBoolean::TransformationAddConstantBoolean(
uint32_t fresh_id, bool is_true, bool is_irrelevant) {
@ -42,14 +42,18 @@ void TransformationAddConstantBoolean::Apply(
TransformationContext* transformation_context) const {
// Add the boolean constant to the module, ensuring the module's id bound is
// high enough.
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse,
fuzzerutil::MaybeGetBoolType(ir_context), message_.fresh_id(),
opt::Instruction::OperandList());
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
ir_context->module()->AddGlobalValue(
message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse,
message_.fresh_id(), fuzzerutil::MaybeGetBoolType(ir_context));
// We have added an instruction to the module, so need to be careful about the
// validity of existing analyses.
ir_context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
// Inform the def-use manager about the new instruction. Invalidate the
// constant manager as we have added a new constant.
ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
if (message_.is_irrelevant()) {
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(

View File

@ -26,7 +26,7 @@ namespace fuzz {
class TransformationAddConstantBoolean : public Transformation {
public:
explicit TransformationAddConstantBoolean(
const protobufs::TransformationAddConstantBoolean& message);
protobufs::TransformationAddConstantBoolean message);
TransformationAddConstantBoolean(uint32_t fresh_id, bool is_true,
bool is_irrelevant);

View File

@ -22,9 +22,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddConstantComposite::TransformationAddConstantComposite(
const spvtools::fuzz::protobufs::TransformationAddConstantComposite&
message)
: message_(message) {}
spvtools::fuzz::protobufs::TransformationAddConstantComposite message)
: message_(std::move(message)) {}
TransformationAddConstantComposite::TransformationAddConstantComposite(
uint32_t fresh_id, uint32_t type_id,
@ -120,14 +119,17 @@ void TransformationAddConstantComposite::Apply(
for (auto constituent_id : message_.constituent_id()) {
in_operands.push_back({SPV_OPERAND_TYPE_ID, {constituent_id}});
}
ir_context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpConstantComposite, message_.type_id(),
message_.fresh_id(), in_operands));
message_.fresh_id(), in_operands);
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
// We have added an instruction to the module, so need to be careful about the
// validity of existing analyses.
ir_context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
// Inform the def-use manager of the new instruction. Invalidate the constant
// manager as we have added a new constant.
ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction_ptr);
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
if (message_.is_irrelevant()) {
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(

View File

@ -28,7 +28,7 @@ namespace fuzz {
class TransformationAddConstantComposite : public Transformation {
public:
explicit TransformationAddConstantComposite(
const protobufs::TransformationAddConstantComposite& message);
protobufs::TransformationAddConstantComposite message);
TransformationAddConstantComposite(
uint32_t fresh_id, uint32_t type_id,

View File

@ -20,8 +20,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddConstantNull::TransformationAddConstantNull(
const spvtools::fuzz::protobufs::TransformationAddConstantNull& message)
: message_(message) {}
spvtools::fuzz::protobufs::TransformationAddConstantNull message)
: message_(std::move(message)) {}
TransformationAddConstantNull::TransformationAddConstantNull(uint32_t fresh_id,
uint32_t type_id) {
@ -46,14 +46,18 @@ bool TransformationAddConstantNull::IsApplicable(
}
void TransformationAddConstantNull::Apply(
opt::IRContext* context, TransformationContext* /*unused*/) const {
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
context, SpvOpConstantNull, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList()));
fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id());
// We have added an instruction to the module, so need to be careful about the
// validity of existing analyses.
context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone);
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpConstantNull, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList());
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
// Inform the def-use manager about the new instruction. Invalidate the
// constant manager as we have added a new constant.
ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
}
protobufs::Transformation TransformationAddConstantNull::ToMessage() const {

View File

@ -26,7 +26,7 @@ namespace fuzz {
class TransformationAddConstantNull : public Transformation {
public:
explicit TransformationAddConstantNull(
const protobufs::TransformationAddConstantNull& message);
protobufs::TransformationAddConstantNull message);
TransformationAddConstantNull(uint32_t fresh_id, uint32_t type_id);
@ -34,12 +34,12 @@ class TransformationAddConstantNull : public Transformation {
// - |message_.type_id| must be the id of a type for which it is acceptable
// to create a null constant
bool IsApplicable(
opt::IRContext* context,
opt::IRContext* ir_context,
const TransformationContext& transformation_context) const override;
// Adds an OpConstantNull instruction to the module, with |message_.type_id|
// as its type. The instruction has result id |message_.fresh_id|.
void Apply(opt::IRContext* context,
void Apply(opt::IRContext* ir_context,
TransformationContext* transformation_context) const override;
std::unordered_set<uint32_t> GetFreshIds() const override;

View File

@ -20,8 +20,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddConstantScalar::TransformationAddConstantScalar(
const spvtools::fuzz::protobufs::TransformationAddConstantScalar& message)
: message_(message) {}
spvtools::fuzz::protobufs::TransformationAddConstantScalar message)
: message_(std::move(message)) {}
TransformationAddConstantScalar::TransformationAddConstantScalar(
uint32_t fresh_id, uint32_t type_id, const std::vector<uint32_t>& words,
@ -64,19 +64,21 @@ bool TransformationAddConstantScalar::IsApplicable(
void TransformationAddConstantScalar::Apply(
opt::IRContext* ir_context,
TransformationContext* transformation_context) const {
ir_context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpConstant, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_LITERAL_INTEGER,
std::vector<uint32_t>(message_.word().begin(),
message_.word().end())}})));
message_.word().end())}}));
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
// We have added an instruction to the module, so need to be careful about the
// validity of existing analyses.
ir_context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
// Inform the def-use manager about the new instruction. Invalidate the
// constant manager as we have added a new constant.
ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
if (message_.is_irrelevant()) {
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(

View File

@ -28,7 +28,7 @@ namespace fuzz {
class TransformationAddConstantScalar : public Transformation {
public:
explicit TransformationAddConstantScalar(
const protobufs::TransformationAddConstantScalar& message);
protobufs::TransformationAddConstantScalar message);
TransformationAddConstantScalar(uint32_t fresh_id, uint32_t type_id,
const std::vector<uint32_t>& words,

View File

@ -20,8 +20,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddGlobalUndef::TransformationAddGlobalUndef(
const spvtools::fuzz::protobufs::TransformationAddGlobalUndef& message)
: message_(message) {}
spvtools::fuzz::protobufs::TransformationAddGlobalUndef message)
: message_(std::move(message)) {}
TransformationAddGlobalUndef::TransformationAddGlobalUndef(uint32_t fresh_id,
uint32_t type_id) {
@ -42,14 +42,14 @@ bool TransformationAddGlobalUndef::IsApplicable(
void TransformationAddGlobalUndef::Apply(
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
ir_context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpUndef, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList()));
opt::Instruction::OperandList());
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
// We have added an instruction to the module, so need to be careful about the
// validity of existing analyses.
ir_context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
// Inform the def-use manager about the new instruction.
ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
}
protobufs::Transformation TransformationAddGlobalUndef::ToMessage() const {

View File

@ -26,7 +26,7 @@ namespace fuzz {
class TransformationAddGlobalUndef : public Transformation {
public:
explicit TransformationAddGlobalUndef(
const protobufs::TransformationAddGlobalUndef& message);
protobufs::TransformationAddGlobalUndef message);
TransformationAddGlobalUndef(uint32_t fresh_id, uint32_t type_id);

View File

@ -20,8 +20,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddGlobalVariable::TransformationAddGlobalVariable(
const spvtools::fuzz::protobufs::TransformationAddGlobalVariable& message)
: message_(message) {}
spvtools::fuzz::protobufs::TransformationAddGlobalVariable message)
: message_(std::move(message)) {}
TransformationAddGlobalVariable::TransformationAddGlobalVariable(
uint32_t fresh_id, uint32_t type_id, SpvStorageClass storage_class,
@ -93,15 +93,13 @@ bool TransformationAddGlobalVariable::IsApplicable(
void TransformationAddGlobalVariable::Apply(
opt::IRContext* ir_context,
TransformationContext* transformation_context) const {
fuzzerutil::AddGlobalVariable(
opt::Instruction* new_instruction = fuzzerutil::AddGlobalVariable(
ir_context, message_.fresh_id(), message_.type_id(),
static_cast<SpvStorageClass>(message_.storage_class()),
message_.initializer_id());
// We have added an instruction to the module, so need to be careful about the
// validity of existing analyses.
ir_context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
// Inform the def-use manager about the new instruction.
ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction);
if (message_.value_is_irrelevant()) {
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(

View File

@ -26,7 +26,7 @@ namespace fuzz {
class TransformationAddGlobalVariable : public Transformation {
public:
explicit TransformationAddGlobalVariable(
const protobufs::TransformationAddGlobalVariable& message);
protobufs::TransformationAddGlobalVariable message);
TransformationAddGlobalVariable(uint32_t fresh_id, uint32_t type_id,
SpvStorageClass storage_class,

View File

@ -20,8 +20,8 @@ namespace spvtools {
namespace fuzz {
TransformationAddLocalVariable::TransformationAddLocalVariable(
const spvtools::fuzz::protobufs::TransformationAddLocalVariable& message)
: message_(message) {}
spvtools::fuzz::protobufs::TransformationAddLocalVariable message)
: message_(std::move(message)) {}
TransformationAddLocalVariable::TransformationAddLocalVariable(
uint32_t fresh_id, uint32_t type_id, uint32_t function_id,
@ -70,11 +70,17 @@ bool TransformationAddLocalVariable::IsApplicable(
void TransformationAddLocalVariable::Apply(
opt::IRContext* ir_context,
TransformationContext* transformation_context) const {
fuzzerutil::AddLocalVariable(ir_context, message_.fresh_id(),
message_.type_id(), message_.function_id(),
message_.initializer_id());
opt::Instruction* new_instruction = fuzzerutil::AddLocalVariable(
ir_context, message_.fresh_id(), message_.type_id(),
message_.function_id(), message_.initializer_id());
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
// Inform the def-use manager about the new instruction.
ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction);
ir_context->set_instr_block(
new_instruction,
fuzzerutil::FindFunction(ir_context, message_.function_id())
->entry()
.get());
if (message_.value_is_irrelevant()) {
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(

View File

@ -26,7 +26,7 @@ namespace fuzz {
class TransformationAddLocalVariable : public Transformation {
public:
explicit TransformationAddLocalVariable(
const protobufs::TransformationAddLocalVariable& message);
protobufs::TransformationAddLocalVariable message);
TransformationAddLocalVariable(uint32_t fresh_id, uint32_t type_id,
uint32_t function_id, uint32_t initializer_id,

View File

@ -46,6 +46,7 @@ TEST(TransformationAddConstantBooleanTest, NeitherPresentInitiallyAddBoth) {
spvtools::ValidatorOptions validator_options;
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
// True and false can both be added as neither is present.
@ -68,7 +69,14 @@ TEST(TransformationAddConstantBooleanTest, NeitherPresentInitiallyAddBoth) {
auto add_false = TransformationAddConstantBoolean(8, false, false);
ASSERT_TRUE(add_true.IsApplicable(context.get(), transformation_context));
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(7));
ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(7));
ApplyAndCheckFreshIds(add_true, context.get(), &transformation_context);
ASSERT_EQ(SpvOpConstantTrue, context->get_def_use_mgr()->GetDef(7)->opcode());
ASSERT_TRUE(context->get_constant_mgr()
->FindDeclaredConstant(7)
->AsBoolConstant()
->value());
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));

View File

@ -82,10 +82,30 @@ TEST(TransformationAddConstantCompositeTest, BasicTest) {
ASSERT_FALSE(TransformationAddConstantComposite(100, 39, {11, 12}, false)
.IsApplicable(context.get(), transformation_context));
TransformationAddConstantComposite transformations[] = {
// %100 = OpConstantComposite %7 %11 %12
TransformationAddConstantComposite(100, 7, {11, 12}, false),
{
// %100 = OpConstantComposite %7 %11 %12
TransformationAddConstantComposite transformation(100, 7, {11, 12}, false);
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(100));
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_EQ(SpvOpConstantComposite,
context->get_def_use_mgr()->GetDef(100)->opcode());
ASSERT_EQ(0.0F, context->get_constant_mgr()
->FindDeclaredConstant(100)
->AsVectorConstant()
->GetComponents()[0]
->GetFloat());
ASSERT_EQ(1.0F, context->get_constant_mgr()
->FindDeclaredConstant(100)
->AsVectorConstant()
->GetComponents()[1]
->GetFloat());
}
TransformationAddConstantComposite transformations[] = {
// %101 = OpConstantComposite %7 %14 %15
TransformationAddConstantComposite(101, 7, {14, 15}, false),

View File

@ -78,9 +78,23 @@ TEST(TransformationAddConstantNullTest, BasicTest) {
ASSERT_FALSE(TransformationAddConstantNull(100, 22).IsApplicable(
context.get(), transformation_context));
{
// %100 = OpConstantNull %6
TransformationAddConstantNull transformation(100, 6);
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(100));
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_EQ(SpvOpConstantNull,
context->get_def_use_mgr()->GetDef(100)->opcode());
ASSERT_EQ(
0.0F,
context->get_constant_mgr()->FindDeclaredConstant(100)->GetFloat());
}
TransformationAddConstantNull transformations[] = {
// %100 = OpConstantNull %6
TransformationAddConstantNull(100, 6),
// %101 = OpConstantNull %7
TransformationAddConstantNull(101, 7),

View File

@ -171,7 +171,11 @@ TEST(TransformationAddConstantScalarTest, Apply) {
MakeUnique<FactManager>(context.get()), validator_options);
// Adds 32-bit unsigned integer (1 logical operand with 1 word).
auto transformation = TransformationAddConstantScalar(19, 2, {4}, false);
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(19));
ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(19));
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_EQ(SpvOpConstant, context->get_def_use_mgr()->GetDef(19)->opcode());
ASSERT_EQ(4, context->get_constant_mgr()->FindDeclaredConstant(19)->GetU32());
auto* constant_instruction = context->get_def_use_mgr()->GetDef(19);
EXPECT_EQ(constant_instruction->NumInOperands(), 1);
EXPECT_EQ(constant_instruction->NumInOperandWords(), 1);

View File

@ -63,9 +63,18 @@ TEST(TransformationAddGlobalUndefTest, BasicTest) {
ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable(
context.get(), transformation_context));
{
// %100 = OpUndef %6
TransformationAddGlobalUndef transformation(100, 6);
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_EQ(SpvOpUndef, context->get_def_use_mgr()->GetDef(100)->opcode());
}
TransformationAddGlobalUndef transformations[] = {
// %100 = OpUndef %6
TransformationAddGlobalUndef(100, 6),
// %101 = OpUndef %7
TransformationAddGlobalUndef(101, 7),

View File

@ -118,11 +118,24 @@ TEST(TransformationAddGlobalVariableTest, BasicTest) {
14, false)
.IsApplicable(context.get(), transformation_context));
TransformationAddGlobalVariable transformations[] = {
// %100 = OpVariable %12 Private
TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, 16,
true),
{
// %100 = OpVariable %12 Private
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
TransformationAddGlobalVariable transformation(
100, 12, SpvStorageClassPrivate, 16, true);
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(100)->opcode());
ASSERT_EQ(
SpvStorageClassPrivate,
static_cast<SpvStorageClass>(
context->get_def_use_mgr()->GetDef(100)->GetSingleWordInOperand(
0)));
}
TransformationAddGlobalVariable transformations[] = {
// %101 = OpVariable %10 Private
TransformationAddGlobalVariable(101, 10, SpvStorageClassPrivate, 40,
false),

View File

@ -98,10 +98,14 @@ TEST(TransformationAddLocalVariableTest, BasicTest) {
// %105 = OpVariable %50 Function %51
{
TransformationAddLocalVariable transformation(105, 50, 4, 51, true);
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(105));
ASSERT_EQ(nullptr, context->get_instr_block(105));
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(105)->opcode());
ASSERT_EQ(5, context->get_instr_block(105)->id());
}
// %104 = OpVariable %41 Function %46