Skip to content

Commit 94bcf6f

Browse files
[mlir][Parser] Deduplicate fp parsing functionality
1 parent 093da29 commit 94bcf6f

File tree

5 files changed

+56
-87
lines changed

5 files changed

+56
-87
lines changed

mlir/lib/AsmParser/AsmParserImpl.h

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -288,32 +288,13 @@ class AsmParserImpl : public BaseT {
288288
bool isNegative = parser.consumeIf(Token::minus);
289289
Token curTok = parser.getToken();
290290
auto emitErrorAtTok = [&]() { return emitError(curTok.getLoc(), ""); };
291-
292-
// Check for a floating point value.
293-
if (curTok.is(Token::floatliteral)) {
294-
auto val = curTok.getFloatingPointValue();
295-
if (!val)
296-
return emitErrorAtTok() << "floating point value too large";
297-
parser.consumeToken(Token::floatliteral);
298-
result = APFloat(isNegative ? -*val : *val);
299-
bool losesInfo;
300-
result.convert(semantics, APFloat::rmNearestTiesToEven, &losesInfo);
301-
return success();
302-
}
303-
304-
// Check for a hexadecimal float value.
305-
if (curTok.is(Token::integer)) {
306-
FailureOr<APFloat> apResult = parseFloatFromIntegerLiteral(
307-
emitErrorAtTok, curTok, isNegative, semantics);
308-
if (failed(apResult))
309-
return failure();
310-
311-
result = *apResult;
312-
parser.consumeToken(Token::integer);
313-
return success();
314-
}
315-
316-
return emitErrorAtTok() << "expected floating point literal";
291+
FailureOr<APFloat> apResult =
292+
parseFloatFromLiteral(emitErrorAtTok, curTok, isNegative, semantics);
293+
if (failed(apResult))
294+
return failure();
295+
parser.consumeToken();
296+
result = *apResult;
297+
return success();
317298
}
318299

319300
/// Parse a floating point value from the stream.

mlir/lib/AsmParser/AttributeParser.cpp

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -658,36 +658,12 @@ TensorLiteralParser::getFloatAttrElements(SMLoc loc, FloatType eltTy,
658658
for (const auto &signAndToken : storage) {
659659
bool isNegative = signAndToken.first;
660660
const Token &token = signAndToken.second;
661-
662-
// Handle hexadecimal float literals.
663-
if (token.is(Token::integer) && token.getSpelling().starts_with("0x")) {
664-
auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
665-
FailureOr<APFloat> result = parseFloatFromIntegerLiteral(
666-
emitErrorAtTok, token, isNegative, eltTy.getFloatSemantics());
667-
if (failed(result))
668-
return failure();
669-
670-
floatValues.push_back(*result);
671-
continue;
672-
}
673-
674-
// Check to see if any decimal integers or booleans were parsed.
675-
if (!token.is(Token::floatliteral))
676-
return p.emitError()
677-
<< "expected floating-point elements, but parsed integer";
678-
679-
// Build the float values from tokens.
680-
auto val = token.getFloatingPointValue();
681-
if (!val)
682-
return p.emitError("floating point value too large for attribute");
683-
684-
APFloat apVal(isNegative ? -*val : *val);
685-
if (!eltTy.isF64()) {
686-
bool unused;
687-
apVal.convert(eltTy.getFloatSemantics(), APFloat::rmNearestTiesToEven,
688-
&unused);
689-
}
690-
floatValues.push_back(apVal);
661+
auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
662+
FailureOr<APFloat> result = parseFloatFromLiteral(
663+
emitErrorAtTok, token, isNegative, eltTy.getFloatSemantics());
664+
if (failed(result))
665+
return failure();
666+
floatValues.push_back(*result);
691667
}
692668
return success();
693669
}
@@ -905,34 +881,15 @@ ParseResult DenseArrayElementParser::parseIntegerElement(Parser &p) {
905881

906882
ParseResult DenseArrayElementParser::parseFloatElement(Parser &p) {
907883
bool isNegative = p.consumeIf(Token::minus);
908-
909884
Token token = p.getToken();
910-
std::optional<APFloat> result;
911-
auto floatType = cast<FloatType>(type);
912-
if (p.consumeIf(Token::integer)) {
913-
// Parse an integer literal as a float.
914-
auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
915-
FailureOr<APFloat> fromIntLit = parseFloatFromIntegerLiteral(
916-
emitErrorAtTok, token, isNegative, floatType.getFloatSemantics());
917-
if (failed(fromIntLit))
918-
return failure();
919-
result = *fromIntLit;
920-
} else if (p.consumeIf(Token::floatliteral)) {
921-
// Parse a floating point literal.
922-
std::optional<double> val = token.getFloatingPointValue();
923-
if (!val)
924-
return failure();
925-
result = APFloat(isNegative ? -*val : *val);
926-
if (!type.isF64()) {
927-
bool unused;
928-
result->convert(floatType.getFloatSemantics(),
929-
APFloat::rmNearestTiesToEven, &unused);
930-
}
931-
} else {
932-
return p.emitError("expected integer or floating point literal");
933-
}
934-
935-
append(result->bitcastToAPInt());
885+
auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
886+
FailureOr<APFloat> fromIntLit =
887+
parseFloatFromLiteral(emitErrorAtTok, token, isNegative,
888+
cast<FloatType>(type).getFloatSemantics());
889+
if (failed(fromIntLit))
890+
return failure();
891+
p.consumeToken();
892+
append(fromIntLit->bitcastToAPInt());
936893
return success();
937894
}
938895

mlir/lib/AsmParser/Parser.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,29 @@ FailureOr<APFloat> detail::parseFloatFromIntegerLiteral(
9999
return APFloat(semantics, truncatedValue);
100100
}
101101

102+
FailureOr<APFloat>
103+
detail::parseFloatFromLiteral(function_ref<InFlightDiagnostic()> emitError,
104+
const Token &tok, bool isNegative,
105+
const llvm::fltSemantics &semantics) {
106+
// Check for a floating point value.
107+
if (tok.is(Token::floatliteral)) {
108+
auto val = tok.getFloatingPointValue();
109+
if (!val)
110+
return emitError() << "floating point value too large";
111+
112+
APFloat result(isNegative ? -*val : *val);
113+
bool unused;
114+
result.convert(semantics, APFloat::rmNearestTiesToEven, &unused);
115+
return result;
116+
}
117+
118+
// Check for a hexadecimal float value.
119+
if (tok.is(Token::integer))
120+
return parseFloatFromIntegerLiteral(emitError, tok, isNegative, semantics);
121+
122+
return emitError() << "expected floating point literal";
123+
}
124+
102125
//===----------------------------------------------------------------------===//
103126
// CodeComplete
104127
//===----------------------------------------------------------------------===//

mlir/lib/AsmParser/Parser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ parseFloatFromIntegerLiteral(function_ref<InFlightDiagnostic()> emitError,
2222
const Token &tok, bool isNegative,
2323
const llvm::fltSemantics &semantics);
2424

25+
/// Parse a floating point value from a literal.
26+
FailureOr<APFloat>
27+
parseFloatFromLiteral(function_ref<InFlightDiagnostic()> emitError,
28+
const Token &tok, bool isNegative,
29+
const llvm::fltSemantics &semantics);
30+
2531
//===----------------------------------------------------------------------===//
2632
// Parser
2733
//===----------------------------------------------------------------------===//

mlir/test/IR/invalid-builtin-attributes.mlir

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ func.func @elementsattr_floattype1() -> () {
4545
// -----
4646

4747
func.func @elementsattr_floattype2() -> () {
48-
// expected-error@+1 {{expected floating-point elements, but parsed integer}}
48+
// expected-error@below {{unexpected decimal integer literal for a floating point value}}
49+
// expected-note@below {{add a trailing dot to make the literal a float}}
4950
"foo"(){bar = dense<[4]> : tensor<1xf32>} : () -> ()
5051
}
5152

@@ -138,21 +139,22 @@ func.func @float_in_int_tensor() {
138139
// -----
139140

140141
func.func @float_in_bool_tensor() {
141-
// expected-error @+1 {{expected integer elements, but parsed floating-point}}
142+
// expected-error@below {{expected integer elements, but parsed floating-point}}
142143
"foo"() {bar = dense<[true, 42.0]> : tensor<2xi1>} : () -> ()
143144
}
144145

145146
// -----
146147

147148
func.func @decimal_int_in_float_tensor() {
148-
// expected-error @+1 {{expected floating-point elements, but parsed integer}}
149+
// expected-error@below {{unexpected decimal integer literal for a floating point value}}
150+
// expected-note@below {{add a trailing dot to make the literal a float}}
149151
"foo"() {bar = dense<[42, 42.0]> : tensor<2xf32>} : () -> ()
150152
}
151153

152154
// -----
153155

154156
func.func @bool_in_float_tensor() {
155-
// expected-error @+1 {{expected floating-point elements, but parsed integer}}
157+
// expected-error @+1 {{expected floating point literal}}
156158
"foo"() {bar = dense<[42.0, true]> : tensor<2xf32>} : () -> ()
157159
}
158160

0 commit comments

Comments
 (0)