Skip to content

Commit 4f13f35

Browse files
[NFC][LLVM][AsmWriter] Extract logic to write out ConstantFP from WriteConstantInternal.
This makes is easier to extend the code to support vector types.
1 parent 485ebbf commit 4f13f35

File tree

1 file changed

+94
-88
lines changed

1 file changed

+94
-88
lines changed

llvm/lib/IR/AsmWriter.cpp

Lines changed: 94 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,99 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
14061406
}
14071407
}
14081408

1409+
static void WriteAPFloatInternal(raw_ostream &Out, const APFloat &APF) {
1410+
if (&APF.getSemantics() == &APFloat::IEEEsingle() ||
1411+
&APF.getSemantics() == &APFloat::IEEEdouble()) {
1412+
// We would like to output the FP constant value in exponential notation,
1413+
// but we cannot do this if doing so will lose precision. Check here to
1414+
// make sure that we only output it in exponential format if we can parse
1415+
// the value back and get the same value.
1416+
//
1417+
bool ignored;
1418+
bool isDouble = &APF.getSemantics() == &APFloat::IEEEdouble();
1419+
bool isInf = APF.isInfinity();
1420+
bool isNaN = APF.isNaN();
1421+
1422+
if (!isInf && !isNaN) {
1423+
double Val = APF.convertToDouble();
1424+
SmallString<128> StrVal;
1425+
APF.toString(StrVal, 6, 0, false);
1426+
// Check to make sure that the stringized number is not some string like
1427+
// "Inf" or NaN, that atof will accept, but the lexer will not. Check
1428+
// that the string matches the "[-+]?[0-9]" regex.
1429+
//
1430+
assert((isDigit(StrVal[0]) ||
1431+
((StrVal[0] == '-' || StrVal[0] == '+') && isDigit(StrVal[1]))) &&
1432+
"[-+]?[0-9] regex does not match!");
1433+
// Reparse stringized version!
1434+
if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
1435+
Out << StrVal;
1436+
return;
1437+
}
1438+
}
1439+
1440+
// Otherwise we could not reparse it to exactly the same value, so we must
1441+
// output the string in hexadecimal format! Note that loading and storing
1442+
// floating point types changes the bits of NaNs on some hosts, notably
1443+
// x86, so we must not use these types.
1444+
static_assert(sizeof(double) == sizeof(uint64_t),
1445+
"assuming that double is 64 bits!");
1446+
APFloat apf = APF;
1447+
1448+
// Floats are represented in ASCII IR as double, convert.
1449+
// FIXME: We should allow 32-bit hex float and remove this.
1450+
if (!isDouble) {
1451+
// A signaling NaN is quieted on conversion, so we need to recreate the
1452+
// expected value after convert (quiet bit of the payload is clear).
1453+
bool IsSNAN = apf.isSignaling();
1454+
apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
1455+
&ignored);
1456+
if (IsSNAN) {
1457+
APInt Payload = apf.bitcastToAPInt();
1458+
apf =
1459+
APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(), &Payload);
1460+
}
1461+
}
1462+
1463+
Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
1464+
return;
1465+
}
1466+
1467+
// Either half, bfloat or some form of long double.
1468+
// These appear as a magic letter identifying the type, then a
1469+
// fixed number of hex digits.
1470+
Out << "0x";
1471+
APInt API = APF.bitcastToAPInt();
1472+
if (&APF.getSemantics() == &APFloat::x87DoubleExtended()) {
1473+
Out << 'K';
1474+
Out << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
1475+
/*Upper=*/true);
1476+
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
1477+
/*Upper=*/true);
1478+
} else if (&APF.getSemantics() == &APFloat::IEEEquad()) {
1479+
Out << 'L';
1480+
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
1481+
/*Upper=*/true);
1482+
Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
1483+
/*Upper=*/true);
1484+
} else if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
1485+
Out << 'M';
1486+
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
1487+
/*Upper=*/true);
1488+
Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
1489+
/*Upper=*/true);
1490+
} else if (&APF.getSemantics() == &APFloat::IEEEhalf()) {
1491+
Out << 'H';
1492+
Out << format_hex_no_prefix(API.getZExtValue(), 4,
1493+
/*Upper=*/true);
1494+
} else if (&APF.getSemantics() == &APFloat::BFloat()) {
1495+
Out << 'R';
1496+
Out << format_hex_no_prefix(API.getZExtValue(), 4,
1497+
/*Upper=*/true);
1498+
} else
1499+
llvm_unreachable("Unsupported floating point type");
1500+
}
1501+
14091502
static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
14101503
AsmWriterContext &WriterCtx) {
14111504
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
@@ -1418,94 +1511,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
14181511
}
14191512

14201513
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
1421-
const APFloat &APF = CFP->getValueAPF();
1422-
if (&APF.getSemantics() == &APFloat::IEEEsingle() ||
1423-
&APF.getSemantics() == &APFloat::IEEEdouble()) {
1424-
// We would like to output the FP constant value in exponential notation,
1425-
// but we cannot do this if doing so will lose precision. Check here to
1426-
// make sure that we only output it in exponential format if we can parse
1427-
// the value back and get the same value.
1428-
//
1429-
bool ignored;
1430-
bool isDouble = &APF.getSemantics() == &APFloat::IEEEdouble();
1431-
bool isInf = APF.isInfinity();
1432-
bool isNaN = APF.isNaN();
1433-
if (!isInf && !isNaN) {
1434-
double Val = APF.convertToDouble();
1435-
SmallString<128> StrVal;
1436-
APF.toString(StrVal, 6, 0, false);
1437-
// Check to make sure that the stringized number is not some string like
1438-
// "Inf" or NaN, that atof will accept, but the lexer will not. Check
1439-
// that the string matches the "[-+]?[0-9]" regex.
1440-
//
1441-
assert((isDigit(StrVal[0]) || ((StrVal[0] == '-' || StrVal[0] == '+') &&
1442-
isDigit(StrVal[1]))) &&
1443-
"[-+]?[0-9] regex does not match!");
1444-
// Reparse stringized version!
1445-
if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
1446-
Out << StrVal;
1447-
return;
1448-
}
1449-
}
1450-
// Otherwise we could not reparse it to exactly the same value, so we must
1451-
// output the string in hexadecimal format! Note that loading and storing
1452-
// floating point types changes the bits of NaNs on some hosts, notably
1453-
// x86, so we must not use these types.
1454-
static_assert(sizeof(double) == sizeof(uint64_t),
1455-
"assuming that double is 64 bits!");
1456-
APFloat apf = APF;
1457-
// Floats are represented in ASCII IR as double, convert.
1458-
// FIXME: We should allow 32-bit hex float and remove this.
1459-
if (!isDouble) {
1460-
// A signaling NaN is quieted on conversion, so we need to recreate the
1461-
// expected value after convert (quiet bit of the payload is clear).
1462-
bool IsSNAN = apf.isSignaling();
1463-
apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
1464-
&ignored);
1465-
if (IsSNAN) {
1466-
APInt Payload = apf.bitcastToAPInt();
1467-
apf = APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(),
1468-
&Payload);
1469-
}
1470-
}
1471-
Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
1472-
return;
1473-
}
1474-
1475-
// Either half, bfloat or some form of long double.
1476-
// These appear as a magic letter identifying the type, then a
1477-
// fixed number of hex digits.
1478-
Out << "0x";
1479-
APInt API = APF.bitcastToAPInt();
1480-
if (&APF.getSemantics() == &APFloat::x87DoubleExtended()) {
1481-
Out << 'K';
1482-
Out << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
1483-
/*Upper=*/true);
1484-
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
1485-
/*Upper=*/true);
1486-
return;
1487-
} else if (&APF.getSemantics() == &APFloat::IEEEquad()) {
1488-
Out << 'L';
1489-
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
1490-
/*Upper=*/true);
1491-
Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
1492-
/*Upper=*/true);
1493-
} else if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
1494-
Out << 'M';
1495-
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
1496-
/*Upper=*/true);
1497-
Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
1498-
/*Upper=*/true);
1499-
} else if (&APF.getSemantics() == &APFloat::IEEEhalf()) {
1500-
Out << 'H';
1501-
Out << format_hex_no_prefix(API.getZExtValue(), 4,
1502-
/*Upper=*/true);
1503-
} else if (&APF.getSemantics() == &APFloat::BFloat()) {
1504-
Out << 'R';
1505-
Out << format_hex_no_prefix(API.getZExtValue(), 4,
1506-
/*Upper=*/true);
1507-
} else
1508-
llvm_unreachable("Unsupported floating point type");
1514+
WriteAPFloatInternal(Out, CFP->getValueAPF());
15091515
return;
15101516
}
15111517

0 commit comments

Comments
 (0)