summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorAlan Baker <alanbaker@google.com>2018-07-19 13:52:24 -0400
committerAlan Baker <alanbaker@google.com>2018-07-19 14:43:59 -0400
commit3c19651733279481f662c68aa49d6b9a1ac8eac7 (patch)
tree75fa398cb8fa7074df6c02756fbf16278e57009d /source
parent28199b80b7c70a03c1002c81503ed480554d9ade (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.cpp22
-rw-r--r--source/opt/instruction.h12
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;