Restructure FloatAttr::get(Type, double) to allow for loss of precision when converting the double value to the target type semantics. A comment is added to discourage the use of this method for non simple constants. The new handling also removes the direct use of the float constructor for APFloat to avoid runtime float cast asan errors.

PiperOrigin-RevId: 230014696
This commit is contained in:
River Riddle 2019-01-18 16:31:58 -08:00 committed by jpienaar
parent d7522eb264
commit 174f66bc8a
2 changed files with 22 additions and 25 deletions

View File

@ -174,11 +174,15 @@ public:
using ImplType = detail::FloatAttributeStorage;
using ValueType = APFloat;
/// Return a float attribute for the specified value in the specified type.
/// These methods should only be used for simple constant values, e.g 1.0/2.0,
/// that are known-valid both as host double and the 'type' format.
static FloatAttr get(Type type, double value);
static FloatAttr get(Type type, const APFloat &value);
static FloatAttr getChecked(Type type, double value, Location loc);
/// Return a float attribute for the specified value in the specified type.
static FloatAttr get(Type type, const APFloat &value);
APFloat getValue() const;
/// This function is used to convert the value to a double, even if it loses

View File

@ -754,30 +754,23 @@ IntegerAttr IntegerAttr::get(Type type, int64_t value) {
static FloatAttr getFloatAttr(Type type, double value,
llvm::Optional<Location> loc) {
Optional<APFloat> val;
if (type.isBF16())
// Treat BF16 as double because it is not supported in LLVM's APFloat.
// TODO(jpienaar): add BF16 support to APFloat?
val = APFloat(value);
else if (type.isF32())
val = APFloat(static_cast<float>(value));
else if (type.isF64())
val = APFloat(value);
else {
// This handles, e.g., F16 because there is no APFloat constructor for it.
bool unused;
val = APFloat(value);
auto fltType = type.cast<FloatType>();
auto status = (*val).convert(fltType.getFloatSemantics(),
APFloat::rmTowardZero, &unused);
if (status != APFloat::opOK) {
if (loc)
type.getContext()->emitError(
*loc, "failed to convert floating point value to requested type");
return nullptr;
}
if (!type.isa<FloatType>()) {
if (loc)
type.getContext()->emitError(*loc, "expected floating point type");
return nullptr;
}
return FloatAttr::get(type, *val);
// Treat BF16 as double because it is not supported in LLVM's APFloat.
// TODO(jpienaar): add BF16 support to APFloat?
if (type.isBF16() || type.isF64())
return FloatAttr::get(type, APFloat(value));
// This handles, e.g., F16 because there is no APFloat constructor for it.
bool unused;
APFloat val(value);
val.convert(type.cast<FloatType>().getFloatSemantics(),
APFloat::rmNearestTiesToEven, &unused);
return FloatAttr::get(type, val);
}
FloatAttr FloatAttr::getChecked(Type type, double value, Location loc) {