Fix PR47973: Addressing integer division edge case with INT_MIN

Adjustment to integer division in int_div_impl.inc to avoid undefined behaviour that can occur as a result of having INT_MIN as one of the parameters.

Reviewed By: sepavloff

Differential Revision: https://reviews.llvm.org/D90218
This commit is contained in:
Ayshe Kuran 2020-11-10 14:15:32 +00:00 committed by Thomas Preud'homme
parent dcde6f17fd
commit 55ec2ba4bc
1 changed files with 12 additions and 12 deletions

View File

@ -72,24 +72,24 @@ static __inline fixuint_t __umodXi3(fixuint_t n, fixuint_t d) {
#ifdef COMPUTE_UDIV
static __inline fixint_t __divXi3(fixint_t a, fixint_t b) {
const int N = (int)(sizeof(fixint_t) * CHAR_BIT) - 1;
fixint_t s_a = a >> N; // s_a = a < 0 ? -1 : 0
fixint_t s_b = b >> N; // s_b = b < 0 ? -1 : 0
a = (a ^ s_a) - s_a; // negate if s_a == -1
b = (b ^ s_b) - s_b; // negate if s_b == -1
s_a ^= s_b; // sign of quotient
return (COMPUTE_UDIV(a, b) ^ s_a) - s_a; // negate if s_a == -1
fixint_t s_a = a >> N; // s_a = a < 0 ? -1 : 0
fixint_t s_b = b >> N; // s_b = b < 0 ? -1 : 0
fixuint_t a_u = (fixuint_t)(a ^ s_a) + (-s_a); // negate if s_a == -1
fixuint_t b_u = (fixuint_t)(b ^ s_b) + (-s_b); // negate if s_b == -1
s_a ^= s_b; // sign of quotient
return (COMPUTE_UDIV(a_u, b_u) ^ s_a) + (-s_a); // negate if s_a == -1
}
#endif // COMPUTE_UDIV
#ifdef ASSIGN_UMOD
static __inline fixint_t __modXi3(fixint_t a, fixint_t b) {
const int N = (int)(sizeof(fixint_t) * CHAR_BIT) - 1;
fixint_t s = b >> N; // s = b < 0 ? -1 : 0
b = (b ^ s) - s; // negate if s == -1
s = a >> N; // s = a < 0 ? -1 : 0
a = (a ^ s) - s; // negate if s == -1
fixint_t s = b >> N; // s = b < 0 ? -1 : 0
fixuint_t b_u = (fixuint_t)(b ^ s) + (-s); // negate if s == -1
s = a >> N; // s = a < 0 ? -1 : 0
fixuint_t a_u = (fixuint_t)(a ^ s) + (-s); // negate if s == -1
fixuint_t res;
ASSIGN_UMOD(res, a, b);
return (res ^ s) - s; // negate if s == -1
ASSIGN_UMOD(res, a_u, b_u);
return (res ^ s) + (-s); // negate if s == -1
}
#endif // ASSIGN_UMOD