Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
swiftshader
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
swiftshader
Commits
612ded06
Commit
612ded06
authored
Nov 05, 2020
by
Sean Risser
Browse files
Options
Browse Files
Download
Plain Diff
Merge changes I3c4f10f7,I5b7ddc75
* changes: Update SPIR-V Tools to a61d07a72 Squashed 'third_party/SPIRV-Tools/' changes from f7da52775..a61d07a72
parents
1a599631
f95bac4e
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
940 additions
and
311 deletions
+940
-311
data_synonym_and_id_equation_facts.cpp
.../fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp
+0
-6
fuzzer.cpp
third_party/SPIRV-Tools/source/fuzz/fuzzer.cpp
+20
-6
fuzzer_context.cpp
third_party/SPIRV-Tools/source/fuzz/fuzzer_context.cpp
+15
-4
fuzzer_context.h
third_party/SPIRV-Tools/source/fuzz/fuzzer_context.h
+116
-85
fuzzer_pass_add_bit_instruction_synonyms.cpp
.../source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.cpp
+7
-0
fuzzer_pass_add_composite_extract.cpp
...V-Tools/source/fuzz/fuzzer_pass_add_composite_extract.cpp
+34
-29
fuzzer_pass_flatten_conditional_branches.cpp
.../source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp
+3
-2
repeated_pass_manager_random_with_recommendations.cpp
...ent/repeated_pass_manager_random_with_recommendations.cpp
+2
-0
transformation_add_bit_instruction_synonym.cpp
...ource/fuzz/transformation_add_bit_instruction_synonym.cpp
+2
-1
transformation_flatten_conditional_branch.cpp
...source/fuzz/transformation_flatten_conditional_branch.cpp
+95
-66
transformation_flatten_conditional_branch.h
...s/source/fuzz/transformation_flatten_conditional_branch.h
+5
-4
debug_info_manager.cpp
third_party/SPIRV-Tools/source/opt/debug_info_manager.cpp
+13
-7
debug_info_manager.h
third_party/SPIRV-Tools/source/opt/debug_info_manager.h
+5
-4
local_single_store_elim_pass.cpp
...y/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp
+29
-4
local_single_store_elim_pass.h
...rty/SPIRV-Tools/source/opt/local_single_store_elim_pass.h
+4
-0
optimizer.cpp
third_party/SPIRV-Tools/source/opt/optimizer.cpp
+1
-0
ssa_rewrite_pass.cpp
third_party/SPIRV-Tools/source/opt/ssa_rewrite_pass.cpp
+85
-21
validate_builtins.cpp
third_party/SPIRV-Tools/source/val/validate_builtins.cpp
+18
-15
validation_state.cpp
third_party/SPIRV-Tools/source/val/validation_state.cpp
+20
-0
transformation_add_bit_instruction_synonym_test.cpp
.../fuzz/transformation_add_bit_instruction_synonym_test.cpp
+85
-53
transformation_flatten_conditional_branch_test.cpp
...t/fuzz/transformation_flatten_conditional_branch_test.cpp
+94
-0
local_single_store_elim_test.cpp
...rty/SPIRV-Tools/test/opt/local_single_store_elim_test.cpp
+231
-0
local_ssa_elim_test.cpp
third_party/SPIRV-Tools/test/opt/local_ssa_elim_test.cpp
+38
-0
flags.py
third_party/SPIRV-Tools/test/tools/opt/flags.py
+1
-0
val_builtins_test.cpp
third_party/SPIRV-Tools/test/val/val_builtins_test.cpp
+17
-4
No files found.
third_party/SPIRV-Tools/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp
View file @
612ded06
...
...
@@ -176,12 +176,6 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
// We can thus infer "a = d"
AddDataSynonymFactRecursive
(
lhs_dd
,
*
equation
.
operands
[
0
]);
}
if
(
synonymous_
.
IsEquivalent
(
*
equation
.
operands
[
0
],
*
rhs_dds
[
1
]))
{
// Equation form: "a = (c - e) + c"
// We can thus infer "a = -e"
AddEquationFactRecursive
(
lhs_dd
,
SpvOpSNegate
,
{
equation
.
operands
[
1
]});
}
}
}
for
(
const
auto
&
equation
:
GetEquations
(
rhs_dds
[
1
]))
{
...
...
third_party/SPIRV-Tools/source/fuzz/fuzzer.cpp
View file @
612ded06
...
...
@@ -107,8 +107,6 @@ namespace fuzz {
namespace
{
const
uint32_t
kIdBoundGap
=
100
;
const
uint32_t
kTransformationLimit
=
2000
;
}
// namespace
Fuzzer
::
Fuzzer
(
spv_target_env
target_env
,
MessageConsumer
consumer
,
...
...
@@ -367,21 +365,37 @@ bool Fuzzer::ShouldContinueFuzzing() {
// that fuzzing stops if the number of repeated passes hits the limit on the
// number of transformations that can be applied.
assert
(
num_repeated_passes_applied_
<=
kTransformationLimit
&&
num_repeated_passes_applied_
<=
fuzzer_context_
->
GetTransformationLimit
()
&&
"The number of repeated passes applied must not exceed its upper limit."
);
if
(
num_repeated_passes_applied_
==
kTransformationLimit
)
{
if
(
ir_context_
->
module
()
->
id_bound
()
>=
fuzzer_context_
->
GetIdBoundLimit
())
{
return
false
;
}
if
(
num_repeated_passes_applied_
==
fuzzer_context_
->
GetTransformationLimit
())
{
// Stop because fuzzing has got stuck.
return
false
;
}
auto
transformations_applied_so_far
=
static_cast
<
uint32_t
>
(
transformation_sequence_out_
.
transformation_size
());
if
(
transformations_applied_so_far
>=
kTransformationLimit
)
{
if
(
transformations_applied_so_far
>=
fuzzer_context_
->
GetTransformationLimit
())
{
// Stop because we have reached the transformation limit.
return
false
;
}
// If we have applied T transformations so far, and the limit on the number of
// transformations to apply is L (where T < L), the chance that we will
// continue fuzzing is:
//
// 1 - T/(2*L)
//
// That is, the chance of continuing decreases as more transformations are
// applied. Using 2*L instead of L increases the number of transformations
// that are applied on average.
auto
chance_of_continuing
=
static_cast
<
uint32_t
>
(
100.0
*
(
1.0
-
(
static_cast
<
double
>
(
transformations_applied_so_far
)
/
static_cast
<
double
>
(
kTransformationLimit
))));
(
2.0
*
static_cast
<
double
>
(
fuzzer_context_
->
GetTransformationLimit
())))));
if
(
!
fuzzer_context_
->
ChoosePercentage
(
chance_of_continuing
))
{
// We have probabilistically decided to stop.
return
false
;
...
...
third_party/SPIRV-Tools/source/fuzz/fuzzer_context.cpp
View file @
612ded06
...
...
@@ -20,14 +20,19 @@ namespace spvtools {
namespace
fuzz
{
namespace
{
// Limits to help control the overall fuzzing process and rein in individual
// fuzzer passes.
const
uint32_t
kIdBoundLimit
=
50000
;
const
uint32_t
kTransformationLimit
=
2000
;
// Default <minimum, maximum> pairs of probabilities for applying various
// transformations. All values are percentages. Keep them in alphabetical order.
const
std
::
pair
<
uint32_t
,
uint32_t
>
kChanceOfAcceptingRepeatedPassRecommendation
=
{
70
,
10
0
};
kChanceOfAcceptingRepeatedPassRecommendation
=
{
50
,
8
0
};
const
std
::
pair
<
uint32_t
,
uint32_t
>
kChanceOfAddingAccessChain
=
{
5
,
50
};
const
std
::
pair
<
uint32_t
,
uint32_t
>
kChanceOfAddingAnotherPassToPassLoop
=
{
85
,
9
5
};
const
std
::
pair
<
uint32_t
,
uint32_t
>
kChanceOfAddingAnotherPassToPassLoop
=
{
50
,
9
0
};
const
std
::
pair
<
uint32_t
,
uint32_t
>
kChanceOfAddingAnotherStructField
=
{
20
,
90
};
const
std
::
pair
<
uint32_t
,
uint32_t
>
kChanceOfAddingArrayOrStructType
=
{
20
,
90
};
...
...
@@ -392,5 +397,11 @@ FuzzerContext::GetRandomSynonymType() {
return
static_cast
<
protobufs
::
TransformationAddSynonym
::
SynonymType
>
(
result
);
}
uint32_t
FuzzerContext
::
GetIdBoundLimit
()
const
{
return
kIdBoundLimit
;
}
uint32_t
FuzzerContext
::
GetTransformationLimit
()
const
{
return
kTransformationLimit
;
}
}
// namespace fuzz
}
// namespace spvtools
third_party/SPIRV-Tools/source/fuzz/fuzzer_context.h
View file @
612ded06
...
...
@@ -104,240 +104,271 @@ class FuzzerContext {
// Returns a vector of |count| fresh ids.
std
::
vector
<
uint32_t
>
GetFreshIds
(
const
uint32_t
count
);
// A suggested limit on the id bound for the module being fuzzed. This is
// useful for deciding when to stop the overall fuzzing process. Furthermore,
// fuzzer passes that run the risk of spiralling out of control can
// periodically check this limit and terminate early if it has been reached.
uint32_t
GetIdBoundLimit
()
const
;
// A suggested limit on the number of transformations that should be applied.
// Also useful to control the overall fuzzing process and rein in individual
// fuzzer passes.
uint32_t
GetTransformationLimit
()
const
;
// Probabilities associated with applying various transformations.
// Keep them in alphabetical order.
uint32_t
GetChanceOfAcceptingRepeatedPassRecommendation
()
{
uint32_t
GetChanceOfAcceptingRepeatedPassRecommendation
()
const
{
return
chance_of_accepting_repeated_pass_recommendation_
;
}
uint32_t
GetChanceOfAddingAccessChain
()
{
uint32_t
GetChanceOfAddingAccessChain
()
const
{
return
chance_of_adding_access_chain_
;
}
uint32_t
GetChanceOfAddingAnotherPassToPassLoop
()
{
uint32_t
GetChanceOfAddingAnotherPassToPassLoop
()
const
{
return
chance_of_adding_another_pass_to_pass_loop_
;
}
uint32_t
GetChanceOfAddingAnotherStructField
()
{
uint32_t
GetChanceOfAddingAnotherStructField
()
const
{
return
chance_of_adding_another_struct_field_
;
}
uint32_t
GetChanceOfAddingArrayOrStructType
()
{
uint32_t
GetChanceOfAddingArrayOrStructType
()
const
{
return
chance_of_adding_array_or_struct_type_
;
}
uint32_t
GetChanceOfAddingBitInstructionSynonym
()
{
uint32_t
GetChanceOfAddingBitInstructionSynonym
()
const
{
return
chance_of_adding_bit_instruction_synonym_
;
}
uint32_t
GetChanceOfAddingBothBranchesWhenReplacingOpSelect
()
{
uint32_t
GetChanceOfAddingBothBranchesWhenReplacingOpSelect
()
const
{
return
chance_of_adding_both_branches_when_replacing_opselect_
;
}
uint32_t
GetChanceOfAddingCompositeExtract
()
{
uint32_t
GetChanceOfAddingCompositeExtract
()
const
{
return
chance_of_adding_composite_extract_
;
}
uint32_t
GetChanceOfAddingCompositeInsert
()
{
uint32_t
GetChanceOfAddingCompositeInsert
()
const
{
return
chance_of_adding_composite_insert_
;
}
uint32_t
GetChanceOfAddingCopyMemory
()
{
uint32_t
GetChanceOfAddingCopyMemory
()
const
{
return
chance_of_adding_copy_memory_
;
}
uint32_t
GetChanceOfAddingDeadBlock
()
{
return
chance_of_adding_dead_block_
;
}
uint32_t
GetChanceOfAddingDeadBreak
()
{
return
chance_of_adding_dead_break_
;
}
uint32_t
GetChanceOfAddingDeadContinue
()
{
uint32_t
GetChanceOfAddingDeadBlock
()
const
{
return
chance_of_adding_dead_block_
;
}
uint32_t
GetChanceOfAddingDeadBreak
()
const
{
return
chance_of_adding_dead_break_
;
}
uint32_t
GetChanceOfAddingDeadContinue
()
const
{
return
chance_of_adding_dead_continue_
;
}
uint32_t
GetChanceOfAddingEquationInstruction
()
{
uint32_t
GetChanceOfAddingEquationInstruction
()
const
{
return
chance_of_adding_equation_instruction_
;
}
uint32_t
GetChanceOfAddingGlobalVariable
()
{
uint32_t
GetChanceOfAddingGlobalVariable
()
const
{
return
chance_of_adding_global_variable_
;
}
uint32_t
GetChanceOfAddingImageSampleUnusedComponents
()
{
uint32_t
GetChanceOfAddingImageSampleUnusedComponents
()
const
{
return
chance_of_adding_image_sample_unused_components_
;
}
uint32_t
GetChanceOfAddingLoad
()
{
return
chance_of_adding_load_
;
}
uint32_t
GetChanceOfAddingLocalVariable
()
{
uint32_t
GetChanceOfAddingLoad
()
const
{
return
chance_of_adding_load_
;
}
uint32_t
GetChanceOfAddingLocalVariable
()
const
{
return
chance_of_adding_local_variable_
;
}
uint32_t
GetChanceOfAddingLoopPreheader
()
{
uint32_t
GetChanceOfAddingLoopPreheader
()
const
{
return
chance_of_adding_loop_preheader_
;
}
uint32_t
GetChanceOfAddingMatrixType
()
{
uint32_t
GetChanceOfAddingMatrixType
()
const
{
return
chance_of_adding_matrix_type_
;
}
uint32_t
GetChanceOfAddingNoContractionDecoration
()
{
uint32_t
GetChanceOfAddingNoContractionDecoration
()
const
{
return
chance_of_adding_no_contraction_decoration_
;
}
uint32_t
GetChanceOfAddingOpPhiSynonym
()
{
uint32_t
GetChanceOfAddingOpPhiSynonym
()
const
{
return
chance_of_adding_opphi_synonym_
;
}
uint32_t
GetChanceOfAddingParameters
()
{
return
chance_of_adding_parameters
;
}
uint32_t
GetChanceOfAddingRelaxedDecoration
()
{
uint32_t
GetChanceOfAddingParameters
()
const
{
return
chance_of_adding_parameters
;
}
uint32_t
GetChanceOfAddingRelaxedDecoration
()
const
{
return
chance_of_adding_relaxed_decoration_
;
}
uint32_t
GetChanceOfAddingStore
()
{
return
chance_of_adding_store_
;
}
uint32_t
GetChanceOfAddingSynonyms
()
{
return
chance_of_adding_synonyms_
;
}
uint32_t
GetChanceOfAddingTrueBranchWhenReplacingOpSelect
()
{
uint32_t
GetChanceOfAddingStore
()
const
{
return
chance_of_adding_store_
;
}
uint32_t
GetChanceOfAddingSynonyms
()
const
{
return
chance_of_adding_synonyms_
;
}
uint32_t
GetChanceOfAddingTrueBranchWhenReplacingOpSelect
()
const
{
return
chance_of_adding_true_branch_when_replacing_opselect_
;
}
uint32_t
GetChanceOfAddingVectorShuffle
()
{
uint32_t
GetChanceOfAddingVectorShuffle
()
const
{
return
chance_of_adding_vector_shuffle_
;
}
uint32_t
GetChanceOfAddingVectorType
()
{
uint32_t
GetChanceOfAddingVectorType
()
const
{
return
chance_of_adding_vector_type_
;
}
uint32_t
GetChanceOfAdjustingBranchWeights
()
{
uint32_t
GetChanceOfAdjustingBranchWeights
()
const
{
return
chance_of_adjusting_branch_weights_
;
}
uint32_t
GetChanceOfAdjustingFunctionControl
()
{
uint32_t
GetChanceOfAdjustingFunctionControl
()
const
{
return
chance_of_adjusting_function_control_
;
}
uint32_t
GetChanceOfAdjustingLoopControl
()
{
uint32_t
GetChanceOfAdjustingLoopControl
()
const
{
return
chance_of_adjusting_loop_control_
;
}
uint32_t
GetChanceOfAdjustingMemoryOperandsMask
()
{
uint32_t
GetChanceOfAdjustingMemoryOperandsMask
()
const
{
return
chance_of_adjusting_memory_operands_mask_
;
}
uint32_t
GetChanceOfAdjustingSelectionControl
()
{
uint32_t
GetChanceOfAdjustingSelectionControl
()
const
{
return
chance_of_adjusting_selection_control_
;
}
uint32_t
GetChanceOfCallingFunction
()
{
return
chance_of_calling_function_
;
}
uint32_t
GetChanceOfChoosingStructTypeVsArrayType
()
{
uint32_t
GetChanceOfCallingFunction
()
const
{
return
chance_of_calling_function_
;
}
uint32_t
GetChanceOfChoosingStructTypeVsArrayType
()
const
{
return
chance_of_choosing_struct_type_vs_array_type_
;
}
uint32_t
GetChanceOfChoosingWorkgroupStorageClass
()
{
uint32_t
GetChanceOfChoosingWorkgroupStorageClass
()
const
{
return
chance_of_choosing_workgroup_storage_class_
;
}
uint32_t
GetChanceOfConstructingComposite
()
{
uint32_t
GetChanceOfConstructingComposite
()
const
{
return
chance_of_constructing_composite_
;
}
uint32_t
GetChanceOfCopyingObject
()
{
return
chance_of_copying_object_
;
}
uint32_t
GetChanceOfCreatingIntSynonymsUsingLoops
()
{
uint32_t
GetChanceOfCopyingObject
()
const
{
return
chance_of_copying_object_
;
}
uint32_t
GetChanceOfCreatingIntSynonymsUsingLoops
()
const
{
return
chance_of_creating_int_synonyms_using_loops_
;
}
uint32_t
GetChanceOfDonatingAdditionalModule
()
{
uint32_t
GetChanceOfDonatingAdditionalModule
()
const
{
return
chance_of_donating_additional_module_
;
}
uint32_t
GetChanceOfDuplicatingRegionWithSelection
()
{
uint32_t
GetChanceOfDuplicatingRegionWithSelection
()
const
{
return
chance_of_duplicating_region_with_selection_
;
}
uint32_t
GetChanceOfExpandingVectorReduction
()
{
uint32_t
GetChanceOfExpandingVectorReduction
()
const
{
return
chance_of_expanding_vector_reduction_
;
}
uint32_t
GetChanceOfFlatteningConditionalBranch
()
{
uint32_t
GetChanceOfFlatteningConditionalBranch
()
const
{
return
chance_of_flattening_conditional_branch_
;
}
uint32_t
GetChanceOfGoingDeeperToExtractComposite
()
{
uint32_t
GetChanceOfGoingDeeperToExtractComposite
()
const
{
return
chance_of_going_deeper_to_extract_composite_
;
}
uint32_t
GetChanceOfGoingDeeperToInsertInComposite
()
{
uint32_t
GetChanceOfGoingDeeperToInsertInComposite
()
const
{
return
chance_of_going_deeper_to_insert_in_composite_
;
}
uint32_t
GetChanceOfGoingDeeperWhenMakingAccessChain
()
{
uint32_t
GetChanceOfGoingDeeperWhenMakingAccessChain
()
const
{
return
chance_of_going_deeper_when_making_access_chain_
;
}
uint32_t
GetChanceOfHavingTwoBlocksInLoopToCreateIntSynonym
()
{
uint32_t
GetChanceOfHavingTwoBlocksInLoopToCreateIntSynonym
()
const
{
return
chance_of_having_two_blocks_in_loop_to_create_int_synonym_
;
}
uint32_t
GetChanceOfInliningFunction
()
{
uint32_t
GetChanceOfInliningFunction
()
const
{
return
chance_of_inlining_function_
;
}
uint32_t
GetChanceOfInterchangingSignednessOfIntegerOperands
()
{
uint32_t
GetChanceOfInterchangingSignednessOfIntegerOperands
()
const
{
return
chance_of_interchanging_signedness_of_integer_operands_
;
}
uint32_t
GetChanceOfInterchangingZeroLikeConstants
()
{
uint32_t
GetChanceOfInterchangingZeroLikeConstants
()
const
{
return
chance_of_interchanging_zero_like_constants_
;
}
uint32_t
GetChanceOfInvertingComparisonOperators
()
{
uint32_t
GetChanceOfInvertingComparisonOperators
()
const
{
return
chance_of_inverting_comparison_operators_
;
}
uint32_t
ChanceOfMakingDonorLivesafe
()
{
uint32_t
ChanceOfMakingDonorLivesafe
()
const
{
return
chance_of_making_donor_livesafe_
;
}
uint32_t
GetChanceOfMakingVectorOperationDynamic
()
{
uint32_t
GetChanceOfMakingVectorOperationDynamic
()
const
{
return
chance_of_making_vector_operation_dynamic_
;
}
uint32_t
GetChanceOfMergingBlocks
()
{
return
chance_of_merging_blocks_
;
}
uint32_t
GetChanceOfMergingFunctionReturns
()
{
uint32_t
GetChanceOfMergingBlocks
()
const
{
return
chance_of_merging_blocks_
;
}
uint32_t
GetChanceOfMergingFunctionReturns
()
const
{
return
chance_of_merging_function_returns_
;
}
uint32_t
GetChanceOfMovingBlockDown
()
{
return
chance_of_moving_block_down_
;
}
uint32_t
GetChanceOfMutatingPointer
()
{
return
chance_of_mutating_pointer_
;
}
uint32_t
GetChanceOfObfuscatingConstant
()
{
uint32_t
GetChanceOfMovingBlockDown
()
const
{
return
chance_of_moving_block_down_
;
}
uint32_t
GetChanceOfMutatingPointer
()
const
{
return
chance_of_mutating_pointer_
;
}
uint32_t
GetChanceOfObfuscatingConstant
()
const
{
return
chance_of_obfuscating_constant_
;
}
uint32_t
GetChanceOfOutliningFunction
()
{
uint32_t
GetChanceOfOutliningFunction
()
const
{
return
chance_of_outlining_function_
;
}
uint32_t
GetChanceOfPermutingInstructions
()
{
uint32_t
GetChanceOfPermutingInstructions
()
const
{
return
chance_of_permuting_instructions_
;
}
uint32_t
GetChanceOfPermutingParameters
()
{
uint32_t
GetChanceOfPermutingParameters
()
const
{
return
chance_of_permuting_parameters_
;
}
uint32_t
GetChanceOfPermutingPhiOperands
()
{
uint32_t
GetChanceOfPermutingPhiOperands
()
const
{
return
chance_of_permuting_phi_operands_
;
}
uint32_t
GetChanceOfPropagatingInstructionsDown
()
{
uint32_t
GetChanceOfPropagatingInstructionsDown
()
const
{
return
chance_of_propagating_instructions_down_
;
}
uint32_t
GetChanceOfPropagatingInstructionsUp
()
{
uint32_t
GetChanceOfPropagatingInstructionsUp
()
const
{
return
chance_of_propagating_instructions_up_
;
}
uint32_t
GetChanceOfPushingIdThroughVariable
()
{
uint32_t
GetChanceOfPushingIdThroughVariable
()
const
{
return
chance_of_pushing_id_through_variable_
;
}
uint32_t
GetChanceOfReplacingAddSubMulWithCarryingExtended
()
{
uint32_t
GetChanceOfReplacingAddSubMulWithCarryingExtended
()
const
{
return
chance_of_replacing_add_sub_mul_with_carrying_extended_
;
}
uint32_t
GetChanceOfReplacingBranchFromDeadBlockWithExit
()
{
uint32_t
GetChanceOfReplacingBranchFromDeadBlockWithExit
()
const
{
return
chance_of_replacing_branch_from_dead_block_with_exit_
;
}
uint32_t
GetChanceOfReplacingCopyMemoryWithLoadStore
()
{
uint32_t
GetChanceOfReplacingCopyMemoryWithLoadStore
()
const
{
return
chance_of_replacing_copy_memory_with_load_store_
;
}
uint32_t
GetChanceOfReplacingCopyObjectWithStoreLoad
()
{
uint32_t
GetChanceOfReplacingCopyObjectWithStoreLoad
()
const
{
return
chance_of_replacing_copyobject_with_store_load_
;
}
uint32_t
GetChanceOfReplacingIdWithSynonym
()
{
uint32_t
GetChanceOfReplacingIdWithSynonym
()
const
{
return
chance_of_replacing_id_with_synonym_
;
}
uint32_t
GetChanceOfReplacingIrrelevantId
()
{
uint32_t
GetChanceOfReplacingIrrelevantId
()
const
{
return
chance_of_replacing_irrelevant_id_
;
}
uint32_t
GetChanceOfReplacingLinearAlgebraInstructions
()
{
uint32_t
GetChanceOfReplacingLinearAlgebraInstructions
()
const
{
return
chance_of_replacing_linear_algebra_instructions_
;
}
uint32_t
GetChanceOfReplacingLoadStoreWithCopyMemory
()
{
uint32_t
GetChanceOfReplacingLoadStoreWithCopyMemory
()
const
{
return
chance_of_replacing_load_store_with_copy_memory_
;
}
uint32_t
GetChanceOfReplacingOpPhiIdFromDeadPredecessor
()
{
uint32_t
GetChanceOfReplacingOpPhiIdFromDeadPredecessor
()
const
{
return
chance_of_replacing_opphi_id_from_dead_predecessor_
;
}
uint32_t
GetChanceOfReplacingOpselectWithConditionalBranch
()
{
uint32_t
GetChanceOfReplacingOpselectWithConditionalBranch
()
const
{
return
chance_of_replacing_opselect_with_conditional_branch_
;
}
uint32_t
GetChanceOfReplacingParametersWithGlobals
()
{
uint32_t
GetChanceOfReplacingParametersWithGlobals
()
const
{
return
chance_of_replacing_parameters_with_globals_
;
}
uint32_t
GetChanceOfReplacingParametersWithStruct
()
{
uint32_t
GetChanceOfReplacingParametersWithStruct
()
const
{
return
chance_of_replacing_parameters_with_struct_
;
}
uint32_t
GetChanceOfSplittingBlock
()
{
return
chance_of_splitting_block_
;
}
uint32_t
GetChanceOfSwappingConditionalBranchOperands
()
{
uint32_t
GetChanceOfSplittingBlock
()
const
{
return
chance_of_splitting_block_
;
}
uint32_t
GetChanceOfSwappingConditionalBranchOperands
()
const
{
return
chance_of_swapping_conditional_branch_operands_
;
}
uint32_t
GetChanceOfTogglingAccessChainInstruction
()
{
uint32_t
GetChanceOfTogglingAccessChainInstruction
()
const
{
return
chance_of_toggling_access_chain_instruction_
;
}
uint32_t
GetChanceOfWrappingRegionInSelection
()
{
uint32_t
GetChanceOfWrappingRegionInSelection
()
const
{
return
chance_of_wrapping_region_in_selection_
;
}
// Other functions to control transformations. Keep them in alphabetical
// order.
uint32_t
GetMaximumEquivalenceClassSizeForDataSynonymFactClosure
()
{
uint32_t
GetMaximumEquivalenceClassSizeForDataSynonymFactClosure
()
const
{
return
max_equivalence_class_size_for_data_synonym_fact_closure_
;
}
uint32_t
GetMaximumNumberOfFunctionParameters
()
{
uint32_t
GetMaximumNumberOfFunctionParameters
()
const
{
return
max_number_of_function_parameters_
;
}
uint32_t
GetMaximumNumberOfParametersReplacedWithStruct
()
{
uint32_t
GetMaximumNumberOfParametersReplacedWithStruct
()
const
{
return
max_number_of_parameters_replaced_with_struct_
;
}
std
::
pair
<
uint32_t
,
uint32_t
>
GetRandomBranchWeights
()
{
...
...
third_party/SPIRV-Tools/source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.cpp
View file @
612ded06
...
...
@@ -35,6 +35,13 @@ void FuzzerPassAddBitInstructionSynonyms::Apply() {
for
(
auto
&
function
:
*
GetIRContext
()
->
module
())
{
for
(
auto
&
block
:
function
)
{
for
(
auto
&
instruction
:
block
)
{
// This fuzzer pass can add a *lot* of ids. We bail out early if we hit
// the recommended id limit.
if
(
GetIRContext
()
->
module
()
->
id_bound
()
>=
GetFuzzerContext
()
->
GetIdBoundLimit
())
{
return
;
}
// Randomly decides whether the transformation will be applied.
if
(
!
GetFuzzerContext
()
->
ChoosePercentage
(
GetFuzzerContext
()
->
GetChanceOfAddingBitInstructionSynonym
()))
{
...
...
third_party/SPIRV-Tools/source/fuzz/fuzzer_pass_add_composite_extract.cpp
View file @
612ded06
...
...
@@ -91,35 +91,29 @@ void FuzzerPassAddCompositeExtract::Apply() {
available_composites
)];
composite_id
=
inst
->
result_id
();
const
auto
*
type
=
GetIRContext
()
->
get_type_mgr
()
->
GetType
(
inst
->
type_id
());
assert
(
type
&&
"Composite instruction has invalid type id"
);
auto
type_id
=
inst
->
type_id
();
do
{
uint32_t
number_of_members
=
0
;
if
(
const
auto
*
array_type
=
type
->
AsArray
())
{
const
auto
*
type_inst
=
GetIRContext
()
->
get_def_use_mgr
()
->
GetDef
(
inst
->
type_id
());
assert
(
type_inst
&&
"Type instruction must exist"
);
number_of_members
=
fuzzerutil
::
GetArraySize
(
*
type_inst
,
GetIRContext
());
type
=
array_type
->
element_type
();
}
else
if
(
const
auto
*
vector_type
=
type
->
AsVector
())
{
number_of_members
=
vector_type
->
element_count
();
type
=
vector_type
->
element_type
();
}
else
if
(
const
auto
*
matrix_type
=
type
->
AsMatrix
())
{
number_of_members
=
matrix_type
->
element_count
();
type
=
matrix_type
->
element_type
();
}
else
if
(
const
auto
*
struct_type
=
type
->
AsStruct
())
{
number_of_members
=
static_cast
<
uint32_t
>
(
struct_type
->
element_types
().
size
());
// The next value of |type| will be assigned when we know the
// index of the OpTypeStruct's operand.
}
else
{
assert
(
false
&&
"|inst| is not a composite"
);
return
;
const
auto
*
type_inst
=
GetIRContext
()
->
get_def_use_mgr
()
->
GetDef
(
type_id
);
assert
(
type_inst
&&
"Composite instruction has invalid type id"
);
switch
(
type_inst
->
opcode
())
{
case
SpvOpTypeArray
:
number_of_members
=
fuzzerutil
::
GetArraySize
(
*
type_inst
,
GetIRContext
());
break
;
case
SpvOpTypeVector
:
case
SpvOpTypeMatrix
:
number_of_members
=
type_inst
->
GetSingleWordInOperand
(
1
);
break
;
case
SpvOpTypeStruct
:
number_of_members
=
type_inst
->
NumInOperands
();
break
;
default
:
assert
(
false
&&
"|type_inst| is not a composite"
);
return
;
}
if
(
number_of_members
==
0
)
{
...
...
@@ -130,10 +124,21 @@ void FuzzerPassAddCompositeExtract::Apply() {
GetFuzzerContext
()
->
GetRandomCompositeExtractIndex
(
number_of_members
));
if
(
const
auto
*
struct_type
=
type
->
AsStruct
())
{
type
=
struct_type
->
element_types
()[
indices
.
back
()];
switch
(
type_inst
->
opcode
())
{
case
SpvOpTypeArray
:
case
SpvOpTypeVector
:
case
SpvOpTypeMatrix
:
type_id
=
type_inst
->
GetSingleWordInOperand
(
0
);
break
;
case
SpvOpTypeStruct
:
type_id
=
type_inst
->
GetSingleWordInOperand
(
indices
.
back
());
break
;
default
:
assert
(
false
&&
"|type_inst| is not a composite"
);
return
;
}
}
while
(
fuzzerutil
::
IsCompositeType
(
type
)
&&
}
while
(
fuzzerutil
::
IsCompositeType
(
GetIRContext
()
->
get_type_mgr
()
->
GetType
(
type_id
))
&&
GetFuzzerContext
()
->
ChoosePercentage
(
GetFuzzerContext
()
->
GetChanceOfGoingDeeperToExtractComposite
()));
...
...
third_party/SPIRV-Tools/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp
View file @
612ded06
...
...
@@ -71,7 +71,8 @@ void FuzzerPassFlattenConditionalBranches::Apply() {
// Do not consider this header if the conditional cannot be flattened.
if
(
!
TransformationFlattenConditionalBranch
::
GetProblematicInstructionsIfConditionalCanBeFlattened
(
GetIRContext
(),
header
,
&
instructions_that_need_ids
))
{
GetIRContext
(),
header
,
*
GetTransformationContext
(),
&
instructions_that_need_ids
))
{
continue
;
}
...
...
@@ -214,7 +215,7 @@ void FuzzerPassFlattenConditionalBranches::Apply() {
}
}
wrappers_info
.
emplace_back
(
wrapper_info
);
wrappers_info
.
push_back
(
std
::
move
(
wrapper_info
)
);
}
// Apply the transformation, evenly choosing whether to lay out the true
...
...
third_party/SPIRV-Tools/source/fuzz/pass_management/repeated_pass_manager_random_with_recommendations.cpp
View file @
612ded06
...
...
@@ -53,6 +53,8 @@ FuzzerPass* RepeatedPassManagerRandomWithRecommendations::ChoosePass(
result
=
recommended_passes_
.
front
();
recommended_passes_
.
pop_front
();
}
assert
(
result
!=
nullptr
&&
"A pass must have been chosen."
);
last_pass_choice_
=
result
;
return
result
;
}
...
...
third_party/SPIRV-Tools/source/fuzz/transformation_add_bit_instruction_synonym.cpp
View file @
612ded06
...
...
@@ -46,7 +46,8 @@ bool TransformationAddBitInstructionSynonym::IsApplicable(
// |instruction| must be defined and must be a supported bit instruction.
if
(
!
instruction
||
(
instruction
->
opcode
()
!=
SpvOpBitwiseOr
&&
instruction
->
opcode
()
!=
SpvOpBitwiseXor
&&
instruction
->
opcode
()
!=
SpvOpBitwiseAnd
))
{
instruction
->
opcode
()
!=
SpvOpBitwiseAnd
&&
instruction
->
opcode
()
!=
SpvOpNot
))
{
return
false
;
}
...
...
third_party/SPIRV-Tools/source/fuzz/transformation_flatten_conditional_branch.cpp
View file @
612ded06
...
...
@@ -82,65 +82,6 @@ bool TransformationFlattenConditionalBranch::IsApplicable(
}
}
if
(
OpSelectArgumentsAreRestricted
(
ir_context
))
{
// OpPhi instructions at the convergence block for the selection are handled
// by turning them into OpSelect instructions. As the SPIR-V version in use
// has restrictions on the arguments that OpSelect can take, we must check
// that any OpPhi instructions are compatible with these restrictions.
uint32_t
convergence_block_id
=
FindConvergenceBlock
(
ir_context
,
*
header_block
);
// Consider every OpPhi instruction at the convergence block.
if
(
!
ir_context
->
cfg
()
->
block
(
convergence_block_id
)
->
WhileEachPhiInst
([
this
,
ir_context
](
opt
::
Instruction
*
inst
)
->
bool
{
// Decide whether the OpPhi can be handled based on its result
// type.
opt
::
Instruction
*
phi_result_type
=
ir_context
->
get_def_use_mgr
()
->
GetDef
(
inst
->
type_id
());
switch
(
phi_result_type
->
opcode
())
{
case
SpvOpTypeBool
:
case
SpvOpTypeInt
:
case
SpvOpTypeFloat
:
case
SpvOpTypePointer
:
// Fine: OpSelect can work directly on scalar and pointer
// types.
return
true
;
case
SpvOpTypeVector
:
{
// In its restricted form, OpSelect can only select between
// vectors if the condition of the select is a boolean
// boolean vector. We thus require the appropriate boolean
// vector type to be present.
uint32_t
bool_type_id
=
fuzzerutil
::
MaybeGetBoolType
(
ir_context
);
uint32_t
dimension
=
phi_result_type
->
GetSingleWordInOperand
(
1
);
if
(
fuzzerutil
::
MaybeGetVectorType
(
ir_context
,
bool_type_id
,
dimension
)
==
0
)
{
// The required boolean vector type is not present.
return
false
;
}
// The transformation needs to be equipped with a fresh id
// in which to store the vectorized version of the selection
// construct's condition.
switch
(
dimension
)
{
case
2
:
return
message_
.
fresh_id_for_bvec2_selector
()
!=
0
;
case
3
:
return
message_
.
fresh_id_for_bvec3_selector
()
!=
0
;
default
:
assert
(
dimension
==
4
&&
"Invalid vector dimension."
);
return
message_
.
fresh_id_for_bvec4_selector
()
!=
0
;
}
}
default
:
return
false
;
}
}))
{
return
false
;
}
}
// Use a set to keep track of the instructions that require fresh ids.
std
::
set
<
opt
::
Instruction
*>
instructions_that_need_ids
;
...
...
@@ -148,7 +89,8 @@ bool TransformationFlattenConditionalBranch::IsApplicable(
// if so, add all the problematic instructions that need to be enclosed inside
// conditionals to |instructions_that_need_ids|.
if
(
!
GetProblematicInstructionsIfConditionalCanBeFlattened
(
ir_context
,
header_block
,
&
instructions_that_need_ids
))
{
ir_context
,
header_block
,
transformation_context
,
&
instructions_that_need_ids
))
{
return
false
;
}
...
...
@@ -205,6 +147,69 @@ bool TransformationFlattenConditionalBranch::IsApplicable(
}
}
if
(
OpSelectArgumentsAreRestricted
(
ir_context
))
{
// OpPhi instructions at the convergence block for the selection are handled
// by turning them into OpSelect instructions. As the SPIR-V version in use
// has restrictions on the arguments that OpSelect can take, we must check
// that any OpPhi instructions are compatible with these restrictions.
uint32_t
convergence_block_id
=
FindConvergenceBlock
(
ir_context
,
*
header_block
);
// Consider every OpPhi instruction at the convergence block.
if
(
!
ir_context
->
cfg
()
->
block
(
convergence_block_id
)
->
WhileEachPhiInst
([
this
,
ir_context
](
opt
::
Instruction
*
inst
)
->
bool
{
// Decide whether the OpPhi can be handled based on its result
// type.
opt
::
Instruction
*
phi_result_type
=
ir_context
->
get_def_use_mgr
()
->
GetDef
(
inst
->
type_id
());
switch
(
phi_result_type
->
opcode
())
{
case
SpvOpTypeBool
:
case
SpvOpTypeInt
:
case
SpvOpTypeFloat
:
case
SpvOpTypePointer
:
// Fine: OpSelect can work directly on scalar and pointer
// types.
return
true
;
case
SpvOpTypeVector
:
{
// In its restricted form, OpSelect can only select between
// vectors if the condition of the select is a boolean
// boolean vector. We thus require the appropriate boolean
// vector type to be present.
uint32_t
bool_type_id
=
fuzzerutil
::
MaybeGetBoolType
(
ir_context
);
if
(
!
bool_type_id
)
{
return
false
;
}
uint32_t
dimension
=
phi_result_type
->
GetSingleWordInOperand
(
1
);
if
(
fuzzerutil
::
MaybeGetVectorType
(
ir_context
,
bool_type_id
,
dimension
)
==
0
)
{
// The required boolean vector type is not present.
return
false
;
}
// The transformation needs to be equipped with a fresh id
// in which to store the vectorized version of the selection
// construct's condition.
switch
(
dimension
)
{
case
2
:
return
message_
.
fresh_id_for_bvec2_selector
()
!=
0
;
case
3
:
return
message_
.
fresh_id_for_bvec3_selector
()
!=
0
;
default
:
assert
(
dimension
==
4
&&
"Invalid vector dimension."
);
return
message_
.
fresh_id_for_bvec4_selector
()
!=
0
;
}
}
default
:
return
false
;
}
}))
{
return
false
;
}
}
// All checks were passed.
return
true
;
}
...
...
@@ -428,6 +433,7 @@ protobufs::Transformation TransformationFlattenConditionalBranch::ToMessage()
bool
TransformationFlattenConditionalBranch
::
GetProblematicInstructionsIfConditionalCanBeFlattened
(
opt
::
IRContext
*
ir_context
,
opt
::
BasicBlock
*
header
,
const
TransformationContext
&
transformation_context
,
std
::
set
<
opt
::
Instruction
*>*
instructions_that_need_ids
)
{
uint32_t
merge_block_id
=
header
->
MergeBlockIdIfAny
();
assert
(
merge_block_id
&&
...
...
@@ -441,6 +447,11 @@ bool TransformationFlattenConditionalBranch::
auto
postdominator_analysis
=
ir_context
->
GetPostDominatorAnalysis
(
enclosing_function
);
// |header| must be reachable.
if
(
!
dominator_analysis
->
IsReachable
(
header
))
{
return
false
;
}
// Check that the header and the merge block describe a single-entry,
// single-exit region.
if
(
!
dominator_analysis
->
Dominates
(
header
->
id
(),
merge_block_id
)
||
...
...
@@ -454,13 +465,22 @@ bool TransformationFlattenConditionalBranch::
// - they branch unconditionally to another block
// Add any side-effecting instruction, requiring fresh ids, to
// |instructions_that_need_ids|
std
::
list
<
uint32_t
>
to_check
;
std
::
queue
<
uint32_t
>
to_check
;
header
->
ForEachSuccessorLabel
(
[
&
to_check
](
uint32_t
label
)
{
to_check
.
push
_back
(
label
);
});
[
&
to_check
](
uint32_t
label
)
{
to_check
.
push
(
label
);
});
auto
*
structured_cfg
=
ir_context
->
GetStructuredCFGAnalysis
();
while
(
!
to_check
.
empty
())
{
uint32_t
block_id
=
to_check
.
front
();
to_check
.
pop_front
();
to_check
.
pop
();
if
(
structured_cfg
->
ContainingConstruct
(
block_id
)
!=
header
->
id
()
&&
block_id
!=
merge_block_id
)
{
// This block can be reached from the |header| but doesn't belong to its
// selection construct. This might be a continue target of some loop -
// we can't flatten the |header|.
return
false
;
}
// If the block post-dominates the header, this is where flow converges, and
// we don't need to check this branch any further, because the
...
...
@@ -470,6 +490,15 @@ bool TransformationFlattenConditionalBranch::
continue
;
}
if
(
!
transformation_context
.
GetFactManager
()
->
BlockIsDead
(
header
->
id
())
&&
transformation_context
.
GetFactManager
()
->
BlockIsDead
(
block_id
))
{
// The |header| is not dead but the |block_id| is. Since |block_id|
// doesn't postdominate the |header|, CFG hasn't converged yet. Thus, we
// don't flatten the construct to prevent |block_id| from becoming
// executable.
return
false
;
}
auto
block
=
ir_context
->
cfg
()
->
block
(
block_id
);
// The block must not have a merge instruction, because inner constructs are
...
...
@@ -518,7 +547,7 @@ bool TransformationFlattenConditionalBranch::
// Add the successor of this block to the list of blocks that need to be
// checked.
to_check
.
push
_back
(
block
->
terminator
()
->
GetSingleWordInOperand
(
0
));
to_check
.
push
(
block
->
terminator
()
->
GetSingleWordInOperand
(
0
));
}
// All the blocks are compatible with the transformation and this is indeed a
...
...
@@ -564,7 +593,7 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional(
opt
::
Instruction
*
instruction
,
const
protobufs
::
SideEffectWrapperInfo
&
wrapper_info
,
uint32_t
condition_id
,
bool
exec_if_cond_true
,
std
::
vector
<
uint32_t
>*
dead_blocks
,
std
::
vector
<
uint32_t
>*
irrelevant_ids
)
const
{
std
::
vector
<
uint32_t
>*
irrelevant_ids
)
{
// Get the next instruction (it will be useful for splitting).
auto
next_instruction
=
instruction
->
NextNode
();
...
...
@@ -810,7 +839,7 @@ bool TransformationFlattenConditionalBranch::OpSelectArgumentsAreRestricted(
void
TransformationFlattenConditionalBranch
::
AddBooleanVectorConstructorToBlock
(
uint32_t
fresh_id
,
uint32_t
dimension
,
const
opt
::
Operand
&
branch_condition_operand
,
opt
::
IRContext
*
ir_context
,
opt
::
BasicBlock
*
block
)
const
{
opt
::
BasicBlock
*
block
)
{
opt
::
Instruction
::
OperandList
in_operands
;
for
(
uint32_t
i
=
0
;
i
<
dimension
;
i
++
)
{
in_operands
.
emplace_back
(
branch_condition_operand
);
...
...
third_party/SPIRV-Tools/source/fuzz/transformation_flatten_conditional_branch.h
View file @
612ded06
...
...
@@ -72,6 +72,7 @@ class TransformationFlattenConditionalBranch : public Transformation {
// instructions are OpSelectionMerge and OpBranchConditional.
static
bool
GetProblematicInstructionsIfConditionalCanBeFlattened
(
opt
::
IRContext
*
ir_context
,
opt
::
BasicBlock
*
header
,
const
TransformationContext
&
transformation_context
,
std
::
set
<
opt
::
Instruction
*>*
instructions_that_need_ids
);
// Returns true iff the given instruction needs a placeholder to be enclosed
...
...
@@ -117,14 +118,14 @@ class TransformationFlattenConditionalBranch : public Transformation {
// |dead_blocks| and |irrelevant_ids| are used to record the ids of blocks
// and instructions for which dead block and irrelevant id facts should
// ultimately be created.
opt
::
BasicBlock
*
EncloseInstructionInConditional
(
static
opt
::
BasicBlock
*
EncloseInstructionInConditional
(
opt
::
IRContext
*
ir_context
,
const
TransformationContext
&
transformation_context
,
opt
::
BasicBlock
*
block
,
opt
::
Instruction
*
instruction
,
const
protobufs
::
SideEffectWrapperInfo
&
wrapper_info
,
uint32_t
condition_id
,
bool
exec_if_cond_true
,
std
::
vector
<
uint32_t
>*
dead_blocks
,
std
::
vector
<
uint32_t
>*
irrelevant_ids
)
const
;
std
::
vector
<
uint32_t
>*
irrelevant_ids
);
// Turns every OpPhi instruction of |convergence_block| -- the convergence
// block for |header_block| (both in |ir_context|) into an OpSelect
...
...
@@ -137,10 +138,10 @@ class TransformationFlattenConditionalBranch : public Transformation {
// |ir_context|, with result id given by |fresh_id|. The instruction will
// make a |dimension|-dimensional boolean vector with
// |branch_condition_operand| at every component.
void
AddBooleanVectorConstructorToBlock
(
static
void
AddBooleanVectorConstructorToBlock
(
uint32_t
fresh_id
,
uint32_t
dimension
,
const
opt
::
Operand
&
branch_condition_operand
,
opt
::
IRContext
*
ir_context
,
opt
::
BasicBlock
*
block
)
const
;
opt
::
BasicBlock
*
block
);
// Returns true if the given instruction either has no side effects or it can
// be handled by being enclosed in a conditional.
...
...
third_party/SPIRV-Tools/source/opt/debug_info_manager.cpp
View file @
612ded06
...
...
@@ -384,7 +384,8 @@ bool DebugInfoManager::IsVariableDebugDeclared(uint32_t variable_id) {
return
dbg_decl_itr
!=
var_id_to_dbg_decl_
.
end
();
}
void
DebugInfoManager
::
KillDebugDeclares
(
uint32_t
variable_id
)
{
bool
DebugInfoManager
::
KillDebugDeclares
(
uint32_t
variable_id
)
{
bool
modified
=
false
;
auto
dbg_decl_itr
=
var_id_to_dbg_decl_
.
find
(
variable_id
);
if
(
dbg_decl_itr
!=
var_id_to_dbg_decl_
.
end
())
{
// We intentionally copy the list of DebugDeclare instructions because
...
...
@@ -394,9 +395,11 @@ void DebugInfoManager::KillDebugDeclares(uint32_t variable_id) {
for
(
auto
*
dbg_decl
:
copy_dbg_decls
)
{
context
()
->
KillInst
(
dbg_decl
);
modified
=
true
;
}
var_id_to_dbg_decl_
.
erase
(
dbg_decl_itr
);
}
return
modified
;
}
uint32_t
DebugInfoManager
::
GetParentScope
(
uint32_t
child_scope
)
{
...
...
@@ -514,16 +517,18 @@ Instruction* DebugInfoManager::AddDebugValueWithIndex(
return
added_dbg_value
;
}
void
DebugInfoManager
::
AddDebugValueIfVarDeclIsVisible
(
bool
DebugInfoManager
::
AddDebugValueIfVarDeclIsVisible
(
Instruction
*
scope_and_line
,
uint32_t
variable_id
,
uint32_t
value_id
,
Instruction
*
insert_pos
,
std
::
unordered_set
<
Instruction
*>*
invisible_decls
)
{
assert
(
scope_and_line
!=
nullptr
);
auto
dbg_decl_itr
=
var_id_to_dbg_decl_
.
find
(
variable_id
);
if
(
dbg_decl_itr
==
var_id_to_dbg_decl_
.
end
())
return
;
if
(
dbg_decl_itr
==
var_id_to_dbg_decl_
.
end
())
return
false
;
bool
modified
=
false
;
for
(
auto
*
dbg_decl_or_val
:
dbg_decl_itr
->
second
)
{
if
(
scope_and_line
&&
!
IsDeclareVisibleToInstr
(
dbg_decl_or_val
,
scope_and_line
))
{
if
(
!
IsDeclareVisibleToInstr
(
dbg_decl_or_val
,
scope_and_line
))
{
if
(
invisible_decls
)
invisible_decls
->
insert
(
dbg_decl_or_val
);
continue
;
}
...
...
@@ -547,10 +552,11 @@ void DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
kDebugValueOperandLocalVariableIndex
),
value_id
,
0
,
index_id
,
insert_before
);
assert
(
added_dbg_value
!=
nullptr
);
added_dbg_value
->
UpdateDebugInfoFrom
(
scope_and_line
?
scope_and_line
:
dbg_decl_or_val
);
added_dbg_value
->
UpdateDebugInfoFrom
(
scope_and_line
);
AnalyzeDebugInst
(
added_dbg_value
);
modified
=
true
;
}
return
modified
;
}
bool
DebugInfoManager
::
AddDebugValueForDecl
(
Instruction
*
dbg_decl
,
...
...
third_party/SPIRV-Tools/source/opt/debug_info_manager.h
View file @
612ded06
...
...
@@ -138,14 +138,15 @@ class DebugInfoManager {
bool
IsVariableDebugDeclared
(
uint32_t
variable_id
);
// Kills all debug declaration instructions with Deref whose 'Local Variable'
// operand is |variable_id|.
void
KillDebugDeclares
(
uint32_t
variable_id
);
// operand is |variable_id|.
Returns whether it kills an instruction or not.
bool
KillDebugDeclares
(
uint32_t
variable_id
);
// Generates a DebugValue instruction with value |value_id| for every local
// variable that is in the scope of |scope_and_line| and whose memory is
// |variable_id| and inserts it after the instruction |insert_pos|.
// |invisible_decls| returns DebugDeclares invisible to |scope_and_line|.
void
AddDebugValueIfVarDeclIsVisible
(
// Returns whether a DebugValue is added or not. |invisible_decls| returns
// DebugDeclares invisible to |scope_and_line|.
bool
AddDebugValueIfVarDeclIsVisible
(
Instruction
*
scope_and_line
,
uint32_t
variable_id
,
uint32_t
value_id
,
Instruction
*
insert_pos
,
std
::
unordered_set
<
Instruction
*>*
invisible_decls
);
...
...
third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp
View file @
612ded06
...
...
@@ -148,16 +148,41 @@ bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
context
()
->
get_type_mgr
()
->
GetType
(
var_inst
->
type_id
());
const
analysis
::
Type
*
store_type
=
var_type
->
AsPointer
()
->
pointee_type
();
if
(
!
(
store_type
->
AsStruct
()
||
store_type
->
AsArray
()))
{
context
()
->
get_debug_info_mgr
()
->
AddDebugValueIfVarDeclIsVisible
(
nullptr
,
var_id
,
store_inst
->
GetSingleWordInOperand
(
1
),
store_inst
,
nullptr
);
context
()
->
get_debug_info_mgr
()
->
KillDebugDeclares
(
var_id
);
modified
|=
RewriteDebugDeclares
(
store_inst
,
var_id
);
}
}
return
modified
;
}
bool
LocalSingleStoreElimPass
::
RewriteDebugDeclares
(
Instruction
*
store_inst
,
uint32_t
var_id
)
{
std
::
unordered_set
<
Instruction
*>
invisible_decls
;
uint32_t
value_id
=
store_inst
->
GetSingleWordInOperand
(
1
);
bool
modified
=
context
()
->
get_debug_info_mgr
()
->
AddDebugValueIfVarDeclIsVisible
(
store_inst
,
var_id
,
value_id
,
store_inst
,
&
invisible_decls
);
// For cases like the argument passing for an inlined function, the value
// assignment is out of DebugDeclare's scope, but we have to preserve the
// value assignment information using DebugValue. Generally, we need
// ssa-rewrite analysis to decide a proper value assignment but at this point
// we confirm that |var_id| has a single store. We can safely add DebugValue.
if
(
!
invisible_decls
.
empty
())
{
BasicBlock
*
store_block
=
context
()
->
get_instr_block
(
store_inst
);
DominatorAnalysis
*
dominator_analysis
=
context
()
->
GetDominatorAnalysis
(
store_block
->
GetParent
());
for
(
auto
*
decl
:
invisible_decls
)
{
if
(
dominator_analysis
->
Dominates
(
store_inst
,
decl
))
{
context
()
->
get_debug_info_mgr
()
->
AddDebugValueForDecl
(
decl
,
value_id
);
modified
=
true
;
}
}
}
modified
|=
context
()
->
get_debug_info_mgr
()
->
KillDebugDeclares
(
var_id
);
return
modified
;
}
Instruction
*
LocalSingleStoreElimPass
::
FindSingleStoreAndCheckUses
(
Instruction
*
var_inst
,
const
std
::
vector
<
Instruction
*>&
users
)
const
{
// Make sure there is exactly 1 store.
...
...
third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.h
View file @
612ded06
...
...
@@ -94,6 +94,10 @@ class LocalSingleStoreElimPass : public Pass {
bool
RewriteLoads
(
Instruction
*
store_inst
,
const
std
::
vector
<
Instruction
*>&
uses
,
bool
*
all_rewritten
);
// Replaces DebugDeclares of |var_id| with DebugValues using the value
// assignment of |store_inst|.
bool
RewriteDebugDeclares
(
Instruction
*
store_inst
,
uint32_t
var_id
);
// Extensions supported by this pass.
std
::
unordered_set
<
std
::
string
>
extensions_allowlist_
;
};
...
...
third_party/SPIRV-Tools/source/opt/optimizer.cpp
View file @
612ded06
...
...
@@ -161,6 +161,7 @@ Optimizer& Optimizer::RegisterPerformancePasses() {
.
RegisterPass
(
CreateDeadBranchElimPass
())
.
RegisterPass
(
CreateMergeReturnPass
())
.
RegisterPass
(
CreateInlineExhaustivePass
())
.
RegisterPass
(
CreateEliminateDeadFunctionsPass
())
.
RegisterPass
(
CreateAggressiveDCEPass
())
.
RegisterPass
(
CreatePrivateToLocalPass
())
.
RegisterPass
(
CreateLocalSingleBlockLoadStoreElimPass
())
...
...
third_party/SPIRV-Tools/source/opt/ssa_rewrite_pass.cpp
View file @
612ded06
...
...
@@ -47,6 +47,7 @@
#include "source/opcode.h"
#include "source/opt/cfg.h"
#include "source/opt/mem_pass.h"
#include "source/opt/types.h"
#include "source/util/make_unique.h"
// Debug logging (0: Off, 1-N: Verbosity level). Replace this with the
...
...
@@ -326,32 +327,94 @@ void SSARewriter::ProcessStore(Instruction* inst, BasicBlock* bb) {
}
bool
SSARewriter
::
ProcessLoad
(
Instruction
*
inst
,
BasicBlock
*
bb
)
{
// Get the pointer that we are using to load from.
uint32_t
var_id
=
0
;
(
void
)
pass_
->
GetPtr
(
inst
,
&
var_id
);
if
(
pass_
->
IsTargetVar
(
var_id
))
{
// Get the immediate reaching definition for |var_id|.
uint32_t
val_id
=
GetReachingDef
(
var_id
,
bb
);
// Get the immediate reaching definition for |var_id|.
//
// In the presence of variable pointers, the reaching definition may be
// another pointer. For example, the following fragment:
//
// %2 = OpVariable %_ptr_Input_float Input
// %11 = OpVariable %_ptr_Function__ptr_Input_float Function
// OpStore %11 %2
// %12 = OpLoad %_ptr_Input_float %11
// %13 = OpLoad %float %12
//
// corresponds to the pseudo-code:
//
// layout(location = 0) in flat float *%2
// float %13;
// float *%12;
// float **%11;
// *%11 = %2;
// %12 = *%11;
// %13 = *%12;
//
// which ultimately, should correspond to:
//
// %13 = *%2;
//
// During rewriting, the pointer %12 is found to be replaceable by %2 (i.e.,
// load_replacement_[12] is 2). However, when processing the load
// %13 = *%12, the type of %12's reaching definition is another float
// pointer (%2), instead of a float value.
//
// When this happens, we need to continue looking up the reaching definition
// chain until we get to a float value or a non-target var (i.e. a variable
// that cannot be SSA replaced, like %2 in this case since it is a function
// argument).
analysis
::
DefUseManager
*
def_use_mgr
=
pass_
->
context
()
->
get_def_use_mgr
();
analysis
::
TypeManager
*
type_mgr
=
pass_
->
context
()
->
get_type_mgr
();
analysis
::
Type
*
load_type
=
type_mgr
->
GetType
(
inst
->
type_id
());
uint32_t
val_id
=
0
;
bool
found_reaching_def
=
false
;
while
(
!
found_reaching_def
)
{
if
(
!
pass_
->
IsTargetVar
(
var_id
))
{
// If the variable we are loading from is not an SSA target (globals,
// function parameters), do nothing.
return
true
;
}
val_id
=
GetReachingDef
(
var_id
,
bb
);
if
(
val_id
==
0
)
{
return
false
;
}
// Schedule a replacement for the result of this load instruction with
// |val_id|. After all the rewriting decisions are made, every use of
// this load will be replaced with |val_id|.
const
uint32_t
load_id
=
inst
->
result_id
();
assert
(
load_replacement_
.
count
(
load_id
)
==
0
);
load_replacement_
[
load_id
]
=
val_id
;
PhiCandidate
*
defining_phi
=
GetPhiCandidate
(
val_id
);
if
(
defining_phi
)
{
defining_phi
->
AddUser
(
load_id
);
// If the reaching definition is a pointer type different than the type of
// the instruction we are analyzing, then it must be a reference to another
// pointer (otherwise, this would be invalid SPIRV). We continue
// de-referencing it by making |val_id| be |var_id|.
//
// NOTE: if there is no reaching definition instruction, it means |val_id|
// is an undef.
Instruction
*
reaching_def_inst
=
def_use_mgr
->
GetDef
(
val_id
);
if
(
reaching_def_inst
&&
!
type_mgr
->
GetType
(
reaching_def_inst
->
type_id
())
->
IsSame
(
load_type
))
{
var_id
=
val_id
;
}
else
{
found_reaching_def
=
true
;
}
}
// Schedule a replacement for the result of this load instruction with
// |val_id|. After all the rewriting decisions are made, every use of
// this load will be replaced with |val_id|.
uint32_t
load_id
=
inst
->
result_id
();
assert
(
load_replacement_
.
count
(
load_id
)
==
0
);
load_replacement_
[
load_id
]
=
val_id
;
PhiCandidate
*
defining_phi
=
GetPhiCandidate
(
val_id
);
if
(
defining_phi
)
{
defining_phi
->
AddUser
(
load_id
);
}
#if SSA_REWRITE_DEBUGGING_LEVEL > 1
std
::
cerr
<<
"
\t
Found load: "
<<
inst
->
PrettyPrint
(
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES
)
<<
" (replacement for %"
<<
load_id
<<
" is %"
<<
val_id
<<
")
\n
"
;
std
::
cerr
<<
"
\t
Found load: "
<<
inst
->
PrettyPrint
(
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES
)
<<
" (replacement for %"
<<
load_id
<<
" is %"
<<
val_id
<<
")
\n
"
;
#endif
}
return
true
;
}
...
...
@@ -390,8 +453,8 @@ bool SSARewriter::GenerateSSAReplacements(BasicBlock* bb) {
}
}
// Seal |bb|. This means that all the stores in it have been scanned and
it's
// ready to feed them into its successors.
// Seal |bb|. This means that all the stores in it have been scanned and
//
it's
ready to feed them into its successors.
SealBlock
(
bb
);
#if SSA_REWRITE_DEBUGGING_LEVEL > 1
...
...
@@ -504,8 +567,8 @@ bool SSARewriter::ApplyReplacements() {
}
// Scan uses for all inserted Phi instructions. Do this separately from the
// registration of the Phi instruction itself to avoid trying to analyze
uses
// of Phi instructions that have not been registered yet.
// registration of the Phi instruction itself to avoid trying to analyze
//
uses
of Phi instructions that have not been registered yet.
for
(
Instruction
*
phi_inst
:
generated_phis
)
{
pass_
->
get_def_use_mgr
()
->
AnalyzeInstUse
(
&*
phi_inst
);
}
...
...
@@ -562,7 +625,8 @@ void SSARewriter::FinalizePhiCandidate(PhiCandidate* phi_candidate) {
// This candidate is now completed.
phi_candidate
->
MarkComplete
();
// If |phi_candidate| is not trivial, add it to the list of Phis to generate.
// If |phi_candidate| is not trivial, add it to the list of Phis to
// generate.
if
(
TryRemoveTrivialPhi
(
phi_candidate
)
==
phi_candidate
->
result_id
())
{
// If we could not remove |phi_candidate|, it means that it is complete
// and not trivial. Add it to the list of Phis to generate.
...
...
third_party/SPIRV-Tools/source/val/validate_builtins.cpp
View file @
612ded06
...
...
@@ -2603,17 +2603,19 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
assert
(
function_id_
==
0
);
for
(
const
auto
em
:
{
SpvExecutionModelVertex
,
SpvExecutionModelTessellationEvaluation
,
SpvExecutionModelGeometry
})
{
SpvExecutionModelGeometry
,
SpvExecutionModelMeshNV
})
{
id_to_at_reference_checks_
[
referenced_from_inst
.
id
()].
push_back
(
std
::
bind
(
&
BuiltInsValidator
::
ValidateNotCalledWithExecutionModel
,
this
,
"Vulkan spec doesn't allow BuiltIn Layer and "
"ViewportIndex to be "
"used for variables with Input storage class if "
"execution model is Vertex, TessellationEvaluation, or "
"Geometry."
,
em
,
decoration
,
built_in_inst
,
referenced_from_inst
,
std
::
placeholders
::
_1
));
std
::
bind
(
&
BuiltInsValidator
::
ValidateNotCalledWithExecutionModel
,
this
,
std
::
string
(
_
.
VkErrorID
((
operand
==
SpvBuiltInLayer
)
?
4274
:
4406
)
+
"Vulkan spec doesn't allow BuiltIn Layer and "
"ViewportIndex to be "
"used for variables with Input storage class if "
"execution model is Vertex, TessellationEvaluation, "
"Geometry, or MeshNV."
),
em
,
decoration
,
built_in_inst
,
referenced_from_inst
,
std
::
placeholders
::
_1
));
}
}
...
...
@@ -2621,11 +2623,12 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
assert
(
function_id_
==
0
);
id_to_at_reference_checks_
[
referenced_from_inst
.
id
()].
push_back
(
std
::
bind
(
&
BuiltInsValidator
::
ValidateNotCalledWithExecutionModel
,
this
,
"Vulkan spec doesn't allow BuiltIn Layer and "
"ViewportIndex to be "
"used for variables with Output storage class if "
"execution model is "
"Fragment."
,
std
::
string
(
_
.
VkErrorID
((
operand
==
SpvBuiltInLayer
)
?
4275
:
4407
)
+
"Vulkan spec doesn't allow BuiltIn Layer and "
"ViewportIndex to be "
"used for variables with Output storage class if "
"execution model is "
"Fragment."
),
SpvExecutionModelFragment
,
decoration
,
built_in_inst
,
referenced_from_inst
,
std
::
placeholders
::
_1
));
}
...
...
third_party/SPIRV-Tools/source/val/validation_state.cpp
View file @
612ded06
...
...
@@ -1377,6 +1377,10 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return
VUID_WRAP
(
VUID
-
InstanceIndex
-
InstanceIndex
-
04265
);
case
4272
:
return
VUID_WRAP
(
VUID
-
Layer
-
Layer
-
04272
);
case
4274
:
return
VUID_WRAP
(
VUID
-
Layer
-
Layer
-
04274
);
case
4275
:
return
VUID_WRAP
(
VUID
-
Layer
-
Layer
-
04275
);
case
4276
:
return
VUID_WRAP
(
VUID
-
Layer
-
Layer
-
04276
);
case
4281
:
...
...
@@ -1469,6 +1473,10 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return
VUID_WRAP
(
VUID
-
ViewIndex
-
ViewIndex
-
04403
);
case
4404
:
return
VUID_WRAP
(
VUID
-
ViewportIndex
-
ViewportIndex
-
04404
);
case
4406
:
return
VUID_WRAP
(
VUID
-
ViewportIndex
-
ViewportIndex
-
04406
);
case
4407
:
return
VUID_WRAP
(
VUID
-
ViewportIndex
-
ViewportIndex
-
04407
);
case
4408
:
return
VUID_WRAP
(
VUID
-
ViewportIndex
-
ViewportIndex
-
0440
8
);
case
4422
:
...
...
@@ -1483,6 +1491,18 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return
VUID_WRAP
(
VUID
-
WorkgroupSize
-
WorkgroupSize
-
04426
);
case
4427
:
return
VUID_WRAP
(
VUID
-
WorkgroupSize
-
WorkgroupSize
-
04427
);
case
4484
:
return
VUID_WRAP
(
VUID
-
PrimitiveShadingRateKHR
-
PrimitiveShadingRateKHR
-
044
84
);
case
4485
:
return
VUID_WRAP
(
VUID
-
PrimitiveShadingRateKHR
-
PrimitiveShadingRateKHR
-
044
85
);
case
4486
:
return
VUID_WRAP
(
VUID
-
PrimitiveShadingRateKHR
-
PrimitiveShadingRateKHR
-
044
86
);
case
4490
:
return
VUID_WRAP
(
VUID
-
ShadingRateKHR
-
ShadingRateKHR
-
044
90
);
case
4491
:
return
VUID_WRAP
(
VUID
-
ShadingRateKHR
-
ShadingRateKHR
-
044
91
);
case
4492
:
return
VUID_WRAP
(
VUID
-
ShadingRateKHR
-
ShadingRateKHR
-
044
92
);
default
:
return
""
;
// unknown id
};
...
...
third_party/SPIRV-Tools/test/fuzz/transformation_add_bit_instruction_synonym_test.cpp
View file @
612ded06
...
...
@@ -30,12 +30,12 @@ TEST(TransformationAddBitInstructionSynonymTest, IsApplicable) {
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %37 "main"
; Types
; Types
%2 = OpTypeInt 32 0
%3 = OpTypeVoid
%4 = OpTypeFunction %3
; Constants
; Constants
%5 = OpConstant %2 0
%6 = OpConstant %2 1
%7 = OpConstant %2 2
...
...
@@ -69,10 +69,22 @@ TEST(TransformationAddBitInstructionSynonymTest, IsApplicable) {
%35 = OpConstant %2 30
%36 = OpConstant %2 31
; main function
; main function
%37 = OpFunction %3 None %4
%38 = OpLabel
; Supported bit instructions
%39 = OpBitwiseOr %2 %5 %6
%40 = OpBitwiseXor %2 %7 %8
%41 = OpBitwiseAnd %2 %9 %10
%42 = OpNot %2 %11
; Not yet supported bit instructions
%43 = OpShiftRightLogical %2 %12 %13
%44 = OpShiftRightArithmetic %2 %14 %15
%45 = OpShiftLeftLogical %2 %16 %17
%46 = OpBitReverse %2 %18
%47 = OpBitCount %2 %19
OpReturn
OpFunctionEnd
)"
;
...
...
@@ -86,78 +98,94 @@ TEST(TransformationAddBitInstructionSynonymTest, IsApplicable) {
kConsoleMessageConsumer
));
TransformationContext
transformation_context
(
MakeUnique
<
FactManager
>
(
context
.
get
()),
validator_options
);
// Tests undefined bit instruction.
auto
transformation
=
TransformationAddBitInstructionSynonym
(
4
0
,
{
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
8
0
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
1
06
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
118
,
1
19
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
1
32
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
144
,
1
45
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
1
58
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
166
,
167
});
4
8
,
{
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
8
8
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
1
14
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
1
27
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
1
40
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
1
53
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
1
66
,
167
,
168
,
169
,
170
,
171
,
172
,
173
,
174
,
175
});
ASSERT_FALSE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
// Tests false bit instruction.
transformation
=
TransformationAddBitInstructionSynonym
(
38
,
{
4
0
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
1
05
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
1
18
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
13
1
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
1
44
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
1
57
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
166
});
38
,
{
4
8
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
1
13
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
1
26
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
13
9
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
1
52
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
1
65
,
166
,
167
,
168
,
169
,
170
,
171
,
172
,
173
,
174
});
ASSERT_FALSE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
// Tests the number of fresh ids being different than the necessary.
transformation
=
TransformationAddBitInstructionSynonym
(
39
,
{
4
0
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
11
0
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
1
24
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
1
38
,
139
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
1
52
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
});
{
4
8
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
11
8
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
1
32
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
144
,
145
,
1
46
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
1
60
,
161
,
162
,
163
,
164
,
165
,
166
,
167
,
168
,
169
,
170
,
171
,
172
,
173
});
ASSERT_FALSE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
// Tests non-fresh ids.
transformation
=
TransformationAddBitInstructionSynonym
(
39
,
{
38
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
1
04
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
1
17
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
13
0
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
1
43
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
1
56
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
});
40
,
{
47
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
1
13
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
1
26
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
13
9
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
1
52
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
1
65
,
166
,
167
,
168
,
169
,
170
,
171
,
172
,
173
,
174
});
ASSERT_FALSE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
// Tests
applicable
transformation.
// Tests
unsupported
transformation.
transformation
=
TransformationAddBitInstructionSynonym
(
39
,
{
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
166
});
43
,
{
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
166
,
167
,
168
,
169
,
170
,
171
,
172
,
173
,
174
});
ASSERT_FALSE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
// Tests supported transformation.
transformation
=
TransformationAddBitInstructionSynonym
(
41
,
{
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
166
,
167
,
168
,
169
,
170
,
171
,
172
,
173
,
174
});
ASSERT_TRUE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
}
...
...
@@ -238,6 +266,8 @@ TEST(TransformationAddBitInstructionSynonymTest, AddOpBitwiseOrSynonym) {
131
,
132
,
133
,
134
,
135
,
136
,
137
,
138
,
139
,
140
,
141
,
142
,
143
,
144
,
145
,
146
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
,
164
,
165
,
166
});
ASSERT_TRUE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
ApplyAndCheckFreshIds
(
transformation
,
context
.
get
(),
&
transformation_context
);
ASSERT_TRUE
(
transformation_context
.
GetFactManager
()
->
IsSynonymous
(
MakeDataDescriptor
(
166
,
{}),
MakeDataDescriptor
(
39
,
{})));
...
...
@@ -534,6 +564,8 @@ TEST(TransformationAddBitInstructionSynonymTest, AddOpNotSynonym) {
96
,
97
,
98
,
99
,
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
112
,
113
,
114
,
115
,
116
,
117
,
118
,
119
,
120
,
121
,
122
,
123
,
124
,
125
,
126
,
127
,
128
,
129
,
130
,
131
,
132
,
133
,
134
});
ASSERT_TRUE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
ApplyAndCheckFreshIds
(
transformation
,
context
.
get
(),
&
transformation_context
);
ASSERT_TRUE
(
transformation_context
.
GetFactManager
()
->
IsSynonymous
(
MakeDataDescriptor
(
134
,
{}),
MakeDataDescriptor
(
39
,
{})));
...
...
third_party/SPIRV-Tools/test/fuzz/transformation_flatten_conditional_branch_test.cpp
View file @
612ded06
...
...
@@ -2041,6 +2041,100 @@ TEST(TransformationFlattenConditionalBranchTest,
ASSERT_TRUE
(
IsEqual
(
env
,
expected
,
context
.
get
()));
}
TEST
(
TransformationFlattenConditionalBranchTest
,
ContainsDeadBlocksTest
)
{
std
::
string
shader
=
R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 320
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeBool
%7 = OpConstantFalse %6
%4 = OpFunction %2 None %3
%5 = OpLabel
OpSelectionMerge %9 None
OpBranchConditional %7 %8 %9
%8 = OpLabel
%10 = OpCopyObject %6 %7
OpBranch %9
%9 = OpLabel
%11 = OpPhi %6 %10 %8 %7 %5
%12 = OpPhi %6 %7 %5 %10 %8
OpReturn
OpFunctionEnd
)"
;
const
auto
env
=
SPV_ENV_UNIVERSAL_1_3
;
const
auto
consumer
=
nullptr
;
const
auto
context
=
BuildModule
(
env
,
consumer
,
shader
,
kFuzzAssembleOption
);
spvtools
::
ValidatorOptions
validator_options
;
ASSERT_TRUE
(
fuzzerutil
::
IsValidAndWellFormed
(
context
.
get
(),
validator_options
,
kConsoleMessageConsumer
));
TransformationContext
transformation_context
(
MakeUnique
<
FactManager
>
(
context
.
get
()),
validator_options
);
TransformationFlattenConditionalBranch
transformation
(
5
,
true
,
0
,
0
,
0
,
{});
ASSERT_TRUE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
transformation_context
.
GetFactManager
()
->
AddFactBlockIsDead
(
8
);
ASSERT_FALSE
(
transformation
.
IsApplicable
(
context
.
get
(),
transformation_context
));
}
TEST
(
TransformationFlattenConditionalBranchTest
,
ContainsContinueBlockTest
)
{
std
::
string
shader
=
R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 320
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeBool
%7 = OpConstantFalse %6
%4 = OpFunction %2 None %3
%12 = OpLabel
OpBranch %13
%13 = OpLabel
OpLoopMerge %15 %14 None
OpBranchConditional %7 %5 %15
%5 = OpLabel
OpSelectionMerge %11 None
OpBranchConditional %7 %9 %10
%9 = OpLabel
OpBranch %11
%10 = OpLabel
OpBranch %14
%11 = OpLabel
OpBranch %14
%14 = OpLabel
OpBranch %13
%15 = OpLabel
OpReturn
OpFunctionEnd
)"
;
const
auto
env
=
SPV_ENV_UNIVERSAL_1_3
;
const
auto
consumer
=
nullptr
;
const
auto
context
=
BuildModule
(
env
,
consumer
,
shader
,
kFuzzAssembleOption
);
spvtools
::
ValidatorOptions
validator_options
;
ASSERT_TRUE
(
fuzzerutil
::
IsValidAndWellFormed
(
context
.
get
(),
validator_options
,
kConsoleMessageConsumer
));
TransformationContext
transformation_context
(
MakeUnique
<
FactManager
>
(
context
.
get
()),
validator_options
);
ASSERT_FALSE
(
TransformationFlattenConditionalBranch
(
5
,
true
,
0
,
0
,
0
,
{})
.
IsApplicable
(
context
.
get
(),
transformation_context
));
}
}
// namespace
}
// namespace fuzz
}
// namespace spvtools
third_party/SPIRV-Tools/test/opt/local_single_store_elim_test.cpp
View file @
612ded06
...
...
@@ -1211,6 +1211,237 @@ TEST_F(LocalSingleStoreElimTest, DebugValueTest) {
SinglePassRunAndMatch
<
LocalSingleStoreElimPass
>
(
text
,
false
);
}
TEST_F
(
LocalSingleStoreElimTest
,
UseStoreLineInfoForDebugValueLine
)
{
// When the store is in the scope of OpenCL.DebugInfo.100 DebugDeclare,
// the OpLine of the added OpenCL.DebugInfo.100 DebugValue must be the
// same with the OpLine of the store.
const
std
::
string
text
=
R"(
OpCapability Shader
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
%7 = OpString "simple.hlsl"
%8 = OpString "float"
%9 = OpString "VS_OUTPUT"
%10 = OpString "color"
%11 = OpString "pos"
%12 = OpString "main"
%13 = OpString ""
%14 = OpString "vout"
OpName %in_var_POSITION "in.var.POSITION"
OpName %in_var_COLOR "in.var.COLOR"
OpName %out_var_COLOR "out.var.COLOR"
OpName %main "main"
OpName %VS_OUTPUT "VS_OUTPUT"
OpMemberName %VS_OUTPUT 0 "pos"
OpMemberName %VS_OUTPUT 1 "color"
OpDecorate %gl_Position BuiltIn Position
OpDecorate %in_var_POSITION Location 0
OpDecorate %in_var_COLOR Location 1
OpDecorate %out_var_COLOR Location 0
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%int_1 = OpConstant %int 1
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
%_ptr_Output_v4float = OpTypePointer Output %v4float
%void = OpTypeVoid
%uint_256 = OpConstant %uint 256
%uint_128 = OpConstant %uint 128
%uint_0 = OpConstant %uint 0
%36 = OpTypeFunction %void
%_ptr_Function_v4float = OpTypePointer Function %v4float
%VS_OUTPUT = OpTypeStruct %v4float %v4float
%_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
%in_var_POSITION = OpVariable %_ptr_Input_v4float Input
%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
%gl_Position = OpVariable %_ptr_Output_v4float Output
%out_var_COLOR = OpVariable %_ptr_Output_v4float Output
%85 = OpExtInst %void %1 DebugOperation Deref
%81 = OpExtInst %void %1 DebugInfoNone
%52 = OpExtInst %void %1 DebugExpression
%40 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
%41 = OpExtInst %void %1 DebugTypeVector %40 4
%42 = OpExtInst %void %1 DebugSource %7
%43 = OpExtInst %void %1 DebugCompilationUnit 1 4 %42 HLSL
%44 = OpExtInst %void %1 DebugTypeComposite %9 Structure %42 1 8 %43 %9 %uint_256 FlagIsProtected|FlagIsPrivate %45 %46
%46 = OpExtInst %void %1 DebugTypeMember %10 %41 %42 3 10 %44 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
%45 = OpExtInst %void %1 DebugTypeMember %11 %41 %42 2 10 %44 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
%47 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %44 %41 %41
%48 = OpExtInst %void %1 DebugFunction %12 %47 %42 6 1 %43 %13 FlagIsProtected|FlagIsPrivate 7 %81
%49 = OpExtInst %void %1 DebugLexicalBlock %42 7 38 %48
%50 = OpExtInst %void %1 DebugLocalVariable %14 %44 %42 8 13 %49 FlagIsLocal
%84 = OpExtInst %void %1 DebugExpression %85
%main = OpFunction %void None %36
%54 = OpLabel
%91 = OpExtInst %void %1 DebugScope %49
OpLine %7 7 23
%83 = OpVariable %_ptr_Function_v4float Function
OpLine %7 8 13
%87 = OpExtInst %void %1 DebugValue %50 %83 %84 %int_1
OpLine %7 7 23
%82 = OpVariable %_ptr_Function_v4float Function
OpLine %7 8 13
%86 = OpExtInst %void %1 DebugValue %50 %82 %84 %int_0
OpNoLine
%92 = OpExtInst %void %1 DebugNoScope
%55 = OpLoad %v4float %in_var_POSITION
%56 = OpLoad %v4float %in_var_COLOR
;CHECK: [[pos:%\w+]] = OpLoad %v4float %in_var_POSITION
;CHECK: [[color:%\w+]] = OpLoad %v4float %in_var_COLOR
%94 = OpExtInst %void %1 DebugScope %49
OpLine %7 9 3
OpStore %82 %55
;CHECK: OpLine [[file:%\w+]] 9 3
;CHECK: OpStore {{%\w+}} [[pos]]
;CHECK: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[vout:%\w+]] [[pos]] [[empty_expr:%\w+]] %int_0
;CHECK: OpLine [[file]] 10 3
;CHECK: OpStore {{%\w+}} [[color]]
;CHECK: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[vout]] [[color]] [[empty_expr]] %int_1
OpLine %7 10 3
OpStore %83 %56
OpLine %7 11 10
%90 = OpCompositeConstruct %VS_OUTPUT %55 %56
OpNoLine
%95 = OpExtInst %void %1 DebugNoScope
%58 = OpCompositeExtract %v4float %90 0
OpStore %gl_Position %58
%59 = OpCompositeExtract %v4float %90 1
OpStore %out_var_COLOR %59
OpReturn
OpFunctionEnd
)"
;
SetAssembleOptions
(
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS
);
SinglePassRunAndMatch
<
LocalSingleStoreElimPass
>
(
text
,
false
);
}
TEST_F
(
LocalSingleStoreElimTest
,
AddDebugValueforStoreOutOfDebugDeclareScope
)
{
const
std
::
string
text
=
R"(
OpCapability Shader
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
%7 = OpString "simple.hlsl"
%8 = OpString "float"
%9 = OpString "VS_OUTPUT"
%10 = OpString "color"
%11 = OpString "pos"
%12 = OpString "main"
%13 = OpString ""
%14 = OpString "vout"
OpName %in_var_POSITION "in.var.POSITION"
OpName %in_var_COLOR "in.var.COLOR"
OpName %out_var_COLOR "out.var.COLOR"
OpName %main "main"
OpName %VS_OUTPUT "VS_OUTPUT"
OpMemberName %VS_OUTPUT 0 "pos"
OpMemberName %VS_OUTPUT 1 "color"
OpDecorate %gl_Position BuiltIn Position
OpDecorate %in_var_POSITION Location 0
OpDecorate %in_var_COLOR Location 1
OpDecorate %out_var_COLOR Location 0
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%int_1 = OpConstant %int 1
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
%_ptr_Output_v4float = OpTypePointer Output %v4float
%void = OpTypeVoid
%uint_256 = OpConstant %uint 256
%uint_128 = OpConstant %uint 128
%uint_0 = OpConstant %uint 0
%36 = OpTypeFunction %void
%_ptr_Function_v4float = OpTypePointer Function %v4float
%VS_OUTPUT = OpTypeStruct %v4float %v4float
%_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
%in_var_POSITION = OpVariable %_ptr_Input_v4float Input
%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
%gl_Position = OpVariable %_ptr_Output_v4float Output
%out_var_COLOR = OpVariable %_ptr_Output_v4float Output
%85 = OpExtInst %void %1 DebugOperation Deref
%81 = OpExtInst %void %1 DebugInfoNone
%52 = OpExtInst %void %1 DebugExpression
%40 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
%41 = OpExtInst %void %1 DebugTypeVector %40 4
%42 = OpExtInst %void %1 DebugSource %7
%43 = OpExtInst %void %1 DebugCompilationUnit 1 4 %42 HLSL
%44 = OpExtInst %void %1 DebugTypeComposite %9 Structure %42 1 8 %43 %9 %uint_256 FlagIsProtected|FlagIsPrivate %45 %46
%46 = OpExtInst %void %1 DebugTypeMember %10 %41 %42 3 10 %44 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
%45 = OpExtInst %void %1 DebugTypeMember %11 %41 %42 2 10 %44 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
%47 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %44 %41 %41
%48 = OpExtInst %void %1 DebugFunction %12 %47 %42 6 1 %43 %13 FlagIsProtected|FlagIsPrivate 7 %81
%49 = OpExtInst %void %1 DebugLexicalBlock %42 7 38 %48
%50 = OpExtInst %void %1 DebugLocalVariable %14 %44 %42 8 13 %49 FlagIsLocal
%51 = OpExtInst %void %1 DebugLocalVariable %10 %41 %42 7 23 %48 FlagIsLocal 2
%53 = OpExtInst %void %1 DebugLocalVariable %11 %41 %42 6 23 %48 FlagIsLocal 1
;CHECK: [[dbg_color:%\w+]] = OpExtInst %void {{%\w+}} DebugLocalVariable {{%\w+}} {{%\w+}} {{%\w+}} 7 23 {{%\w+}} FlagIsLocal 2
;CHECK: [[dbg_pos:%\w+]] = OpExtInst %void {{%\w+}} DebugLocalVariable {{%\w+}} {{%\w+}} {{%\w+}} 6 23 {{%\w+}} FlagIsLocal 1
%84 = OpExtInst %void %1 DebugExpression %85
%main = OpFunction %void None %36
%54 = OpLabel
%91 = OpExtInst %void %1 DebugScope %49
OpLine %7 7 23
%83 = OpVariable %_ptr_Function_v4float Function
OpLine %7 8 13
%87 = OpExtInst %void %1 DebugValue %50 %83 %84 %int_1
OpLine %7 7 23
%82 = OpVariable %_ptr_Function_v4float Function
OpLine %7 8 13
%86 = OpExtInst %void %1 DebugValue %50 %82 %84 %int_0
OpNoLine
%92 = OpExtInst %void %1 DebugNoScope
%param_var_pos = OpVariable %_ptr_Function_v4float Function
%param_var_color = OpVariable %_ptr_Function_v4float Function
%55 = OpLoad %v4float %in_var_POSITION
OpStore %param_var_pos %55
%56 = OpLoad %v4float %in_var_COLOR
;CHECK: DebugNoScope
;CHECK-NOT: OpLine
;CHECK: [[pos:%\w+]] = OpLoad %v4float %in_var_POSITION
;CHECK: [[color:%\w+]] = OpLoad %v4float %in_var_COLOR
OpStore %param_var_color %56
%93 = OpExtInst %void %1 DebugScope %48
OpLine %7 6 23
%73 = OpExtInst %void %1 DebugDeclare %53 %param_var_pos %52
OpLine %7 7 23
%74 = OpExtInst %void %1 DebugDeclare %51 %param_var_color %52
;CHECK: OpLine [[file:%\w+]] 6 23
;CHECK-NEXT: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[dbg_pos]] [[pos]] [[empty_expr:%\w+]]
;CHECK: OpLine [[file]] 7 23
;CHECK-NEXT: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[dbg_color]] [[color]] [[empty_expr]]
%94 = OpExtInst %void %1 DebugScope %49
OpLine %7 9 3
OpStore %82 %55
OpLine %7 10 3
OpStore %83 %56
OpLine %7 11 10
%90 = OpCompositeConstruct %VS_OUTPUT %55 %56
OpNoLine
%95 = OpExtInst %void %1 DebugNoScope
%58 = OpCompositeExtract %v4float %90 0
OpStore %gl_Position %58
%59 = OpCompositeExtract %v4float %90 1
OpStore %out_var_COLOR %59
OpReturn
OpFunctionEnd
)"
;
SetAssembleOptions
(
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS
);
SinglePassRunAndMatch
<
LocalSingleStoreElimPass
>
(
text
,
false
);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// Other types
...
...
third_party/SPIRV-Tools/test/opt/local_ssa_elim_test.cpp
View file @
612ded06
...
...
@@ -3891,6 +3891,44 @@ TEST_F(LocalSSAElimTest, RemoveDebugDeclareWithoutLoads) {
SinglePassRunAndMatch
<
SSARewritePass
>
(
text
,
true
);
}
// Check support for pointer variables. When pointer variables are used, the
// computation of reaching definitions may need to follow pointer chains.
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/3873 for details.
TEST_F
(
LocalSSAElimTest
,
PointerVariables
)
{
const
std
::
string
text
=
R"(
OpCapability Shader
OpCapability VariablePointers
OpExtension "SPV_KHR_variable_pointers"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main" %2 %3
OpExecutionMode %1 OriginUpperLeft
%float = OpTypeFloat 32
%void = OpTypeVoid
%6 = OpTypeFunction %void
%_ptr_Input_float = OpTypePointer Input %float
%_ptr_Output_float = OpTypePointer Output %float
%_ptr_Function__ptr_Input_float = OpTypePointer Function %_ptr_Input_float
%2 = OpVariable %_ptr_Input_float Input
%3 = OpVariable %_ptr_Output_float Output
%1 = OpFunction %void None %6
%10 = OpLabel
%11 = OpVariable %_ptr_Function__ptr_Input_float Function
OpStore %11 %2
; CHECK-NOT: %12 = OpLoad %_ptr_Input_float %11
%12 = OpLoad %_ptr_Input_float %11
; CHECK: %13 = OpLoad %float %2
%13 = OpLoad %float %12
OpStore %3 %13
OpReturn
OpFunctionEnd
)"
;
SinglePassRunAndMatch
<
SSARewritePass
>
(
text
,
true
);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// No optimization in the presence of
...
...
third_party/SPIRV-Tools/test/tools/opt/flags.py
View file @
612ded06
...
...
@@ -149,6 +149,7 @@ class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_5,
'eliminate-dead-branches'
,
'merge-return'
,
'inline-entry-points-exhaustive'
,
'eliminate-dead-functions'
,
'eliminate-dead-code-aggressive'
,
'private-to-local'
,
'eliminate-local-single-block'
,
...
...
third_party/SPIRV-Tools/test/val/val_builtins_test.cpp
View file @
612ded06
...
...
@@ -168,6 +168,17 @@ MATCHER_P(AnyVUID, vuid_set, "VUID from the set is in error message") {
std
::
string
token
;
std
::
string
vuids
=
std
::
string
(
vuid_set
);
size_t
position
;
// Catch case were someone accidentally left spaces by trimming string
// clang-format off
vuids
.
erase
(
std
::
find_if
(
vuids
.
rbegin
(),
vuids
.
rend
(),
[](
unsigned
char
c
)
{
return
(
c
!=
' '
);
}).
base
(),
vuids
.
end
());
vuids
.
erase
(
vuids
.
begin
(),
std
::
find_if
(
vuids
.
begin
(),
vuids
.
end
(),
[](
unsigned
char
c
)
{
return
(
c
!=
' '
);
}));
// clang-format on
do
{
position
=
vuids
.
find
(
delimiter
);
if
(
position
!=
std
::
string
::
npos
)
{
...
...
@@ -1263,7 +1274,8 @@ INSTANTIATE_TEST_SUITE_P(
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult
,
Combine
(
Values
(
"Layer"
,
"ViewportIndex"
),
Values
(
"Fragment"
),
Values
(
"Output"
),
Values
(
"%u32"
),
Values
(
nullptr
),
Values
(
"%u32"
),
Values
(
"VUID-Layer-Layer-04275 VUID-ViewportIndex-ViewportIndex-04407"
),
Values
(
TestResult
(
SPV_ERROR_INVALID_DATA
,
"Output storage class if execution model is Fragment"
,
"which is called with execution model Fragment"
))));
...
...
@@ -1274,10 +1286,11 @@ INSTANTIATE_TEST_SUITE_P(
Combine
(
Values
(
"Layer"
,
"ViewportIndex"
),
Values
(
"Vertex"
,
"TessellationEvaluation"
,
"Geometry"
),
Values
(
"Input"
),
Values
(
"%u32"
),
Values
(
nullptr
),
Values
(
"%u32"
),
Values
(
"VUID-Layer-Layer-04274 VUID-ViewportIndex-ViewportIndex-04406"
),
Values
(
TestResult
(
SPV_ERROR_INVALID_DATA
,
"Input storage class if execution model is Vertex, "
"TessellationEvaluation,
or Geometry
"
,
"TessellationEvaluation,
Geometry, or MeshNV
"
,
"which is called with execution model"
))));
INSTANTIATE_TEST_SUITE_P
(
...
...
@@ -3836,7 +3849,7 @@ INSTANTIATE_TEST_SUITE_P(
Values
(
"PrimitiveShadingRateKHR"
),
Values
(
"Vertex"
),
Values
(
"Output"
),
Values
(
"%f32"
),
Values
(
"OpCapability FragmentShadingRateKHR
\n
"
),
Values
(
"OpExtension
\"
SPV_KHR_fragment_shading_rate
\"\n
"
),
Values
(
"VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-0448
5
"
),
Values
(
"VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-0448
6
"
),
Values
(
TestResult
(
SPV_ERROR_INVALID_DATA
,
"According to the Vulkan spec BuiltIn PrimitiveShadingRateKHR "
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment