Fix overflow when negating INT_MIN. (#2293)

When doing (-INT_MIN) is considered overflow, so we cannot fold it by
actually performing the negation.

Fixes https://crbug.com/917991
This commit is contained in:
Steven Perron 2019-01-17 17:01:55 -05:00 committed by GitHub
parent 99c2c21cf4
commit 213e15e100
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 3 deletions

View File

@ -45,8 +45,13 @@ namespace {
uint32_t InstructionFolder::UnaryOperate(SpvOp opcode, uint32_t operand) const {
switch (opcode) {
// Arthimetics
case SpvOp::SpvOpSNegate:
return -static_cast<int32_t>(operand);
case SpvOp::SpvOpSNegate: {
int32_t s_operand = static_cast<int32_t>(operand);
if (s_operand == std::numeric_limits<int32_t>::min()) {
return s_operand;
}
return -s_operand;
}
case SpvOp::SpvOpNot:
return ~operand;
case SpvOp::SpvOpLogicalNot:

View File

@ -538,7 +538,15 @@ INSTANTIATE_TEST_CASE_P(TestCase, IntegerInstructionFoldingTest,
"%2 = OpShiftLeftLogical %int %int_2 %uint_32\n" +
"OpReturn\n" +
"OpFunctionEnd",
2, 0)
2, 0),
// Test case 29: fold -INT_MIN
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
"%2 = OpSNegate %int %int_min\n" +
"OpReturn\n" +
"OpFunctionEnd",
2, std::numeric_limits<int32_t>::min())
));
// clang-format on