spirv-fuzz: consider additional access chain instructions (#3672)
`TransformationReplaceIdWithSynonym` is careful to avoid replacing id uses that index into a struct with synonyms because the indices must only be `OpConstant` instructions. However, the check only considered `OpAccessChain` instructions, even though the same restriction applies to `OpInBoundsAccessChain`, `OpPtrAccessChain`, etc.
This change extends the check to include all access chain instructions.
Fixes #3671.
diff --git a/source/fuzz/transformation_replace_id_with_synonym.cpp b/source/fuzz/transformation_replace_id_with_synonym.cpp
index fbbeab2..8ebfbe0 100644
--- a/source/fuzz/transformation_replace_id_with_synonym.cpp
+++ b/source/fuzz/transformation_replace_id_with_synonym.cpp
@@ -109,7 +109,7 @@
bool TransformationReplaceIdWithSynonym::UseCanBeReplacedWithSynonym(
opt::IRContext* ir_context, opt::Instruction* use_instruction,
uint32_t use_in_operand_index) {
- if (use_instruction->opcode() == SpvOpAccessChain &&
+ if (spvOpcodeIsAccessChain(use_instruction->opcode()) &&
use_in_operand_index > 0) {
// This is an access chain index. If the (sub-)object being accessed by the
// given index has struct type then we cannot replace the use with a
diff --git a/test/fuzz/transformation_replace_id_with_synonym_test.cpp b/test/fuzz/transformation_replace_id_with_synonym_test.cpp
index 33713c2..fa0f6bb 100644
--- a/test/fuzz/transformation_replace_id_with_synonym_test.cpp
+++ b/test/fuzz/transformation_replace_id_with_synonym_test.cpp
@@ -807,7 +807,7 @@
OpStore %53 %32
%56 = OpAccessChain %23 %50 %17 %21 %21 %55
OpStore %56 %54
- %58 = OpAccessChain %26 %50 %57 %21 %17
+ %58 = OpInBoundsAccessChain %26 %50 %57 %21 %17
OpStore %58 %45
OpReturn
OpFunctionEnd
@@ -1032,12 +1032,12 @@
ASSERT_FALSE(
replacement17.IsApplicable(context.get(), transformation_context));
- // %58 = OpAccessChain %26 %50 %57 *%21* %17
+ // %58 = OpInBoundsAccessChain %26 %50 %57 *%21* %17
// Corresponds to i[3].*g*.c
// The index %24 used for g cannot be replaced
auto replacement18 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(
- 21, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 2),
+ 21, MakeInstructionDescriptor(58, SpvOpInBoundsAccessChain, 0), 2),
101);
ASSERT_FALSE(
replacement18.IsApplicable(context.get(), transformation_context));
@@ -1088,24 +1088,24 @@
replacement22.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- // %58 = OpAccessChain %26 %50 %57 %21 %17
+ // %58 = OpInBoundsAccessChain %26 %50 %57 %21 %17
// Corresponds to i[3].g.*c*
// The index %17 used for c cannot be replaced
auto replacement23 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(
- 17, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 3),
+ 17, MakeInstructionDescriptor(58, SpvOpInBoundsAccessChain, 0), 3),
102);
ASSERT_FALSE(
replacement23.IsApplicable(context.get(), transformation_context));
// Replacements of the form %57 -> %103
- // %58 = OpAccessChain %26 %50 *%57* %21 %17
+ // %58 = OpInBoundsAccessChain %26 %50 *%57* %21 %17
// Corresponds to i[*3*].g.c
// The index %57 used for 3 *can* be replaced
auto replacement24 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(
- 57, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 1),
+ 57, MakeInstructionDescriptor(58, SpvOpInBoundsAccessChain, 0), 1),
103);
ASSERT_TRUE(
replacement24.IsApplicable(context.get(), transformation_context));
@@ -1269,7 +1269,7 @@
OpStore %53 %32
%56 = OpAccessChain %23 %50 %102 %21 %21 %108
OpStore %56 %54
- %58 = OpAccessChain %26 %50 %103 %21 %17
+ %58 = OpInBoundsAccessChain %26 %50 %103 %21 %17
OpStore %58 %45
OpReturn
OpFunctionEnd