mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 12:10:06 +00:00
Don't fold unsigned divides of an constant and a negation (#4457)
Negating an unsigned constant results in its two's complement which is still interpreted as unsigned. For example -2u becomes 4294967294u. Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/4456
This commit is contained in:
parent
881001070a
commit
869a550d26
@ -967,12 +967,11 @@ FoldingRule MergeDivMulArithmetic() {
|
||||
// Fold divides of a constant and a negation.
|
||||
// Cases:
|
||||
// (-x) / 2 = x / -2
|
||||
// 2 / (-x) = 2 / -x
|
||||
// 2 / (-x) = -2 / x
|
||||
FoldingRule MergeDivNegateArithmetic() {
|
||||
return [](IRContext* context, Instruction* inst,
|
||||
const std::vector<const analysis::Constant*>& constants) {
|
||||
assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv ||
|
||||
inst->opcode() == SpvOpUDiv);
|
||||
assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv);
|
||||
analysis::ConstantManager* const_mgr = context->get_constant_mgr();
|
||||
const analysis::Type* type =
|
||||
context->get_type_mgr()->GetType(inst->type_id());
|
||||
@ -2572,8 +2571,6 @@ void FoldingRules::AddFoldingRules() {
|
||||
|
||||
rules_[SpvOpStore].push_back(StoringUndef());
|
||||
|
||||
rules_[SpvOpUDiv].push_back(MergeDivNegateArithmetic());
|
||||
|
||||
rules_[SpvOpVectorShuffle].push_back(VectorShuffleFeedingShuffle());
|
||||
|
||||
rules_[SpvOpImageSampleImplicitLod].push_back(UpdateImageOperands());
|
||||
|
@ -5818,7 +5818,33 @@ INSTANTIATE_TEST_SUITE_P(MergeDivTest, MatchingInstructionFoldingTest,
|
||||
"%5 = OpFDiv %float %4 %2\n" +
|
||||
"OpReturn\n" +
|
||||
"OpFunctionEnd\n",
|
||||
5, true)
|
||||
5, true),
|
||||
// Test case 16: Do not merge udiv of snegate
|
||||
// (-x) / 2u
|
||||
InstructionFoldingCase<bool>(
|
||||
Header() +
|
||||
"%main = OpFunction %void None %void_func\n" +
|
||||
"%main_lab = OpLabel\n" +
|
||||
"%var = OpVariable %_ptr_uint Function\n" +
|
||||
"%2 = OpLoad %uint %var\n" +
|
||||
"%3 = OpSNegate %uint %2\n" +
|
||||
"%4 = OpUDiv %uint %3 %uint_2\n" +
|
||||
"OpReturn\n" +
|
||||
"OpFunctionEnd\n",
|
||||
4, false),
|
||||
// Test case 17: Do not merge udiv of snegate
|
||||
// 2u / (-x)
|
||||
InstructionFoldingCase<bool>(
|
||||
Header() +
|
||||
"%main = OpFunction %void None %void_func\n" +
|
||||
"%main_lab = OpLabel\n" +
|
||||
"%var = OpVariable %_ptr_uint Function\n" +
|
||||
"%2 = OpLoad %uint %var\n" +
|
||||
"%3 = OpSNegate %uint %2\n" +
|
||||
"%4 = OpUDiv %uint %uint_2 %3\n" +
|
||||
"OpReturn\n" +
|
||||
"OpFunctionEnd\n",
|
||||
4, false)
|
||||
));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(MergeAddTest, MatchingInstructionFoldingTest,
|
||||
|
Loading…
Reference in New Issue
Block a user