Skip to content

Commit 00b3499

Browse files
committed
Use MutableArrayRef for APFloat::convertToInteger
As discussed on D31074, use MutableArrayRef for destination integer buffers to help assert before stack overflows happen. llvm-svn: 298253
1 parent 195f23c commit 00b3499

File tree

6 files changed

+63
-43
lines changed

6 files changed

+63
-43
lines changed

llvm/include/llvm/ADT/APFloat.h

+10-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define LLVM_ADT_APFLOAT_H
1919

2020
#include "llvm/ADT/APInt.h"
21+
#include "llvm/ADT/ArrayRef.h"
2122
#include "llvm/Support/ErrorHandling.h"
2223
#include <memory>
2324

@@ -273,8 +274,8 @@ class IEEEFloat final : public APFloatBase {
273274
/// @{
274275

275276
opStatus convert(const fltSemantics &, roundingMode, bool *);
276-
opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode,
277-
bool *) const;
277+
opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
278+
roundingMode, bool *) const;
278279
opStatus convertFromAPInt(const APInt &, bool, roundingMode);
279280
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
280281
bool, roundingMode);
@@ -495,8 +496,9 @@ class IEEEFloat final : public APFloatBase {
495496
opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract);
496497
opStatus handleOverflow(roundingMode);
497498
bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
498-
opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
499-
roundingMode, bool *) const;
499+
opStatus convertToSignExtendedInteger(MutableArrayRef<integerPart>,
500+
unsigned int, bool, roundingMode,
501+
bool *) const;
500502
opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
501503
roundingMode);
502504
opStatus convertFromHexadecimalString(StringRef, roundingMode);
@@ -625,8 +627,8 @@ class DoubleAPFloat final : public APFloatBase {
625627
opStatus convertFromString(StringRef, roundingMode);
626628
opStatus next(bool nextDown);
627629

628-
opStatus convertToInteger(integerPart *Input, unsigned int Width,
629-
bool IsSigned, roundingMode RM,
630+
opStatus convertToInteger(MutableArrayRef<integerPart> Input,
631+
unsigned int Width, bool IsSigned, roundingMode RM,
630632
bool *IsExact) const;
631633
opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM);
632634
opStatus convertFromSignExtendedInteger(const integerPart *Input,
@@ -1055,8 +1057,8 @@ class APFloat : public APFloatBase {
10551057

10561058
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
10571059
bool *losesInfo);
1058-
opStatus convertToInteger(integerPart *Input, unsigned int Width,
1059-
bool IsSigned, roundingMode RM,
1060+
opStatus convertToInteger(MutableArrayRef<integerPart> Input,
1061+
unsigned int Width, bool IsSigned, roundingMode RM,
10601062
bool *IsExact) const {
10611063
APFLOAT_DISPATCH_ON_SEMANTICS(
10621064
convertToInteger(Input, Width, IsSigned, RM, IsExact));

llvm/include/llvm/ADT/ArrayRef.h

+12
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,18 @@ namespace llvm {
487487
return ArrayRef<T>(Arr);
488488
}
489489

490+
/// Construct a MutableArrayRef from a single element.
491+
template<typename T>
492+
MutableArrayRef<T> makeMutableArrayRef(T &OneElt) {
493+
return OneElt;
494+
}
495+
496+
/// Construct a MutableArrayRef from a pointer and length.
497+
template<typename T>
498+
MutableArrayRef<T> makeMutableArrayRef(T *data, size_t length) {
499+
return MutableArrayRef<T>(data, length);
500+
}
501+
490502
/// @}
491503
/// @name ArrayRef Comparison Operators
492504
/// @{

llvm/lib/Analysis/ConstantFolding.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1518,9 +1518,9 @@ Constant *ConstantFoldSSEConvertToInt(const APFloat &Val, bool roundTowardZero,
15181518
bool isExact = false;
15191519
APFloat::roundingMode mode = roundTowardZero? APFloat::rmTowardZero
15201520
: APFloat::rmNearestTiesToEven;
1521-
APFloat::opStatus status = Val.convertToInteger(&UIntVal, ResultWidth,
1522-
/*isSigned=*/true, mode,
1523-
&isExact);
1521+
APFloat::opStatus status =
1522+
Val.convertToInteger(makeMutableArrayRef(UIntVal), ResultWidth,
1523+
/*isSigned=*/true, mode, &isExact);
15241524
if (status != APFloat::opOK &&
15251525
(!roundTowardZero || status != APFloat::opInexact))
15261526
return nullptr;

llvm/lib/ExecutionEngine/ExecutionEngine.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
727727
APFloat apf = APFloat(APFloat::x87DoubleExtended(), GV.IntVal);
728728
uint64_t v;
729729
bool ignored;
730-
(void)apf.convertToInteger(&v, BitWidth,
730+
(void)apf.convertToInteger(makeMutableArrayRef(v), BitWidth,
731731
CE->getOpcode()==Instruction::FPToSI,
732732
APFloat::rmTowardZero, &ignored);
733733
GV.IntVal = v; // endian?

llvm/lib/Support/APFloat.cpp

+34-29
Original file line numberDiff line numberDiff line change
@@ -1716,9 +1716,10 @@ IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) {
17161716
int parts = partCount();
17171717
integerPart *x = new integerPart[parts];
17181718
bool ignored;
1719-
fs = V.convertToInteger(x, parts * integerPartWidth, true,
1720-
rmNearestTiesToEven, &ignored);
1721-
if (fs==opInvalidOp) {
1719+
fs = V.convertToInteger(makeMutableArrayRef(x, parts),
1720+
parts * integerPartWidth, true, rmNearestTiesToEven,
1721+
&ignored);
1722+
if (fs == opInvalidOp) {
17221723
delete[] x;
17231724
return fs;
17241725
}
@@ -1756,9 +1757,10 @@ IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
17561757
int parts = partCount();
17571758
integerPart *x = new integerPart[parts];
17581759
bool ignored;
1759-
fs = V.convertToInteger(x, parts * integerPartWidth, true,
1760-
rmTowardZero, &ignored);
1761-
if (fs==opInvalidOp) {
1760+
fs = V.convertToInteger(makeMutableArrayRef(x, parts),
1761+
parts * integerPartWidth, true, rmTowardZero,
1762+
&ignored);
1763+
if (fs == opInvalidOp) {
17621764
delete[] x;
17631765
return fs;
17641766
}
@@ -2051,7 +2053,7 @@ IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics,
20512053
Note that for conversions to integer type the C standard requires
20522054
round-to-zero to always be used. */
20532055
IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
2054-
integerPart *parts, unsigned int width, bool isSigned,
2056+
MutableArrayRef<integerPart> parts, unsigned int width, bool isSigned,
20552057
roundingMode rounding_mode, bool *isExact) const {
20562058
lostFraction lost_fraction;
20572059
const integerPart *src;
@@ -2064,9 +2066,10 @@ IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
20642066
return opInvalidOp;
20652067

20662068
dstPartsCount = partCountForBits(width);
2069+
assert(dstPartsCount <= parts.size() && "Integer too big");
20672070

20682071
if (category == fcZero) {
2069-
APInt::tcSet(parts, 0, dstPartsCount);
2072+
APInt::tcSet(parts.data(), 0, dstPartsCount);
20702073
// Negative zero can't be represented as an int.
20712074
*isExact = !sign;
20722075
return opOK;
@@ -2078,7 +2081,7 @@ IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
20782081
the destination. */
20792082
if (exponent < 0) {
20802083
/* Our absolute value is less than one; truncate everything. */
2081-
APInt::tcSet(parts, 0, dstPartsCount);
2084+
APInt::tcSet(parts.data(), 0, dstPartsCount);
20822085
/* For exponent -1 the integer bit represents .5, look at that.
20832086
For smaller exponents leftmost truncated bit is 0. */
20842087
truncatedBits = semantics->precision -1U - exponent;
@@ -2094,11 +2097,13 @@ IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
20942097
if (bits < semantics->precision) {
20952098
/* We truncate (semantics->precision - bits) bits. */
20962099
truncatedBits = semantics->precision - bits;
2097-
APInt::tcExtract(parts, dstPartsCount, src, bits, truncatedBits);
2100+
APInt::tcExtract(parts.data(), dstPartsCount, src, bits, truncatedBits);
20982101
} else {
20992102
/* We want at least as many bits as are available. */
2100-
APInt::tcExtract(parts, dstPartsCount, src, semantics->precision, 0);
2101-
APInt::tcShiftLeft(parts, dstPartsCount, bits - semantics->precision);
2103+
APInt::tcExtract(parts.data(), dstPartsCount, src, semantics->precision,
2104+
0);
2105+
APInt::tcShiftLeft(parts.data(), dstPartsCount,
2106+
bits - semantics->precision);
21022107
truncatedBits = 0;
21032108
}
21042109
}
@@ -2110,15 +2115,15 @@ IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
21102115
truncatedBits);
21112116
if (lost_fraction != lfExactlyZero &&
21122117
roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
2113-
if (APInt::tcIncrement(parts, dstPartsCount))
2118+
if (APInt::tcIncrement(parts.data(), dstPartsCount))
21142119
return opInvalidOp; /* Overflow. */
21152120
}
21162121
} else {
21172122
lost_fraction = lfExactlyZero;
21182123
}
21192124

21202125
/* Step 3: check if we fit in the destination. */
2121-
unsigned int omsb = APInt::tcMSB(parts, dstPartsCount) + 1;
2126+
unsigned int omsb = APInt::tcMSB(parts.data(), dstPartsCount) + 1;
21222127

21232128
if (sign) {
21242129
if (!isSigned) {
@@ -2129,15 +2134,16 @@ IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
21292134
/* It takes omsb bits to represent the unsigned integer value.
21302135
We lose a bit for the sign, but care is needed as the
21312136
maximally negative integer is a special case. */
2132-
if (omsb == width && APInt::tcLSB(parts, dstPartsCount) + 1 != omsb)
2137+
if (omsb == width &&
2138+
APInt::tcLSB(parts.data(), dstPartsCount) + 1 != omsb)
21332139
return opInvalidOp;
21342140

21352141
/* This case can happen because of rounding. */
21362142
if (omsb > width)
21372143
return opInvalidOp;
21382144
}
21392145

2140-
APInt::tcNegate (parts, dstPartsCount);
2146+
APInt::tcNegate (parts.data(), dstPartsCount);
21412147
} else {
21422148
if (omsb >= width + !isSigned)
21432149
return opInvalidOp;
@@ -2159,11 +2165,10 @@ IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
21592165
the original value. This is almost equivalent to result==opOK,
21602166
except for negative zeroes.
21612167
*/
2162-
IEEEFloat::opStatus IEEEFloat::convertToInteger(integerPart *parts,
2163-
unsigned int width,
2164-
bool isSigned,
2165-
roundingMode rounding_mode,
2166-
bool *isExact) const {
2168+
IEEEFloat::opStatus
2169+
IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts,
2170+
unsigned int width, bool isSigned,
2171+
roundingMode rounding_mode, bool *isExact) const {
21672172
opStatus fs;
21682173

21692174
fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
@@ -2173,6 +2178,7 @@ IEEEFloat::opStatus IEEEFloat::convertToInteger(integerPart *parts,
21732178
unsigned int bits, dstPartsCount;
21742179

21752180
dstPartsCount = partCountForBits(width);
2181+
assert(dstPartsCount <= parts.size() && "Integer too big");
21762182

21772183
if (category == fcNaN)
21782184
bits = 0;
@@ -2181,9 +2187,9 @@ IEEEFloat::opStatus IEEEFloat::convertToInteger(integerPart *parts,
21812187
else
21822188
bits = width - isSigned;
21832189

2184-
APInt::tcSetLeastSignificantBits(parts, dstPartsCount, bits);
2190+
APInt::tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits);
21852191
if (sign && isSigned)
2186-
APInt::tcShiftLeft(parts, dstPartsCount, width - 1);
2192+
APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1);
21872193
}
21882194

21892195
return fs;
@@ -4293,11 +4299,10 @@ APFloat::opStatus DoubleAPFloat::next(bool nextDown) {
42934299
return Ret;
42944300
}
42954301

4296-
APFloat::opStatus DoubleAPFloat::convertToInteger(integerPart *Input,
4297-
unsigned int Width,
4298-
bool IsSigned,
4299-
roundingMode RM,
4300-
bool *IsExact) const {
4302+
APFloat::opStatus
4303+
DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input,
4304+
unsigned int Width, bool IsSigned,
4305+
roundingMode RM, bool *IsExact) const {
43014306
assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43024307
return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
43034308
.convertToInteger(Input, Width, IsSigned, RM, IsExact);
@@ -4511,7 +4516,7 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result,
45114516
bool *isExact) const {
45124517
unsigned bitWidth = result.getBitWidth();
45134518
SmallVector<uint64_t, 4> parts(result.getNumWords());
4514-
opStatus status = convertToInteger(parts.data(), bitWidth, result.isSigned(),
4519+
opStatus status = convertToInteger(parts, bitWidth, result.isSigned(),
45154520
rounding_mode, isExact);
45164521
// Keeps the original signed-ness.
45174522
result = APInt(bitWidth, parts);

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,9 @@ static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) {
231231
bool isExact = false;
232232
// See if we can convert this to an int64_t
233233
uint64_t UIntVal;
234-
if (APF.convertToInteger(&UIntVal, 64, true, APFloat::rmTowardZero,
235-
&isExact) != APFloat::opOK || !isExact)
234+
if (APF.convertToInteger(makeMutableArrayRef(UIntVal), 64, true,
235+
APFloat::rmTowardZero, &isExact) != APFloat::opOK ||
236+
!isExact)
236237
return false;
237238
IntVal = UIntVal;
238239
return true;

0 commit comments

Comments
 (0)