forked from OSchip/llvm-project
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:
parent
dcde6f17fd
commit
55ec2ba4bc
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue