diff options
author | Alan Baker <alanbaker@google.com> | 2018-07-19 13:52:24 -0400 |
---|---|---|
committer | Alan Baker <alanbaker@google.com> | 2018-07-19 14:43:59 -0400 |
commit | 3c19651733279481f662c68aa49d6b9a1ac8eac7 (patch) | |
tree | 75fa398cb8fa7074df6c02756fbf16278e57009d /source | |
parent | 28199b80b7c70a03c1002c81503ed480554d9ade (diff) |
Add variable pointer support to IsValidBasePointer
Fixes #1729
* Adds supported opcodes to IsValidBasePointer() enable by
VariablePointers and VariablePointersStorageBuffer capabilities
* Added tests
Diffstat (limited to 'source')
-rw-r--r-- | source/opt/instruction.cpp | 22 | ||||
-rw-r--r-- | source/opt/instruction.h | 12 |
2 files changed, 27 insertions, 7 deletions
diff --git a/source/opt/instruction.cpp b/source/opt/instruction.cpp index af61bf19..12026846 100644 --- a/source/opt/instruction.cpp +++ b/source/opt/instruction.cpp @@ -419,7 +419,8 @@ bool Instruction::IsValidBasePointer() const { return false; } - if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) { + auto feature_mgr = context()->get_feature_mgr(); + if (feature_mgr->HasCapability(SpvCapabilityAddresses)) { // TODO: The rules here could be more restrictive. return true; } @@ -428,6 +429,25 @@ bool Instruction::IsValidBasePointer() const { return true; } + // With variable pointers, there are more valid base pointer objects. + // Variable pointers implicitly declares Variable pointers storage buffer. + SpvStorageClass storage_class = + static_cast<SpvStorageClass>(type->GetSingleWordInOperand(0)); + if ((feature_mgr->HasCapability(SpvCapabilityVariablePointersStorageBuffer) && + storage_class == SpvStorageClassStorageBuffer) || + (feature_mgr->HasCapability(SpvCapabilityVariablePointers) && + storage_class == SpvStorageClassWorkgroup)) { + switch (opcode()) { + case SpvOpPhi: + case SpvOpSelect: + case SpvOpFunctionCall: + case SpvOpConstantNull: + return true; + default: + break; + } + } + uint32_t pointee_type_id = type->GetSingleWordInOperand(1); Instruction* pointee_type_inst = context()->get_def_use_mgr()->GetDef(pointee_type_id); diff --git a/source/opt/instruction.h b/source/opt/instruction.h index 812c4831..e6528ee5 100644 --- a/source/opt/instruction.h +++ b/source/opt/instruction.h @@ -415,6 +415,12 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> { // Return true if the only effect of this instructions is the result. bool IsOpcodeSafeToDelete() const; + // Returns true if it is valid to use the result of |inst| as the base + // pointer for a load or store. In this case, valid is defined by the relaxed + // logical addressing rules when using logical addressing. Normal validation + // rules for physical addressing. + bool IsValidBasePointer() const; + private: // Returns the total count of result type id and result id. uint32_t TypeResultIdCount() const { @@ -427,12 +433,6 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> { bool IsReadOnlyVariableShaders() const; bool IsReadOnlyVariableKernel() const; - // Returns true if it is valid to use the result of |inst| as the base - // pointer for a load or store. In this case, valid is defined by the relaxed - // logical addressing rules when using logical addressing. Normal validation - // rules for physical addressing. - bool IsValidBasePointer() const; - // Returns true if the result of |inst| can be used as the base image for an // instruction that samples a image, reads an image, or writes to an image. bool IsValidBaseImage() const; |