Make APFloat->int conversions deterministic even in

cases with undefined behavior.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42328 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2007-09-25 23:07:07 +00:00
parent 7086ce7268
commit 0edc47ad7b
2 changed files with 33 additions and 7 deletions

View File

@ -1399,13 +1399,28 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
unsigned int msb, partsCount;
int bits;
/* Handle the three special cases first. */
if(category == fcInfinity || category == fcNaN)
return opInvalidOp;
partsCount = partCountForBits(width);
if(category == fcZero) {
/* Handle the three special cases first. We produce
a deterministic result even for the Invalid cases. */
if (category == fcNaN) {
// Neither sign nor isSigned affects this.
APInt::tcSet(parts, 0, partsCount);
return opInvalidOp;
}
if (category == fcInfinity) {
if (!sign && isSigned)
APInt::tcSetLeastSignificantBits(parts, partsCount, width-1);
else if (!sign && !isSigned)
APInt::tcSetLeastSignificantBits(parts, partsCount, width);
else if (sign && isSigned) {
APInt::tcSetLeastSignificantBits(parts, partsCount, 1);
APInt::tcShiftLeft(parts, partsCount, width-1);
} else // sign && !isSigned
APInt::tcSet(parts, 0, partsCount);
return opInvalidOp;
}
if (category == fcZero) {
APInt::tcSet(parts, 0, partsCount);
return opOK;
}
@ -1418,6 +1433,19 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
if(bits > 0) {
lost_fraction = tmp.shiftSignificandRight(bits);
} else {
if (-bits >= semantics->precision) {
// Unrepresentably large.
if (!sign && isSigned)
APInt::tcSetLeastSignificantBits(parts, partsCount, width-1);
else if (!sign && !isSigned)
APInt::tcSetLeastSignificantBits(parts, partsCount, width);
else if (sign && isSigned) {
APInt::tcSetLeastSignificantBits(parts, partsCount, 1);
APInt::tcShiftLeft(parts, partsCount, width-1);
} else // sign && !isSigned
APInt::tcSet(parts, 0, partsCount);
return (opStatus)(opOverflow | opInexact);
}
tmp.shiftSignificandLeft(-bits);
lost_fraction = lfExactlyZero;
}

View File

@ -197,8 +197,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
APFloat::opStatus status = V.convertToInteger(x, DestBitWidth,
opc==Instruction::FPToSI,
APFloat::rmTowardZero);
if (status!=APFloat::opOK && status!=APFloat::opInexact)
return 0; // give up
APInt Val(DestBitWidth, 2, x);
return ConstantInt::get(Val);
}