Skip to content

Commit

Permalink
runtime intrinsics: correct several
Browse files Browse the repository at this point in the history
flipsign was using the wrong argument
several others could trigger an LLVM assertion on divide-by-zero
  • Loading branch information
vtjnash committed Nov 7, 2017
1 parent 8122daf commit 039aeb0
Showing 1 changed file with 41 additions and 32 deletions.
73 changes: 41 additions & 32 deletions src/APInt-C.cpp
Expand Up @@ -84,34 +84,26 @@ void LLVMMul(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr

extern "C" JL_DLLEXPORT
void LLVMSDiv(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
a = a.sdiv(b);
ASSIGN(r, a)
if (LLVMDiv_sov(numbits, pa, pb, pr))
jl_throw(jl_diverror_exception);
}

extern "C" JL_DLLEXPORT
void LLVMUDiv(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
a = a.udiv(b);
ASSIGN(r, a)
if (LLVMDiv_uov(numbits, pa, pb, pr))
jl_throw(jl_diverror_exception);
}

extern "C" JL_DLLEXPORT
void LLVMSRem(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
a = a.srem(b);
ASSIGN(r, a)
if (LLVMRem_sov(numbits, pa, pb, pr))
jl_throw(jl_diverror_exception);
}

extern "C" JL_DLLEXPORT
void LLVMURem(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
a = a.urem(b);
ASSIGN(r, a)
if (LLVMRem_uov(numbits, pa, pb, pr))
jl_throw(jl_diverror_exception);
}

extern "C" JL_DLLEXPORT
Expand Down Expand Up @@ -274,6 +266,8 @@ extern "C" JL_DLLEXPORT
int LLVMDiv_sov(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
if (!b)
return true;
bool Overflow;
a = a.sdiv_ov(b, Overflow);
ASSIGN(r, a)
Expand All @@ -284,29 +278,32 @@ extern "C" JL_DLLEXPORT
int LLVMDiv_uov(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
if (!b)
return true;
a = a.udiv(b);
ASSIGN(r, a)
// unsigned division cannot overflow
return false;
}

extern "C" JL_DLLEXPORT
int LLVMRem_sov(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
if (!b)
return true;
a = a.srem(b);
ASSIGN(r, a)
// signed remainder cannot overflow
return false;
}

extern "C" JL_DLLEXPORT
int LLVMRem_uov(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
if (!b)
return true;
a = a.urem(b);
ASSIGN(r, a)
// unsigned remainder cannot overflow
return false;
}

Expand Down Expand Up @@ -391,8 +388,11 @@ int LLVMFPtoUI_exact(unsigned numbits, integerPart *pa, unsigned onumbits, integ

extern "C" JL_DLLEXPORT
void LLVMSItoFP(unsigned numbits, integerPart *pa, unsigned onumbits, integerPart *pr) {
CREATE(a)
double val = a.roundToDouble(true);
double val;
{ // end scope before jl_error call
CREATE(a)
val = a.roundToDouble(true);
}
if (onumbits == 32)
*(float*)pr = val;
else if (onumbits == 64)
Expand All @@ -403,8 +403,11 @@ void LLVMSItoFP(unsigned numbits, integerPart *pa, unsigned onumbits, integerPar

extern "C" JL_DLLEXPORT
void LLVMUItoFP(unsigned numbits, integerPart *pa, unsigned onumbits, integerPart *pr) {
CREATE(a)
double val = a.roundToDouble(false);
double val;
{ // end scope before jl_error call
CREATE(a)
val = a.roundToDouble(false);
}
if (onumbits == 32)
*(float*)pr = val;
else if (onumbits == 64)
Expand Down Expand Up @@ -476,24 +479,30 @@ unsigned countTrailingZeros_64(uint64_t Val) {

extern "C" JL_DLLEXPORT
void jl_LLVMSMod(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
CREATE(a)
CREATE(b)
APInt r = a.srem(b);
if (a.isNegative() != b.isNegative()) {
r = (b + r).srem(b);
{ // end scope before jl_error call
CREATE(a)
CREATE(b)
if (!!b) {
APInt r = a.srem(b);
if (a.isNegative() != b.isNegative()) {
r = (b + r).srem(b);
}
ASSIGN(r, r)
return;
}
}
ASSIGN(r, r)
jl_throw(jl_diverror_exception);
}

extern "C" JL_DLLEXPORT
void jl_LLVMFlipSign(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) {
unsigned numbytes = RoundUpToAlignment(numbits, host_char_bit) / host_char_bit;
unsigned numbytes = (numbits + host_char_bit - 1) / host_char_bit;
int signbit = (numbits - 1) % host_char_bit;
int sign = ((unsigned char*)pa)[numbytes - 1] & (1 << signbit) ? -1 : 0;
int sign = ((unsigned char*)pb)[numbytes - 1] & (1 << signbit);
if (sign)
LLVMNeg(numbits, pa, pr);
else
memcpy(pr, pa, numbytes);
memcpy(pr, pa, numbytes);
}

extern "C" JL_DLLEXPORT
Expand Down

0 comments on commit 039aeb0

Please sign in to comment.