mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
Fix undefined bit shift in sroa. (#2532)
There was a bit shift done on 32-bit values, but they should have been done on 64-bit values. This is fixed. At the same time, uses of size_t are repalaced by uint64_t to ensure these values are 64-bit. A test case cannot be created because the code that was change is not run at the moment since we do not split up vectors or matricies. I do not want to delete the code because I like to experitment with it every once in a while. Fixes #2528.
This commit is contained in:
parent
dca3ea5e17
commit
64faf6d9cb
@ -225,12 +225,12 @@ bool ScalarReplacementPass::ReplaceAccessChain(
|
||||
// indexes) or a direct use of the replacement variable.
|
||||
uint32_t indexId = chain->GetSingleWordInOperand(1u);
|
||||
const Instruction* index = get_def_use_mgr()->GetDef(indexId);
|
||||
size_t indexValue = GetConstantInteger(index);
|
||||
uint64_t indexValue = GetConstantInteger(index);
|
||||
if (indexValue > replacements.size()) {
|
||||
// Out of bounds access, this is illegal IR.
|
||||
return false;
|
||||
} else {
|
||||
const Instruction* var = replacements[indexValue];
|
||||
const Instruction* var = replacements[static_cast<size_t>(indexValue)];
|
||||
if (chain->NumInOperands() > 2) {
|
||||
// Replace input access chain with another access chain.
|
||||
BasicBlock::iterator chainIter(chain);
|
||||
@ -457,16 +457,16 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source,
|
||||
}
|
||||
}
|
||||
|
||||
size_t ScalarReplacementPass::GetIntegerLiteral(const Operand& op) const {
|
||||
uint64_t ScalarReplacementPass::GetIntegerLiteral(const Operand& op) const {
|
||||
assert(op.words.size() <= 2);
|
||||
size_t len = 0;
|
||||
uint64_t len = 0;
|
||||
for (uint32_t i = 0; i != op.words.size(); ++i) {
|
||||
len |= (op.words[i] << (32 * i));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t ScalarReplacementPass::GetConstantInteger(
|
||||
uint64_t ScalarReplacementPass::GetConstantInteger(
|
||||
const Instruction* constant) const {
|
||||
assert(get_def_use_mgr()->GetDef(constant->type_id())->opcode() ==
|
||||
SpvOpTypeInt);
|
||||
@ -480,7 +480,7 @@ size_t ScalarReplacementPass::GetConstantInteger(
|
||||
return GetIntegerLiteral(op);
|
||||
}
|
||||
|
||||
size_t ScalarReplacementPass::GetArrayLength(
|
||||
uint64_t ScalarReplacementPass::GetArrayLength(
|
||||
const Instruction* arrayType) const {
|
||||
assert(arrayType->opcode() == SpvOpTypeArray);
|
||||
const Instruction* length =
|
||||
@ -488,14 +488,14 @@ size_t ScalarReplacementPass::GetArrayLength(
|
||||
return GetConstantInteger(length);
|
||||
}
|
||||
|
||||
size_t ScalarReplacementPass::GetNumElements(const Instruction* type) const {
|
||||
uint64_t ScalarReplacementPass::GetNumElements(const Instruction* type) const {
|
||||
assert(type->opcode() == SpvOpTypeVector ||
|
||||
type->opcode() == SpvOpTypeMatrix);
|
||||
const Operand& op = type->GetInOperand(1u);
|
||||
assert(op.words.size() <= 2);
|
||||
size_t len = 0;
|
||||
for (uint32_t i = 0; i != op.words.size(); ++i) {
|
||||
len |= (op.words[i] << (32 * i));
|
||||
uint64_t len = 0;
|
||||
for (size_t i = 0; i != op.words.size(); ++i) {
|
||||
len |= (static_cast<uint64_t>(op.words[i]) << (32ull * i));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -717,7 +717,7 @@ bool ScalarReplacementPass::CheckStore(const Instruction* inst,
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool ScalarReplacementPass::IsLargerThanSizeLimit(size_t length) const {
|
||||
bool ScalarReplacementPass::IsLargerThanSizeLimit(uint64_t length) const {
|
||||
if (max_num_elements_ == 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -157,18 +157,18 @@ class ScalarReplacementPass : public Pass {
|
||||
// Returns the value of an OpConstant of integer type.
|
||||
//
|
||||
// |constant| must use two or fewer words to generate the value.
|
||||
size_t GetConstantInteger(const Instruction* constant) const;
|
||||
uint64_t GetConstantInteger(const Instruction* constant) const;
|
||||
|
||||
// Returns the integer literal for |op|.
|
||||
size_t GetIntegerLiteral(const Operand& op) const;
|
||||
uint64_t GetIntegerLiteral(const Operand& op) const;
|
||||
|
||||
// Returns the array length for |arrayInst|.
|
||||
size_t GetArrayLength(const Instruction* arrayInst) const;
|
||||
uint64_t GetArrayLength(const Instruction* arrayInst) const;
|
||||
|
||||
// Returns the number of elements in |type|.
|
||||
//
|
||||
// |type| must be a vector or matrix type.
|
||||
size_t GetNumElements(const Instruction* type) const;
|
||||
uint64_t GetNumElements(const Instruction* type) const;
|
||||
|
||||
// Returns true if |id| is a specialization constant.
|
||||
//
|
||||
@ -228,7 +228,7 @@ class ScalarReplacementPass : public Pass {
|
||||
// Limit on the number of members in an object that will be replaced.
|
||||
// 0 means there is no limit.
|
||||
uint32_t max_num_elements_;
|
||||
bool IsLargerThanSizeLimit(size_t length) const;
|
||||
bool IsLargerThanSizeLimit(uint64_t length) const;
|
||||
char name_[55];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user