[flang-commits] [flang] [mlir] [mlir] Support human-readable float literals in the textual IR (PR #210422)
Victor Perez via flang-commits
flang-commits at lists.llvm.org
Fri Jul 24 12:56:48 PDT 2026
https://github.com/victor-eds updated https://github.com/llvm/llvm-project/pull/210422
>From 5971da3896e830c9242b1f73fa7d64a5fa39cb95 Mon Sep 17 00:00:00 2001
From: Victor Perez <victor.pc.upm at gmail.com>
Date: Fri, 17 Jul 2026 11:52:35 -0700
Subject: [PATCH] [mlir] Support human-readable float literals in the textual
IR
Add LLVM-style textual floating-point literals to the MLIR assembly
format, both parsed and printed:
+inf / -inf
+qnan / -qnan
+nan(0x<payload>) / +snan(0x<payload>) (and their negatives)
0x1.8p3 (C-style hexadecimal float)
The sign is mandatory for inf/NaN, so bare `inf`/`nan` remain ordinary
identifiers. C-style hex floats are distinguished from the existing
bit-pattern form by a fractional part and/or a binary exponent; the plain
`0x..` form is still parsed as a bit pattern.
Float literal values are now built directly in the target type's
semantics: Token::getFloatingPointValue takes the target fltSemantics
(and sign) and returns std::optional<APFloat> via
APFloat::convertFromString, instead of first converting to double. This
preserves NaN payloads and fixes a precision bug for types wider than
double: e.g. `0.1 : f128` was previously stored as the double
approximation of 0.1 widened to f128 rather than the correctly-rounded
f128 value. convertFromString accepts inf/nan/snan spellings but not
"qnan" (built via APFloat::getQNaN) nor a leading '+', so the sign is
handled explicitly. The printer mirrors LLVM's writeAPFloatInternal.
A special value that the target type cannot represent is now a parse
error rather than an APFloat abort: the parser rejects infinity, NaN, or
a negative value when the type's semantics lack the matching property
(e.g. `+inf` for a type without infinity, or `-...` for an unsigned
type).
The printer emits the human-readable form by default. The
--mlir-print-float-special-literals-as-hex flag restores the legacy
output, where infinities and NaNs print as a hexadecimal bit pattern.
The parser accepts both forms regardless of the flag. The flag is wired
into every tool that registers the AsmPrinter command-line options
(mlir-opt, mlir-translate, and flang's bbc).
Also thread the float literal's location into the FloatAttr parse
diagnostics so "not valid for specified type" points at the constant
rather than the following token.
Signed-off-by: Victor Perez <victor.pc.upm at gmail.com>
---
flang/test/Transforms/simplifyintrinsics.fir | 4 +-
mlir/docs/LangRef.md | 16 +++
mlir/include/mlir/IR/OperationSupport.h | 11 ++
mlir/lib/AsmParser/AttributeParser.cpp | 21 ++--
mlir/lib/AsmParser/Lexer.cpp | 64 ++++++++++
mlir/lib/AsmParser/Lexer.h | 1 +
mlir/lib/AsmParser/Parser.cpp | 11 +-
mlir/lib/AsmParser/Token.cpp | 55 +++++++-
mlir/lib/AsmParser/Token.h | 11 +-
mlir/lib/IR/AsmPrinter.cpp | 90 +++++++++++---
.../8-bit-float-saturation-ocp.mlir | 8 +-
.../ArithToAMDGPU/8-bit-float-saturation.mlir | 8 +-
.../ComplexToLLVM/complex-range-option.mlir | 4 +-
.../ComplexToSPIRV/complex-to-spirv.mlir | 2 +-
.../complex-range-option.mlir | 4 +-
.../convert-to-standard.mlir | 44 +++----
.../GPUToNVVM/wmma-ops-to-nvvm.mlir | 8 +-
.../TosaToLinalg/tosa-to-linalg.mlir | 16 +--
.../vector-reduction-to-llvm.mlir | 6 +-
.../SuperVectorize/vectorize_reduction.mlir | 12 +-
mlir/test/Dialect/Arith/emulate-wide-int.mlir | 2 +-
mlir/test/Dialect/Builtin/Bytecode/attrs.mlir | 10 +-
.../Builtin/Bytecode/builtin_fixed.mlir | 4 +-
.../Builtin/Bytecode/builtin_fixed_0.mlirbc | Bin 5470 -> 5470 bytes
mlir/test/Dialect/Complex/canonicalize.mlir | 6 +-
.../Linalg/transform-op-decompose.mlir | 2 +-
.../Linalg/transform-op-split-reduction.mlir | 8 +-
.../Linalg/transform-tile-reduction.mlir | 2 +-
mlir/test/Dialect/Math/canonicalize.mlir | 4 +-
mlir/test/Dialect/Math/expand-math.mlir | 8 +-
.../Math/polynomial-approximation.mlir | 18 +--
mlir/test/Dialect/SPIRV/IR/structure-ops.mlir | 2 +-
.../Tosa/constant-reciprocal-fold.mlir | 14 +--
mlir/test/Dialect/Tosa/invalid.mlir | 4 +-
mlir/test/Dialect/XeGPU/propagate-layout.mlir | 2 +-
mlir/test/IR/array-of-attr.mlir | 2 +-
mlir/test/IR/custom-float-attr-roundtrip.mlir | 6 +-
mlir/test/IR/float-literals-hex.mlir | 50 ++++++++
mlir/test/IR/float-literals.mlir | 117 ++++++++++++++++++
mlir/test/IR/invalid-builtin-attributes.mlir | 95 ++++++++++++++
mlir/test/IR/parser.mlir | 66 +++++-----
41 files changed, 637 insertions(+), 181 deletions(-)
create mode 100644 mlir/test/IR/float-literals-hex.mlir
create mode 100644 mlir/test/IR/float-literals.mlir
diff --git a/flang/test/Transforms/simplifyintrinsics.fir b/flang/test/Transforms/simplifyintrinsics.fir
index 1cfda08e39694..585083df690c5 100644
--- a/flang/test/Transforms/simplifyintrinsics.fir
+++ b/flang/test/Transforms/simplifyintrinsics.fir
@@ -2005,7 +2005,7 @@ func.func @_QPtestminloc_works1d_scalarmask_f64(%arg0: !fir.ref<!fir.array<10xf6
// CHECK: %[[FLAG_SET:.*]] = arith.constant 1 : i32
// CHECK: %[[FLAG_EMPTY:.*]] = arith.constant 0 : i32
// CHECK: fir.store %[[FLAG_EMPTY]] to %[[FLAG_ALLOC]] : !fir.ref<i32>
-// CHECK: %[[MAX:.*]] = arith.constant 0x7FF0000000000000 : f64
+// CHECK: %[[MAX:.*]] = arith.constant +inf : f64
// CHECK: %[[C_INDEX1:.*]] = arith.constant 1 : index
// CHECK: %[[DIM_INDEX:.*]] = arith.constant 0 : index
// CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[BOX_INARR]], %[[DIM_INDEX]] : (!fir.box<!fir.array<?xf64>>, index) -> (index, index, index)
@@ -2581,7 +2581,7 @@ func.func @_QPtestmaxloc_works1d_scalarmask_f64(%arg0: !fir.ref<!fir.array<10xf6
// CHECK: %[[FLAG_SET:.*]] = arith.constant 1 : i32
// CHECK: %[[FLAG_EMPTY:.*]] = arith.constant 0 : i32
// CHECK: fir.store %[[FLAG_EMPTY]] to %[[FLAG_ALLOC]] : !fir.ref<i32>
-// CHECK: %[[MAX:.*]] = arith.constant 0xFFF0000000000000 : f64
+// CHECK: %[[MAX:.*]] = arith.constant -inf : f64
// CHECK: %[[C_INDEX1:.*]] = arith.constant 1 : index
// CHECK: %[[DIM_INDEX:.*]] = arith.constant 0 : index
// CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[BOX_INARR]], %[[DIM_INDEX]] : (!fir.box<!fir.array<?xf64>>, index) -> (index, index, index)
diff --git a/mlir/docs/LangRef.md b/mlir/docs/LangRef.md
index fea34c093418d..2ba81375a6ac4 100644
--- a/mlir/docs/LangRef.md
+++ b/mlir/docs/LangRef.md
@@ -174,9 +174,25 @@ integer-literal ::= decimal-literal | hexadecimal-literal
decimal-literal ::= digit+
hexadecimal-literal ::= `0x` hex_digit+
float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
+ | `0x` hex_digit+ (`.` hex_digit*)? [pP] [-+]? digit+
+ | float-special-literal
+float-special-literal ::= [-+] (`inf` | `qnan` | `s`? `nan` `(` `0x` hex_digit+ `)`)
string-literal ::= `"` [^"\n\f\v\r]* `"` TODO: define escaping rules
```
+Special floating point values are spelled with a mandatory sign: `+inf`/`-inf`
+for infinities, `+qnan`/`-qnan` for the preferred quiet NaN, and
+`+nan(0x..)`/`+snan(0x..)` for quiet/signaling NaNs with an explicit hexadecimal
+payload. Finite values may also be written as C-style hexadecimal floats
+(`0x1.8p3`). The `0x` bit-pattern form without a fractional part or exponent
+(e.g. `0x7F800000`) is instead interpreted as the raw bit pattern of the target
+type.
+
+The `--mlir-print-float-special-literals-as-hex` flag makes the printer emit infinities
+and NaNs as a `0x` bit pattern instead of the human-readable form. This restores
+the legacy output for backwards compatibility. The parser accepts both forms
+regardless of the flag.
+
Not listed here, but MLIR does support comments. They use standard BCPL syntax,
starting with a `//` and going until the end of the line.
diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 942b55e8f7a76..64f9ecfa2f1d7 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -1239,6 +1239,10 @@ class OpPrintingFlags {
/// Print SSA IDs using their NameLoc, if provided, as prefix.
OpPrintingFlags &printNameLocAsPrefix(bool enable = true);
+ /// Print special float literals (inf, NaN) as a hexadecimal bit pattern
+ /// instead of the human-readable form. Restores the legacy output.
+ OpPrintingFlags &printFloatSpecialLiteralsAsHex(bool enable = true);
+
/// Return if the given ElementsAttr should be elided.
bool shouldElideElementsAttr(ElementsAttr attr) const;
@@ -1282,6 +1286,10 @@ class OpPrintingFlags {
/// IDs
bool shouldUseNameLocAsPrefix() const;
+ /// Return if special float literals (inf, NaN) should print as a hexadecimal
+ /// bit pattern.
+ bool shouldPrintFloatSpecialLiteralsAsHex() const;
+
private:
/// Elide large elements attributes if the number of elements is larger than
/// the upper limit.
@@ -1318,6 +1326,9 @@ class OpPrintingFlags {
/// Print SSA IDs using NameLocs as prefixes
bool useNameLocAsPrefix : 1;
+
+ /// Print special float literals (inf, NaN) as a hexadecimal bit pattern.
+ bool printFloatSpecialLiteralsAsHexFlag : 1;
};
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/AsmParser/AttributeParser.cpp b/mlir/lib/AsmParser/AttributeParser.cpp
index ca8e4ae2cecbc..5f7ae4aa8bdc6 100644
--- a/mlir/lib/AsmParser/AttributeParser.cpp
+++ b/mlir/lib/AsmParser/AttributeParser.cpp
@@ -339,9 +339,8 @@ ParseResult Parser::parseAttributeDict(NamedAttrList &attributes) {
/// Parse a float attribute.
Attribute Parser::parseFloatAttr(Type type, bool isNegative) {
- auto val = getToken().getFloatingPointValue();
- if (!val)
- return (emitError("floating point value too large for attribute"), nullptr);
+ Token tok = getToken();
+ SMLoc loc = tok.getLoc();
consumeToken(Token::floatliteral);
if (!type) {
// Default to F64 when no type is specified.
@@ -350,10 +349,18 @@ Attribute Parser::parseFloatAttr(Type type, bool isNegative) {
else if (!(type = parseType()))
return nullptr;
}
- if (!isa<FloatType>(type))
- return (emitError("floating point value not valid for specified type"),
- nullptr);
- return FloatAttr::get(type, isNegative ? -*val : *val);
+ auto floatType = dyn_cast<FloatType>(type);
+ if (!floatType) {
+ emitError(loc, "floating point value not valid for specified type");
+ return nullptr;
+ }
+
+ std::optional<APFloat> result =
+ tok.getFloatingPointValue(isNegative, floatType.getFloatSemantics(),
+ [&] { return emitError(loc); });
+ if (!result)
+ return nullptr;
+ return FloatAttr::get(floatType, *result);
}
/// Construct an APint from a parsed value, a known attribute type and
diff --git a/mlir/lib/AsmParser/Lexer.cpp b/mlir/lib/AsmParser/Lexer.cpp
index 161dcb4ca27c0..3191b9e2b1d92 100644
--- a/mlir/lib/AsmParser/Lexer.cpp
+++ b/mlir/lib/AsmParser/Lexer.cpp
@@ -147,6 +147,9 @@ Token Lexer::lexToken() {
return formToken(Token::equal, tokStart);
case '+':
+ if (std::optional<Token> tok = lexSpecialFloatLiteral(
+ StringRef(tokStart, curBuffer.end() - tokStart)))
+ return *tok;
return formToken(Token::plus, tokStart);
case '*':
return formToken(Token::star, tokStart);
@@ -155,6 +158,9 @@ Token Lexer::lexToken() {
++curPtr;
return formToken(Token::arrow, tokStart);
}
+ if (std::optional<Token> tok = lexSpecialFloatLiteral(
+ StringRef(tokStart, curBuffer.end() - tokStart)))
+ return *tok;
return formToken(Token::minus, tokStart);
case '?':
@@ -308,10 +314,46 @@ Token Lexer::lexEllipsis(const char *tokStart) {
return formToken(Token::ellipsis, tokStart);
}
+/// Try to lex a signed special float literal (inf/NaN) from `fromSign`, which
+/// starts at the already-consumed sign. On success returns a `floatliteral`
+/// (or `error`) token and advances `curPtr`, else std::nullopt (curPtr intact).
+///
+/// float-special ::= [-+] (`inf` | `qnan` | `s`? `nan(0x` hex_digit+ `)`)
+///
+std::optional<Token> Lexer::lexSpecialFloatLiteral(StringRef fromSign) {
+ const char *tokStart = fromSign.data();
+ StringRef afterSign = fromSign.drop_front();
+ StringRef keyword = afterSign.take_while(llvm::isAlpha);
+ StringRef rest = afterSign.drop_front(keyword.size());
+
+ // Reject `inf`/`qnan` that is only a prefix of a longer identifier.
+ if (keyword == "inf" || keyword == "qnan") {
+ if (!rest.empty() && (llvm::isAlnum(rest.front()) || rest.front() == '_' ||
+ rest.front() == '$' || rest.front() == '.'))
+ return std::nullopt;
+ curPtr = rest.data();
+ return formToken(Token::floatliteral, tokStart);
+ }
+
+ // `nan(0x..)` / `snan(0x..)`: capture through ')'; APFloat validates later.
+ if ((keyword == "nan" || keyword == "snan") && rest.consume_front("(")) {
+ StringRef payload = rest.take_until([](char c) { return c == ')'; });
+ if (payload.end() == rest.end()) {
+ curPtr = afterSign.end();
+ return emitError(tokStart, "expected ')' in NaN literal");
+ }
+ curPtr = payload.end() + 1;
+ return formToken(Token::floatliteral, tokStart);
+ }
+
+ return std::nullopt;
+}
+
/// Lex a number literal.
///
/// integer-literal ::= digit+ | `0x` hex_digit+
/// float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
+/// | `0x` hex_digit+ (`.` hex_digit*)? [pP] [-+]? digit+
///
Token Lexer::lexNumber(const char *tokStart) {
assert(isdigit(curPtr[-1]));
@@ -327,6 +369,28 @@ Token Lexer::lexNumber(const char *tokStart) {
while (isxdigit(*curPtr))
++curPtr;
+ // C-style hex float (`0x1.fp13`): a '.'/'p' distinguishes it from the
+ // bit-pattern form; the binary exponent is mandatory.
+ if (*curPtr == '.' || *curPtr == 'p' || *curPtr == 'P') {
+ if (*curPtr == '.') {
+ ++curPtr;
+ while (isxdigit(*curPtr))
+ ++curPtr;
+ }
+ if (*curPtr != 'p' && *curPtr != 'P')
+ return emitError(tokStart, "expected binary exponent in hexadecimal "
+ "floating point literal");
+ ++curPtr;
+ if (*curPtr == '-' || *curPtr == '+')
+ ++curPtr;
+ if (!isdigit(static_cast<unsigned char>(*curPtr)))
+ return emitError(tokStart, "expected binary exponent in hexadecimal "
+ "floating point literal");
+ while (isdigit(*curPtr))
+ ++curPtr;
+ return formToken(Token::floatliteral, tokStart);
+ }
+
return formToken(Token::integer, tokStart);
}
diff --git a/mlir/lib/AsmParser/Lexer.h b/mlir/lib/AsmParser/Lexer.h
index 670444eb1f5b4..802ebcb7a8393 100644
--- a/mlir/lib/AsmParser/Lexer.h
+++ b/mlir/lib/AsmParser/Lexer.h
@@ -60,6 +60,7 @@ class Lexer {
Token lexBareIdentifierOrKeyword(const char *tokStart);
Token lexEllipsis(const char *tokStart);
Token lexNumber(const char *tokStart);
+ std::optional<Token> lexSpecialFloatLiteral(StringRef fromSign);
Token lexPrefixedIdentifier(const char *tokStart);
Token lexString(const char *tokStart);
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 952d7e460c6e2..d9173a5308eee 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -401,14 +401,9 @@ ParseResult Parser::parseFloatFromLiteral(std::optional<APFloat> &result,
const llvm::fltSemantics &semantics) {
// Check for a floating point value.
if (tok.is(Token::floatliteral)) {
- auto val = tok.getFloatingPointValue();
- if (!val)
- return emitError(tok.getLoc()) << "floating point value too large";
-
- result.emplace(isNegative ? -*val : *val);
- bool unused;
- result->convert(semantics, APFloat::rmNearestTiesToEven, &unused);
- return success();
+ result = tok.getFloatingPointValue(isNegative, semantics,
+ [&] { return emitError(tok.getLoc()); });
+ return failure(!result);
}
// Check for a hexadecimal float value.
diff --git a/mlir/lib/AsmParser/Token.cpp b/mlir/lib/AsmParser/Token.cpp
index 5bf25bac6a5c6..835cd892c9a19 100644
--- a/mlir/lib/AsmParser/Token.cpp
+++ b/mlir/lib/AsmParser/Token.cpp
@@ -11,8 +11,10 @@
//===----------------------------------------------------------------------===//
#include "Token.h"
+#include "mlir/IR/Diagnostics.h"
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
@@ -51,12 +53,55 @@ std::optional<uint64_t> Token::getUInt64IntegerValue(StringRef spelling) {
return result;
}
-/// For a floatliteral, return its value as a double. Return std::nullopt if the
-/// value underflows or overflows.
-std::optional<double> Token::getFloatingPointValue() const {
- double result = 0;
- if (spelling.getAsDouble(result))
+/// For a floatliteral token, build its value in `semantics`, combining any sign
+/// folded into the spelling with `isNegative`. On failure, emits a diagnostic
+/// through `emitError` and returns std::nullopt.
+std::optional<APFloat> Token::getFloatingPointValue(
+ bool isNegative, const llvm::fltSemantics &semantics,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ // The sign is either a preceding '-' token (isNegative) or folded into an
+ // inf/NaN spelling; both at once (e.g. `-+inf`) is invalid. Drop a leading
+ // '+' since convertFromString rejects it on NaN forms.
+ StringRef str = spelling;
+ if (isNegative && (str.starts_with("+") || str.starts_with("-"))) {
+ emitError() << "floating point literal has more than one sign";
return std::nullopt;
+ }
+ bool isNeg = isNegative || str.consume_front("-");
+ str.consume_front("+");
+
+ // Reject values the type cannot represent; APFloat would otherwise abort.
+ if (isNeg && !APFloat::semanticsHasSignedRepr(semantics)) {
+ emitError() << "floating point type does not support negative values";
+ return std::nullopt;
+ }
+ if (str == "inf" && !APFloat::semanticsHasInf(semantics)) {
+ emitError() << "floating point type does not support infinity";
+ return std::nullopt;
+ }
+ bool wantsNaN =
+ str == "qnan" || str.starts_with("nan") || str.starts_with("snan");
+ if (wantsNaN && !APFloat::semanticsHasNaN(semantics)) {
+ emitError() << "floating point type does not support NaN";
+ return std::nullopt;
+ }
+
+ // convertFromString does not accept "qnan".
+ if (str == "qnan")
+ return APFloat::getQNaN(semantics, isNeg);
+
+ // Build in the target semantics to preserve NaN payloads; overflow/underflow
+ // are tolerated (inf/zero).
+ APFloat result(semantics);
+ llvm::Expected<APFloat::opStatus> status =
+ result.convertFromString(str, APFloat::rmNearestTiesToEven);
+ if (!status) {
+ llvm::consumeError(status.takeError());
+ emitError() << "invalid floating point literal";
+ return std::nullopt;
+ }
+ if (isNeg)
+ result.changeSign();
return result;
}
diff --git a/mlir/lib/AsmParser/Token.h b/mlir/lib/AsmParser/Token.h
index 9cae80fd51da0..9193465af9419 100644
--- a/mlir/lib/AsmParser/Token.h
+++ b/mlir/lib/AsmParser/Token.h
@@ -10,11 +10,13 @@
#define MLIR_LIB_PARSER_TOKEN_H
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SMLoc.h"
#include <optional>
namespace mlir {
+class InFlightDiagnostic;
/// This represents a token in the MLIR syntax.
class Token {
@@ -84,9 +86,12 @@ class Token {
return getUInt64IntegerValue(getSpelling());
}
- /// For a floatliteral token, return its value as a double. Returns
- /// std::nullopt in the case of underflow or overflow.
- std::optional<double> getFloatingPointValue() const;
+ /// For a floatliteral token, build its value in `semantics`, combining any
+ /// sign folded into the spelling with `isNegative`. On failure, emits a
+ /// diagnostic through `emitError` and returns std::nullopt.
+ std::optional<APFloat>
+ getFloatingPointValue(bool isNegative, const llvm::fltSemantics &semantics,
+ function_ref<InFlightDiagnostic()> emitError) const;
/// For an inttype token, return its bitwidth.
std::optional<unsigned> getIntTypeBitwidth() const;
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index ca5c2d2a88ee5..b1f91a5d6f261 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -201,6 +201,11 @@ struct AsmPrinterOptions {
llvm::cl::opt<bool> useNameLocAsPrefix{
"mlir-use-nameloc-as-prefix", llvm::cl::init(false),
llvm::cl::desc("Print SSA IDs using NameLocs as prefixes")};
+
+ llvm::cl::opt<bool> printFloatSpecialLiteralsAsHexOpt{
+ "mlir-print-float-special-literals-as-hex", llvm::cl::init(false),
+ llvm::cl::desc("Print special float literals (inf, NaN) as a hexadecimal "
+ "bit pattern instead of the human-readable form")};
};
} // namespace
@@ -219,7 +224,7 @@ OpPrintingFlags::OpPrintingFlags()
printGenericOpFormFlag(false), skipRegionsFlag(false),
assumeVerifiedFlag(false), printLocalScope(false),
printValueUsersFlag(false), printUniqueSSAIDsFlag(false),
- useNameLocAsPrefix(false) {
+ useNameLocAsPrefix(false), printFloatSpecialLiteralsAsHexFlag(false) {
// Initialize based upon command line options, if they are available.
if (!clOptions.isConstructed())
return;
@@ -239,6 +244,7 @@ OpPrintingFlags::OpPrintingFlags()
printValueUsersFlag = clOptions->printValueUsers;
printUniqueSSAIDsFlag = clOptions->printUniqueSSAIDs;
useNameLocAsPrefix = clOptions->useNameLocAsPrefix;
+ printFloatSpecialLiteralsAsHexFlag = clOptions->printFloatSpecialLiteralsAsHexOpt;
}
/// Enable the elision of large elements attributes, by printing a '...'
@@ -331,6 +337,11 @@ OpPrintingFlags &OpPrintingFlags::printNameLocAsPrefix(bool enable) {
return *this;
}
+OpPrintingFlags &OpPrintingFlags::printFloatSpecialLiteralsAsHex(bool enable) {
+ printFloatSpecialLiteralsAsHexFlag = enable;
+ return *this;
+}
+
/// Return the size limit for printing large ElementsAttr.
std::optional<int64_t> OpPrintingFlags::getLargeElementsAttrLimit() const {
return elementsAttrElementLimit;
@@ -387,6 +398,11 @@ bool OpPrintingFlags::shouldUseNameLocAsPrefix() const {
return useNameLocAsPrefix;
}
+/// Return if special float literals should print as a hexadecimal bit pattern.
+bool OpPrintingFlags::shouldPrintFloatSpecialLiteralsAsHex() const {
+ return printFloatSpecialLiteralsAsHexFlag;
+}
+
//===----------------------------------------------------------------------===//
// NewLineCounter
//===----------------------------------------------------------------------===//
@@ -418,6 +434,9 @@ class AsmPrinter::Impl {
/// Returns the output stream of the printer.
raw_ostream &getStream() { return os; }
+ /// Returns the printing flags of the printer.
+ const OpPrintingFlags &getPrinterFlags() const { return printerFlags; }
+
/// Print a newline and indent the printer to the start of the current
/// operation/attribute/type.
/// Note: For attributes and types this method should only be used in
@@ -2256,14 +2275,11 @@ void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty,
/// Print a floating point value in a way that the parser will be able to
/// round-trip losslessly.
static void printFloatValue(const APFloat &apValue, raw_ostream &os,
- bool *printedHex = nullptr) {
- // We would like to output the FP constant value in exponential notation,
- // but we cannot do this if doing so will lose precision. Check here to
- // make sure that we only output it in exponential format if we can parse
- // the value back and get the same value.
- bool isInf = apValue.isInfinity();
- bool isNaN = apValue.isNaN();
- if (!isInf && !isNaN) {
+ bool *printedHex = nullptr,
+ bool printFloatSpecialLiteralsAsHex = false) {
+ // Finite values print as decimal; this is the only form whose type may be
+ // elided.
+ if (!apValue.isInfinity() && !apValue.isNaN()) {
SmallString<128> strValue;
apValue.toString(strValue, /*FormatPrecision=*/6, /*FormatMaxPadding=*/0,
/*TruncateZero=*/false);
@@ -2295,14 +2311,42 @@ static void printFloatValue(const APFloat &apValue, raw_ostream &os,
}
}
- // Print special values in hexadecimal format. The sign bit should be included
- // in the literal.
+ // The rest (inf, NaN, hex bit-pattern) are typeless; keep the type.
if (printedHex)
*printedHex = true;
+
+ // The legacy form prints inf/NaN as a hexadecimal bit pattern too.
+ if (!printFloatSpecialLiteralsAsHex && apValue.isInfinity()) {
+ os << (apValue.isNegative() ? "-inf" : "+inf");
+ return;
+ }
+
+ if (!printFloatSpecialLiteralsAsHex && apValue.isNaN()) {
+ os << (apValue.isNegative() ? '-' : '+');
+ APInt payload = apValue.getNaNPayload();
+ // Preferred quiet NaN = only the quiet (sign-mask) bit set. A zero-width
+ // payload (no mantissa bits, e.g. f8E8M0FNU) has none, so print qnan.
+ if (payload.getBitWidth() == 0 || payload.isSignMask()) {
+ os << "qnan";
+ return;
+ }
+ if (apValue.isSignaling())
+ os << 's';
+ os << "nan(";
+ // Drop the quiet/signaling bit; trim leading zeros.
+ payload.clearBit(payload.getBitWidth() - 1);
+ SmallVector<char, 16> str;
+ payload.trunc(std::max(payload.getActiveBits(), 1u))
+ .toString(str, /*Radix=*/16, /*Signed=*/false,
+ /*formatAsCLiteral=*/true);
+ os << str << ')';
+ return;
+ }
+
+ // Hexadecimal bit pattern.
SmallVector<char, 16> str;
- APInt apInt = apValue.bitcastToAPInt();
- apInt.toString(str, /*Radix=*/16, /*Signed=*/false,
- /*formatAsCLiteral=*/true);
+ apValue.bitcastToAPInt().toString(str, /*Radix=*/16, /*Signed=*/false,
+ /*formatAsCLiteral=*/true);
os << str;
}
@@ -2472,7 +2516,8 @@ void AsmPrinter::Impl::printAttributeImpl(Attribute attr,
} else if (auto floatAttr = llvm::dyn_cast<FloatAttr>(attr)) {
bool printedHex = false;
- printFloatValue(floatAttr.getValue(), os, &printedHex);
+ printFloatValue(floatAttr.getValue(), os, &printedHex,
+ printerFlags.shouldPrintFloatSpecialLiteralsAsHex());
// FloatAttr elides the type if F64.
if (typeElision == AttrTypeElision::May && floatAttr.getType().isF64() &&
@@ -2702,9 +2747,11 @@ void AsmPrinter::Impl::printDenseTypedElementsAttr(DenseTypedElementsAttr attr,
printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) {
auto complexValue = *(valueIt + index);
os << "(";
- printFloatValue(complexValue.real(), os);
+ printFloatValue(complexValue.real(), os, /*printedHex=*/nullptr,
+ printerFlags.shouldPrintFloatSpecialLiteralsAsHex());
os << ",";
- printFloatValue(complexValue.imag(), os);
+ printFloatValue(complexValue.imag(), os, /*printedHex=*/nullptr,
+ printerFlags.shouldPrintFloatSpecialLiteralsAsHex());
os << ")";
});
}
@@ -2717,7 +2764,8 @@ void AsmPrinter::Impl::printDenseTypedElementsAttr(DenseTypedElementsAttr attr,
assert(llvm::isa<FloatType>(elementType) && "unexpected element type");
auto valueIt = attr.value_begin<APFloat>();
printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) {
- printFloatValue(*(valueIt + index), os);
+ printFloatValue(*(valueIt + index), os, /*printedHex=*/nullptr,
+ printerFlags.shouldPrintFloatSpecialLiteralsAsHex());
});
}
}
@@ -2768,7 +2816,8 @@ void AsmPrinter::Impl::printDenseArrayAttr(DenseArrayAttr attr) {
printDenseIntElement(value, getStream(), type);
} else {
APFloat fltVal(llvm::cast<FloatType>(type).getFloatSemantics(), value);
- printFloatValue(fltVal, getStream());
+ printFloatValue(fltVal, getStream(), /*printedHex=*/nullptr,
+ printerFlags.shouldPrintFloatSpecialLiteralsAsHex());
}
};
llvm::interleaveComma(llvm::seq<unsigned>(0, attr.size()), getStream(),
@@ -3063,7 +3112,8 @@ void AsmPrinter::decreaseIndent() {
/// Print the given floating point value in a stablized form.
void AsmPrinter::printFloat(const APFloat &value) {
assert(impl && "expected AsmPrinter::printFloat to be overriden");
- printFloatValue(value, impl->getStream());
+ printFloatValue(value, impl->getStream(), /*printedHex=*/nullptr,
+ impl->getPrinterFlags().shouldPrintFloatSpecialLiteralsAsHex());
}
void AsmPrinter::printType(Type type) {
diff --git a/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation-ocp.mlir b/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation-ocp.mlir
index 2df5f2fa1965f..f66a7194d2afb 100644
--- a/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation-ocp.mlir
+++ b/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation-ocp.mlir
@@ -10,8 +10,8 @@
// CHECK-SAME: ([[V:%.+]]: f16)
// CHECK-DAG: [[CMin:%.+]] = arith.constant -5.734400e+04 : f16
// CHECK-DAG: [[CMax:%.+]] = arith.constant 5.734400e+04 : f16
-// CHECK-DAG: [[CInf:%.+]] = arith.constant 0x7C00 : f16
-// CHECK-DAG: [[CNegInf:%.+]] = arith.constant 0xFC00 : f16
+// CHECK-DAG: [[CInf:%.+]] = arith.constant +inf : f16
+// CHECK-DAG: [[CNegInf:%.+]] = arith.constant -inf : f16
// CHECK: [[ISINF:%.+]] = arith.cmpf oeq, [[V]], [[CInf]]
// CHECK: [[ISNEGINF:%.+]] = arith.cmpf oeq, [[V]], [[CNegInf]]
// CHECK: [[ISNAN:%.+]] = arith.cmpf uno, [[V]], [[V]]
@@ -37,8 +37,8 @@ func.func @scalar_trunc(%v: f16) -> f8E5M2 {
// CHECK-SAME: ([[V:%.+]]: vector<2xf32>) -> vector<2xf8E4M3FN> {
// CHECK-DAG: [[CMin:%.+]] = arith.constant dense<-4.480000e+02> : vector<2xf32>
// CHECK-DAG: [[CMax:%.+]] = arith.constant dense<4.480000e+02> : vector<2xf32>
-// CHECK-DAG: [[CInf:%.+]] = arith.constant dense<0x7F800000> : vector<2xf32>
-// CHECK-DAG: [[CNegInf:%.+]] = arith.constant dense<0xFF800000> : vector<2xf32>
+// CHECK-DAG: [[CInf:%.+]] = arith.constant dense<+inf> : vector<2xf32>
+// CHECK-DAG: [[CNegInf:%.+]] = arith.constant dense<-inf> : vector<2xf32>
// CHECK: [[ISINF:%.+]] = arith.cmpf oeq, [[V]], [[CInf]]
// CHECK: [[ISNEGINF:%.+]] = arith.cmpf oeq, [[V]], [[CNegInf]]
// CHECK: [[ISNAN:%.+]] = arith.cmpf uno, [[V]], [[V]]
diff --git a/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation.mlir b/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation.mlir
index 07a428566d488..f36b35b913c9b 100644
--- a/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation.mlir
+++ b/mlir/test/Conversion/ArithToAMDGPU/8-bit-float-saturation.mlir
@@ -6,8 +6,8 @@
// CHECK-SAME: ([[V:%.+]]: f16)
// CHECK-DAG: [[CMin:%.+]] = arith.constant -5.734400e+04 : f16
// CHECK-DAG: [[CMax:%.+]] = arith.constant 5.734400e+04 : f16
-// CHECK-DAG: [[CInf:%.+]] = arith.constant 0x7C00 : f16
-// CHECK-DAG: [[CNegInf:%.+]] = arith.constant 0xFC00 : f16
+// CHECK-DAG: [[CInf:%.+]] = arith.constant +inf : f16
+// CHECK-DAG: [[CNegInf:%.+]] = arith.constant -inf : f16
// CHECK: [[ISINF:%.+]] = arith.cmpf oeq, [[V]], [[CInf]]
// CHECK: [[ISNEGINF:%.+]] = arith.cmpf oeq, [[V]], [[CNegInf]]
// CHECK: [[ISNAN:%.+]] = arith.cmpf uno, [[V]], [[V]]
@@ -33,8 +33,8 @@ func.func @scalar_trunc(%v: f16) -> f8E5M2FNUZ {
// CHECK-SAME: ([[V:%.+]]: vector<2xf32>) -> vector<2xf8E4M3FNUZ> {
// CHECK-DAG: [[CMin:%.+]] = arith.constant dense<-2.400000e+02> : vector<2xf32>
// CHECK-DAG: [[CMax:%.+]] = arith.constant dense<2.400000e+02> : vector<2xf32>
-// CHECK-DAG: [[CInf:%.+]] = arith.constant dense<0x7F800000> : vector<2xf32>
-// CHECK-DAG: [[CNegInf:%.+]] = arith.constant dense<0xFF800000> : vector<2xf32>
+// CHECK-DAG: [[CInf:%.+]] = arith.constant dense<+inf> : vector<2xf32>
+// CHECK-DAG: [[CNegInf:%.+]] = arith.constant dense<-inf> : vector<2xf32>
// CHECK: [[ISINF:%.+]] = arith.cmpf oeq, [[V]], [[CInf]]
// CHECK: [[ISNEGINF:%.+]] = arith.cmpf oeq, [[V]], [[CNegInf]]
// CHECK: [[ISNAN:%.+]] = arith.cmpf uno, [[V]], [[V]]
diff --git a/mlir/test/Conversion/ComplexToLLVM/complex-range-option.mlir b/mlir/test/Conversion/ComplexToLLVM/complex-range-option.mlir
index 78e8db795788a..cef9ec850387e 100644
--- a/mlir/test/Conversion/ComplexToLLVM/complex-range-option.mlir
+++ b/mlir/test/Conversion/ComplexToLLVM/complex-range-option.mlir
@@ -50,7 +50,7 @@ func.func @complex_div(%lhs: complex<f32>, %rhs: complex<f32>) -> complex<f32> {
// DIV-SMITH: %[[LHS_CONTAINS_NOT_NAN_VALUE:.*]] = llvm.or %[[LHS_REAL_IS_NOT_NAN]], %[[LHS_IMAG_IS_NOT_NAN]] : i1
// DIV-SMITH: %[[RHS_IS_ZERO:.*]] = llvm.and %[[RHS_REAL_ABS_IS_ZERO]], %[[RHS_IMAG_ABS_IS_ZERO]] : i1
// DIV-SMITH: %[[RESULT_IS_INFINITY:.*]] = llvm.and %[[LHS_CONTAINS_NOT_NAN_VALUE]], %[[RHS_IS_ZERO]] : i1
-// DIV-SMITH: %[[INF:.*]] = llvm.mlir.constant(0x7F800000 : f32) : f32
+// DIV-SMITH: %[[INF:.*]] = llvm.mlir.constant(+inf : f32) : f32
// DIV-SMITH: %[[INF_WITH_SIGN_OF_RHS_REAL:.*]] = llvm.intr.copysign(%[[INF]], %[[RHS_REAL]]) : (f32, f32) -> f32
// DIV-SMITH: %[[INFINITY_RESULT_REAL:.*]] = llvm.fmul %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_REAL]] : f32
// DIV-SMITH: %[[INFINITY_RESULT_IMAG:.*]] = llvm.fmul %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_IMAG]] : f32
@@ -200,7 +200,7 @@ func.func @complex_div_with_fmf(%lhs: complex<f32>, %rhs: complex<f32>) -> compl
// DIV-SMITH: %[[LHS_CONTAINS_NOT_NAN_VALUE:.*]] = llvm.or %[[LHS_REAL_IS_NOT_NAN]], %[[LHS_IMAG_IS_NOT_NAN]] : i1
// DIV-SMITH: %[[RHS_IS_ZERO:.*]] = llvm.and %[[RHS_REAL_ABS_IS_ZERO]], %[[RHS_IMAG_ABS_IS_ZERO]] : i1
// DIV-SMITH: %[[RESULT_IS_INFINITY:.*]] = llvm.and %[[LHS_CONTAINS_NOT_NAN_VALUE]], %[[RHS_IS_ZERO]] : i1
-// DIV-SMITH: %[[INF:.*]] = llvm.mlir.constant(0x7F800000 : f32) : f32
+// DIV-SMITH: %[[INF:.*]] = llvm.mlir.constant(+inf : f32) : f32
// DIV-SMITH: %[[INF_WITH_SIGN_OF_RHS_REAL:.*]] = llvm.intr.copysign(%[[INF]], %[[RHS_REAL]]) : (f32, f32) -> f32
// DIV-SMITH: %[[INFINITY_RESULT_REAL:.*]] = llvm.fmul %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_REAL]] {fastmathFlags = #llvm.fastmath<nsz, arcp>} : f32
// DIV-SMITH: %[[INFINITY_RESULT_IMAG:.*]] = llvm.fmul %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_IMAG]] {fastmathFlags = #llvm.fastmath<nsz, arcp>} : f32
diff --git a/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir b/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir
index deb4eb6d9d08c..9e1c540d8cd5b 100644
--- a/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir
+++ b/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir
@@ -46,7 +46,7 @@ func.func @complex_const() -> complex<f32> {
}
// CHECK-LABEL: func.func @complex_const()
-// CHECK: spirv.Constant dense<[0x7FC00000, 0.000000e+00]> : vector<2xf32>
+// CHECK: spirv.Constant dense<[+qnan, 0.000000e+00]> : vector<2xf32>
// -----
diff --git a/mlir/test/Conversion/ComplexToStandard/complex-range-option.mlir b/mlir/test/Conversion/ComplexToStandard/complex-range-option.mlir
index 97f37d8ebe77e..ce588fa5d20dc 100644
--- a/mlir/test/Conversion/ComplexToStandard/complex-range-option.mlir
+++ b/mlir/test/Conversion/ComplexToStandard/complex-range-option.mlir
@@ -46,7 +46,7 @@ func.func @complex_div(%lhs: complex<f32>, %rhs: complex<f32>) -> complex<f32> {
// DIV-SMITH: %[[LHS_CONTAINS_NOT_NAN_VALUE:.*]] = arith.ori %[[LHS_REAL_IS_NOT_NAN]], %[[LHS_IMAG_IS_NOT_NAN]] : i1
// DIV-SMITH: %[[RHS_IS_ZERO:.*]] = arith.andi %[[RHS_REAL_ABS_IS_ZERO]], %[[RHS_IMAG_ABS_IS_ZERO]] : i1
// DIV-SMITH: %[[RESULT_IS_INFINITY:.*]] = arith.andi %[[LHS_CONTAINS_NOT_NAN_VALUE]], %[[RHS_IS_ZERO]] : i1
-// DIV-SMITH: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// DIV-SMITH: %[[INF:.*]] = arith.constant +inf : f32
// DIV-SMITH: %[[INF_WITH_SIGN_OF_RHS_REAL:.*]] = math.copysign %[[INF]], %[[RHS_REAL]] : f32
// DIV-SMITH: %[[INFINITY_RESULT_REAL:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_REAL]] : f32
// DIV-SMITH: %[[INFINITY_RESULT_IMAG:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_IMAG]] : f32
@@ -183,7 +183,7 @@ func.func @complex_div_with_fmf(%lhs: complex<f32>, %rhs: complex<f32>) -> compl
// DIV-SMITH: %[[LHS_CONTAINS_NOT_NAN_VALUE:.*]] = arith.ori %[[LHS_REAL_IS_NOT_NAN]], %[[LHS_IMAG_IS_NOT_NAN]] : i1
// DIV-SMITH: %[[RHS_IS_ZERO:.*]] = arith.andi %[[RHS_REAL_ABS_IS_ZERO]], %[[RHS_IMAG_ABS_IS_ZERO]] : i1
// DIV-SMITH: %[[RESULT_IS_INFINITY:.*]] = arith.andi %[[LHS_CONTAINS_NOT_NAN_VALUE]], %[[RHS_IS_ZERO]] : i1
-// DIV-SMITH: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// DIV-SMITH: %[[INF:.*]] = arith.constant +inf : f32
// DIV-SMITH: %[[INF_WITH_SIGN_OF_RHS_REAL:.*]] = math.copysign %[[INF]], %[[RHS_REAL]] : f32
// DIV-SMITH: %[[INFINITY_RESULT_REAL:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_REAL]] fastmath<nsz,arcp> : f32
// DIV-SMITH: %[[INFINITY_RESULT_IMAG:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_IMAG]] fastmath<nsz,arcp> : f32
diff --git a/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir b/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir
index 1242b1b66ff7b..bef9163077b15 100644
--- a/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir
+++ b/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir
@@ -117,7 +117,7 @@ func.func @complex_div(%lhs: complex<f32>, %rhs: complex<f32>) -> complex<f32> {
// CHECK: %[[LHS_CONTAINS_NOT_NAN_VALUE:.*]] = arith.ori %[[LHS_REAL_IS_NOT_NAN]], %[[LHS_IMAG_IS_NOT_NAN]] : i1
// CHECK: %[[RHS_IS_ZERO:.*]] = arith.andi %[[RHS_REAL_ABS_IS_ZERO]], %[[RHS_IMAG_ABS_IS_ZERO]] : i1
// CHECK: %[[RESULT_IS_INFINITY:.*]] = arith.andi %[[LHS_CONTAINS_NOT_NAN_VALUE]], %[[RHS_IS_ZERO]] : i1
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
// CHECK: %[[INF_WITH_SIGN_OF_RHS_REAL:.*]] = math.copysign %[[INF]], %[[RHS_REAL]] : f32
// CHECK: %[[INFINITY_RESULT_REAL:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_REAL]] : f32
// CHECK: %[[INFINITY_RESULT_IMAG:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_IMAG]] : f32
@@ -213,7 +213,7 @@ func.func @complex_exp(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[IMAG:.*]] = complex.im %[[ARG]] : complex<f32>
// CHECK-DAG: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f32
// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01 : f32
-// CHECK-DAG: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK-DAG: %[[INF:.*]] = arith.constant +inf : f32
// CHECK-DAG: %[[EXP_REAL:.*]] = math.exp %[[REAL]] : f32
// CHECK-DAG: %[[REAL_HALF:.*]] = arith.mulf %[[REAL]], %[[HALF]] : f32
// CHECK-DAG: %[[EXP_HALF:.*]] = math.exp %[[REAL_HALF]] : f32
@@ -486,7 +486,7 @@ func.func @complex_tan(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[V0:.*]] = complex.im %[[ARG]] : complex<f32>
// CHECK: %[[NEG_ONE:.*]] = arith.constant -1.000000e+00 : f32
// CHECK: %[[REAL:.*]] = arith.mulf %[[V0]], %[[NEG_ONE]] : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
// CHECK: %[[FOUR:.*]] = arith.constant 4.000000e+00 : f32
// CHECK: %[[TWO_REAL:.*]] = arith.addf %[[REAL]], %[[REAL]] : f32
// CHECK: %[[NEG_TWO_REAL:.*]] = arith.mulf %[[NEG_ONE]], %[[TWO_REAL]] : f32
@@ -508,7 +508,7 @@ func.func @complex_tan(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[RESULT_IMAG:.*]] = arith.divf %[[IMAG_NUM]], %[[DENOM]] : f32
// CHECK: %[[ABS_REAL:.*]] = math.absf %[[REAL]] : f32
// CHECK: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABS_REAL_INF:.*]] = arith.cmpf oeq, %[[ABS_REAL]], %[[INF]] : f32
// CHECK: %[[IMAG_ZERO:.*]] = arith.cmpf oeq, %[[IMAG]], %[[ZERO]] : f32
// CHECK: %true = arith.constant true
@@ -534,7 +534,7 @@ func.func @complex_tanh(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[REAL:.*]] = complex.re %[[ARG]] : complex<f32>
// CHECK: %[[IMAG:.*]] = complex.im %[[ARG]] : complex<f32>
// CHECK: %[[NEG_ONE:.*]] = arith.constant -1.000000e+00 : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
// CHECK: %[[FOUR:.*]] = arith.constant 4.000000e+00 : f32
// CHECK: %[[TWO_REAL:.*]] = arith.addf %[[REAL]], %[[REAL]] : f32
// CHECK: %[[NEG_TWO_REAL:.*]] = arith.mulf %[[NEG_ONE]], %[[TWO_REAL]] : f32
@@ -556,7 +556,7 @@ func.func @complex_tanh(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[RESULT_IMAG:.*]] = arith.divf %[[IMAG_NUM]], %[[DENOM]] : f32
// CHECK: %[[ABS_REAL:.*]] = math.absf %[[REAL]] : f32
// CHECK: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABS_REAL_INF:.*]] = arith.cmpf oeq, %[[ABS_REAL]], %[[INF]] : f32
// CHECK: %[[IMAG_ZERO:.*]] = arith.cmpf oeq, %[[IMAG]], %[[ZERO]] : f32
// CHECK: %true = arith.constant true
@@ -605,9 +605,9 @@ func.func @complex_sqrt(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[RESULT_RE:.*]] = arith.mulf %[[SQRT_ABS]], %[[COS]] : f32
// CHECK: %[[RESULT_IM:.*]] = arith.mulf %[[SQRT_ABS]], %[[SIN]] : f32
// CHECK: %[[RESULT_IM2:.*]] = arith.select %[[SIN_ZERO]], %[[ZERO]], %[[RESULT_IM]] : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
-// CHECK: %[[NINF:.*]] = arith.constant 0xFF800000 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
+// CHECK: %[[NINF:.*]] = arith.constant -inf : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABSIM:.*]] = math.absf %[[IM]] : f32
// CHECK: %[[ABSIMINF:.*]] = arith.cmpf oeq, %[[ABSIM]], %[[INF]] : f32
// CHECK: %[[ABSIMNOTINF:.*]] = arith.cmpf one, %[[ABSIM]], %[[INF]] : f32
@@ -847,7 +847,7 @@ func.func @complex_exp_with_fmf(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[IMAG:.*]] = complex.im %[[ARG]] : complex<f32>
// CHECK-DAG: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f32
// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01 : f32
-// CHECK-DAG: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK-DAG: %[[INF:.*]] = arith.constant +inf : f32
// CHECK-DAG: %[[EXP_REAL:.*]] = math.exp %[[REAL]] fastmath<nnan,contract> : f32
// CHECK-DAG: %[[REAL_HALF:.*]] = arith.mulf %[[REAL]], %[[HALF]] fastmath<nnan,contract> : f32
// CHECK-DAG: %[[EXP_HALF:.*]] = math.exp %[[REAL_HALF]] fastmath<nnan,contract> : f32
@@ -1011,9 +1011,9 @@ func.func @complex_atan2_with_fmf(%lhs: complex<f32>,
// CHECK: %[[RESULT_RE:.*]] = arith.mulf %[[SQRT_ABS]], %[[COS]] fastmath<nnan,contract> : f32
// CHECK: %[[RESULT_IM:.*]] = arith.mulf %[[SQRT_ABS]], %[[SIN]] fastmath<nnan,contract> : f32
// CHECK: %[[RESULT_IM2:.*]] = arith.select %[[SIN_ZERO]], %[[ZERO]], %[[RESULT_IM]] : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
-// CHECK: %[[NINF:.*]] = arith.constant 0xFF800000 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
+// CHECK: %[[NINF:.*]] = arith.constant -inf : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABSIM:.*]] = math.absf %[[IM]] fastmath<nnan,contract> : f32
// CHECK: %[[ABSIMINF:.*]] = arith.cmpf oeq, %[[ABSIM]], %[[INF]] fastmath<nnan,contract> : f32
// CHECK: %[[ABSIMNOTINF:.*]] = arith.cmpf one, %[[ABSIM]], %[[INF]] fastmath<nnan,contract> : f32
@@ -1084,7 +1084,7 @@ func.func @complex_atan2_with_fmf(%lhs: complex<f32>,
// CHECK: %[[VAR355:.*]] = arith.ori %[[VAR353]], %[[VAR354]] : i1
// CHECK: %[[VAR356:.*]] = arith.andi %[[VAR350]], %[[VAR352]] : i1
// CHECK: %[[VAR357:.*]] = arith.andi %[[VAR355]], %[[VAR356]] : i1
-// CHECK: %[[CST_17:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[CST_17:.*]] = arith.constant +inf : f32
// CHECK: %[[VAR358:.*]] = math.copysign %[[CST_17]], %[[VAR329]] : f32
// CHECK: %[[VAR359:.*]] = arith.mulf %[[VAR358]], %[[VAR327]] fastmath<nnan,contract> : f32
// CHECK: %[[VAR360:.*]] = arith.mulf %[[VAR358]], %[[VAR328]] fastmath<nnan,contract> : f32
@@ -1221,7 +1221,7 @@ func.func @complex_div_with_fmf(%lhs: complex<f32>, %rhs: complex<f32>) -> compl
// CHECK: %[[LHS_CONTAINS_NOT_NAN_VALUE:.*]] = arith.ori %[[LHS_REAL_IS_NOT_NAN]], %[[LHS_IMAG_IS_NOT_NAN]] : i1
// CHECK: %[[RHS_IS_ZERO:.*]] = arith.andi %[[RHS_REAL_ABS_IS_ZERO]], %[[RHS_IMAG_ABS_IS_ZERO]] : i1
// CHECK: %[[RESULT_IS_INFINITY:.*]] = arith.andi %[[LHS_CONTAINS_NOT_NAN_VALUE]], %[[RHS_IS_ZERO]] : i1
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
// CHECK: %[[INF_WITH_SIGN_OF_RHS_REAL:.*]] = math.copysign %[[INF]], %[[RHS_REAL]] : f32
// CHECK: %[[INFINITY_RESULT_REAL:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_REAL]] fastmath<nnan,contract> : f32
// CHECK: %[[INFINITY_RESULT_IMAG:.*]] = arith.mulf %[[INF_WITH_SIGN_OF_RHS_REAL]], %[[LHS_IMAG]] fastmath<nnan,contract> : f32
@@ -1323,9 +1323,9 @@ func.func @complex_sqrt_with_fmf(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[RESULT_RE:.*]] = arith.mulf %[[SQRT_ABS]], %[[COS]] fastmath<nnan,contract> : f32
// CHECK: %[[RESULT_IM:.*]] = arith.mulf %[[SQRT_ABS]], %[[SIN]] fastmath<nnan,contract> : f32
// CHECK: %[[RESULT_IM2:.*]] = arith.select %[[SIN_ZERO]], %[[ZERO]], %[[RESULT_IM]] : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
-// CHECK: %[[NINF:.*]] = arith.constant 0xFF800000 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
+// CHECK: %[[NINF:.*]] = arith.constant -inf : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABSIM:.*]] = math.absf %[[IM]] fastmath<nnan,contract> : f32
// CHECK: %[[ABSIMINF:.*]] = arith.cmpf oeq, %[[ABSIM]], %[[INF]] fastmath<nnan,contract> : f32
// CHECK: %[[ABSIMNOTINF:.*]] = arith.cmpf one, %[[ABSIM]], %[[INF]] fastmath<nnan,contract> : f32
@@ -1440,7 +1440,7 @@ func.func @complex_tan_with_fmf(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[V0:.*]] = complex.im %[[ARG]] : complex<f32>
// CHECK: %[[NEG_ONE:.*]] = arith.constant -1.000000e+00 : f32
// CHECK: %[[REAL:.*]] = arith.mulf %[[V0]], %cst fastmath<nnan,contract> : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
// CHECK: %[[FOUR:.*]] = arith.constant 4.000000e+00 : f32
// CHECK: %[[TWO_REAL:.*]] = arith.addf %[[REAL]], %[[REAL]] fastmath<nnan,contract> : f32
// CHECK: %[[NEG_TWO_REAL:.*]] = arith.mulf %[[NEG_ONE]], %[[TWO_REAL]] fastmath<nnan,contract> : f32
@@ -1462,7 +1462,7 @@ func.func @complex_tan_with_fmf(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[RESULT_IMAG:.*]] = arith.divf %[[IMAG_NUM]], %[[DENOM]] fastmath<nnan,contract> : f32
// CHECK: %[[ABS_REAL:.*]] = math.absf %[[REAL]] fastmath<nnan,contract> : f32
// CHECK: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABS_REAL_INF:.*]] = arith.cmpf oeq, %[[ABS_REAL]], %[[INF]] fastmath<nnan,contract> : f32
// CHECK: %[[IMAG_ZERO:.*]] = arith.cmpf oeq, %[[IMAG]], %[[ZERO]] fastmath<nnan,contract> : f32
// CHECK: %true = arith.constant true
@@ -1489,7 +1489,7 @@ func.func @complex_tanh_with_fmf(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[REAL:.*]] = complex.re %[[ARG]] : complex<f32>
// CHECK: %[[IMAG:.*]] = complex.im %[[ARG]] : complex<f32>
// CHECK: %[[NEG_ONE:.*]] = arith.constant -1.000000e+00 : f32
-// CHECK: %[[INF:.*]] = arith.constant 0x7F800000 : f32
+// CHECK: %[[INF:.*]] = arith.constant +inf : f32
// CHECK: %[[FOUR:.*]] = arith.constant 4.000000e+00 : f32
// CHECK: %[[TWO_REAL:.*]] = arith.addf %[[REAL]], %[[REAL]] fastmath<nnan,contract> : f32
// CHECK: %[[NEG_TWO_REAL:.*]] = arith.mulf %[[NEG_ONE]], %[[TWO_REAL]] fastmath<nnan,contract> : f32
@@ -1511,7 +1511,7 @@ func.func @complex_tanh_with_fmf(%arg: complex<f32>) -> complex<f32> {
// CHECK: %[[RESULT_IMAG:.*]] = arith.divf %[[IMAG_NUM]], %[[DENOM]] fastmath<nnan,contract> : f32
// CHECK: %[[ABS_REAL:.*]] = math.absf %[[REAL]] fastmath<nnan,contract> : f32
// CHECK: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f32
-// CHECK: %[[NAN:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK: %[[NAN:.*]] = arith.constant +qnan : f32
// CHECK: %[[ABS_REAL_INF:.*]] = arith.cmpf oeq, %[[ABS_REAL]], %[[INF]] fastmath<nnan,contract> : f32
// CHECK: %[[IMAG_ZERO:.*]] = arith.cmpf oeq, %[[IMAG]], %[[ZERO]] fastmath<nnan,contract> : f32
// CHECK: %true = arith.constant true
diff --git a/mlir/test/Conversion/GPUToNVVM/wmma-ops-to-nvvm.mlir b/mlir/test/Conversion/GPUToNVVM/wmma-ops-to-nvvm.mlir
index a0801443057ea..eaacce2f91e7f 100644
--- a/mlir/test/Conversion/GPUToNVVM/wmma-ops-to-nvvm.mlir
+++ b/mlir/test/Conversion/GPUToNVVM/wmma-ops-to-nvvm.mlir
@@ -335,7 +335,7 @@ gpu.module @test_module {
// CHECK: %[[CMP0:.*]] = llvm.fcmp "ogt" %[[A0]], %[[B0]] : vector<2xf16>
// CHECK: %[[SEL0:.*]] = llvm.select %[[CMP0]], %[[A0]], %[[B0]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[CMP1:.*]] = llvm.fcmp "uno" %[[A0]], %[[B0]] : vector<2xf16>
-// CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7E00 : f16) : vector<2xf16>
+// CHECK: %[[NAN:.*]] = llvm.mlir.constant(+qnan : f16) : vector<2xf16>
// CHECK: %[[C0:.*]] = llvm.select %[[CMP1]], %[[NAN]], %[[SEL0]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[M1:.*]] = llvm.insertvalue %[[C0]], %[[M0]][0] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
// CHECK: %[[A1:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
@@ -343,7 +343,7 @@ gpu.module @test_module {
// CHECK: %[[CMP2:.*]] = llvm.fcmp "ogt" %[[A1]], %[[B1]] : vector<2xf16>
// CHECK: %[[SEL1:.*]] = llvm.select %[[CMP2]], %[[A1]], %[[B1]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[CMP3:.*]] = llvm.fcmp "uno" %[[A1]], %[[B1]] : vector<2xf16>
-// CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7E00 : f16) : vector<2xf16>
+// CHECK: %[[NAN:.*]] = llvm.mlir.constant(+qnan : f16) : vector<2xf16>
// CHECK: %[[C1:.*]] = llvm.select %[[CMP3]], %[[NAN]], %[[SEL1]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[M2:.*]] = llvm.insertvalue %[[C1]], %[[M1]][1] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
// CHECK: %[[A2:.*]] = llvm.extractvalue %{{.*}}[2] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
@@ -351,7 +351,7 @@ gpu.module @test_module {
// CHECK: %[[CMP4:.*]] = llvm.fcmp "ogt" %[[A2]], %[[B2]] : vector<2xf16>
// CHECK: %[[SEL2:.*]] = llvm.select %[[CMP4]], %[[A2]], %[[B2]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[CMP5:.*]] = llvm.fcmp "uno" %[[A2]], %[[B2]] : vector<2xf16>
-// CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7E00 : f16) : vector<2xf16>
+// CHECK: %[[NAN:.*]] = llvm.mlir.constant(+qnan : f16) : vector<2xf16>
// CHECK: %[[C2:.*]] = llvm.select %[[CMP5]], %[[NAN]], %[[SEL2]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[M3:.*]] = llvm.insertvalue %[[C2]], %[[M2]][2] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
// CHECK: %[[A3:.*]] = llvm.extractvalue %{{.*}}[3] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
@@ -359,7 +359,7 @@ gpu.module @test_module {
// CHECK: %[[CMP6:.*]] = llvm.fcmp "ogt" %[[A3]], %[[B3]] : vector<2xf16>
// CHECK: %[[SEL3:.*]] = llvm.select %[[CMP6]], %[[A3]], %[[B3]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[CMP7:.*]] = llvm.fcmp "uno" %[[A3]], %[[B3]] : vector<2xf16>
-// CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7E00 : f16) : vector<2xf16>
+// CHECK: %[[NAN:.*]] = llvm.mlir.constant(+qnan : f16) : vector<2xf16>
// CHECK: %[[C3:.*]] = llvm.select %[[CMP7]], %[[NAN]], %[[SEL3]] : vector<2xi1>, vector<2xf16>
// CHECK: %[[M5:.*]] = llvm.insertvalue %[[C3]], %[[M3]][3] : !llvm.struct<(vector<2xf16>, vector<2xf16>, vector<2xf16>, vector<2xf16>)>
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
index e6bd800a0cf0a..938426c271f82 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
@@ -601,8 +601,8 @@ func.func @test_simple_f16(%arg0: tensor<1xf16>) -> () {
// CHECK: linalg.generic
// CHECK: [[ROUND:%.+]] = math.roundeven {{%[a-z0-9_]+}} : f16
// CHECK: [[CONV:%.+]] = arith.fptosi [[ROUND]] : f16 to i32
- // CHECK: [[POSINF:%.+]] = arith.constant 0x7C00 : f16
- // CHECK: [[NEGINF:%.+]] = arith.constant 0xFC00 : f16
+ // CHECK: [[POSINF:%.+]] = arith.constant +inf : f16
+ // CHECK: [[NEGINF:%.+]] = arith.constant -inf : f16
// CHECK: [[OVERFLOW:%.+]] = arith.cmpf ueq, [[ROUND]], [[POSINF]] : f16
// CHECK: [[UNDERFLOW:%.+]] = arith.cmpf ueq, [[ROUND]], [[NEGINF]] : f16
// CHECK: [[MININT:%.+]] = arith.constant -2147483648 : i32
@@ -2334,7 +2334,7 @@ func.func @reduce_min_nan_propagate(%arg0: tensor<5x4xf32>, %arg1: tensor<5x4xf3
// CHECK-NOT: arith.cmpf uno
// CHECK-NOT: arith.select
// CHECK: linalg.yield
- // CHECK-NOT: arith.constant 0x7FC00000
+ // CHECK-NOT: arith.constant +qnan
// CHECK-NOT: tensor.empty()
// CHECK-NOT: linalg.fill
// CHECK-NOT: tensor.empty()
@@ -2353,7 +2353,7 @@ func.func @reduce_max_nan_propagate(%arg0: tensor<5x4xf32>, %arg1: tensor<5x4xf3
// CHECK-NOT: arith.cmpf uno
// CHECK-NOT: arith.select
// CHECK: linalg.yield
- // CHECK-NOT: arith.constant 0x7FC00000
+ // CHECK-NOT: arith.constant +qnan
// CHECK-NOT: tensor.empty()
// CHECK-NOT: linalg.fill
// CHECK-NOT: tensor.empty()
@@ -2372,7 +2372,7 @@ func.func @reduce_min_nan_ignore_int(%arg0: tensor<5x4xi8>, %arg1: tensor<5x4xi8
// CHECK-NOT: arith.cmpf uno
// CHECK-NOT: arith.select
// CHECK: linalg.yield
- // CHECK-NOT: arith.constant 0x7FC00000
+ // CHECK-NOT: arith.constant +qnan
// CHECK-NOT: tensor.empty()
// CHECK-NOT: linalg.fill
// CHECK-NOT: tensor.empty()
@@ -2391,7 +2391,7 @@ func.func @reduce_max_nan_ignore_int(%arg0: tensor<5x4xi8>, %arg1: tensor<5x4xi8
// CHECK-NOT: arith.cmpf uno
// CHECK-NOT: arith.select
// CHECK: linalg.yield
- // CHECK-NOT: arith.constant 0x7FC00000
+ // CHECK-NOT: arith.constant +qnan
// CHECK-NOT: tensor.empty()
// CHECK-NOT: linalg.fill
// CHECK-NOT: tensor.empty()
@@ -2410,7 +2410,7 @@ func.func @reduce_min_nan_ignore(%arg0: tensor<5x4xf32>, %arg1: tensor<5x4xf32>)
// CHECK: arith.cmpf uno
// CHECK: arith.select
// CHECK: linalg.yield
- // CHECK: arith.constant 0x7FC00000
+ // CHECK: arith.constant +qnan
// CHECK: tensor.empty()
// CHECK: linalg.fill
// CHECK: tensor.empty()
@@ -2428,7 +2428,7 @@ func.func @reduce_max_nan_ignore(%arg0: tensor<5x4xf32>, %arg1: tensor<5x4xf32>)
// CHECK: arith.cmpf uno
// CHECK: arith.select
// CHECK: linalg.yield
- // CHECK: arith.constant 0x7FC00000
+ // CHECK: arith.constant +qnan
// CHECK: tensor.empty()
// CHECK: linalg.fill
// CHECK: tensor.empty()
diff --git a/mlir/test/Conversion/VectorToLLVM/vector-reduction-to-llvm.mlir b/mlir/test/Conversion/VectorToLLVM/vector-reduction-to-llvm.mlir
index c7d9e22fb2423..4a536c003abb3 100644
--- a/mlir/test/Conversion/VectorToLLVM/vector-reduction-to-llvm.mlir
+++ b/mlir/test/Conversion/VectorToLLVM/vector-reduction-to-llvm.mlir
@@ -123,7 +123,7 @@ func.func @masked_reduce_minf_f32(%arg0: vector<16xf32>, %mask : vector<16xi1>)
// CHECK-LABEL: func.func @masked_reduce_minf_f32(
// CHECK-SAME: %[[INPUT:.*]]: vector<16xf32>,
// CHECK-SAME: %[[MASK:.*]]: vector<16xi1>) -> f32 {
-// CHECK: %[[NEUTRAL:.*]] = llvm.mlir.constant(0xFFC00000 : f32) : f32
+// CHECK: %[[NEUTRAL:.*]] = llvm.mlir.constant(-qnan : f32) : f32
// CHECK: %[[VL:.*]] = llvm.mlir.constant(16 : i32) : i32
// CHECK: "llvm.intr.vp.reduce.fmin"(%[[NEUTRAL]], %[[INPUT]], %[[MASK]], %[[VL]]) : (f32, vector<16xf32>, vector<16xi1>, i32) -> f32
@@ -137,7 +137,7 @@ func.func @masked_reduce_minf_f32_scalable(%arg0: vector<[16]xf32>, %mask : vect
// CHECK-LABEL: func.func @masked_reduce_minf_f32_scalable(
// CHECK-SAME: %[[INPUT:.*]]: vector<[16]xf32>,
// CHECK-SAME: %[[MASK:.*]]: vector<[16]xi1>) -> f32 {
-// CHECK: %[[NEUTRAL:.*]] = llvm.mlir.constant(0xFFC00000 : f32) : f32
+// CHECK: %[[NEUTRAL:.*]] = llvm.mlir.constant(-qnan : f32) : f32
// CHECK: %[[VL_BASE:.*]] = llvm.mlir.constant(16 : i32) : i32
// CHECK: %[[VSCALE:.*]] = "llvm.intr.vscale"() : () -> i64
// CHECK: %[[CAST_IDX:.*]] = builtin.unrealized_conversion_cast %[[VSCALE]] : i64 to index
@@ -155,7 +155,7 @@ func.func @masked_reduce_maxf_f32(%arg0: vector<16xf32>, %mask : vector<16xi1>)
// CHECK-LABEL: func.func @masked_reduce_maxf_f32(
// CHECK-SAME: %[[INPUT:.*]]: vector<16xf32>,
// CHECK-SAME: %[[MASK:.*]]: vector<16xi1>) -> f32 {
-// CHECK: %[[NEUTRAL:.*]] = llvm.mlir.constant(0x7FC00000 : f32) : f32
+// CHECK: %[[NEUTRAL:.*]] = llvm.mlir.constant(+qnan : f32) : f32
// CHECK: %[[VL:.*]] = llvm.mlir.constant(16 : i32) : i32
// CHECK: "llvm.intr.vp.reduce.fmax"(%[[NEUTRAL]], %[[INPUT]], %[[MASK]], %[[VL]]) : (f32, vector<16xf32>, vector<16xi1>, i32) -> f32
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir
index 9dacc316f1072..31dffa96adace 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir
@@ -44,7 +44,7 @@ func.func @vecdim_reduction_minf(%in: memref<256x512xf32>, %out: memref<256xf32>
// CHECK-LABEL: @vecdim_reduction_minf
// CHECK: affine.for %{{.*}} = 0 to 256 {
-// CHECK: %[[vmax:.*]] = arith.constant dense<0x7F800000> : vector<128xf32>
+// CHECK: %[[vmax:.*]] = arith.constant dense<+inf> : vector<128xf32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vmax]]) -> (vector<128xf32>) {
// CHECK: %[[ld:.*]] = vector.transfer_read %{{.*}} : memref<256x512xf32>, vector<128xf32>
// CHECK: %[[min:.*]] = arith.minimumf %[[red_iter]], %[[ld]] : vector<128xf32>
@@ -71,7 +71,7 @@ func.func @vecdim_reduction_maxf(%in: memref<256x512xf32>, %out: memref<256xf32>
// CHECK-LABEL: @vecdim_reduction_maxf
// CHECK: affine.for %{{.*}} = 0 to 256 {
-// CHECK: %[[vmin:.*]] = arith.constant dense<0xFF800000> : vector<128xf32>
+// CHECK: %[[vmin:.*]] = arith.constant dense<-inf> : vector<128xf32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vmin]]) -> (vector<128xf32>) {
// CHECK: %[[ld:.*]] = vector.transfer_read %{{.*}} : memref<256x512xf32>, vector<128xf32>
// CHECK: %[[max:.*]] = arith.maximumf %[[red_iter]], %[[ld]] : vector<128xf32>
@@ -294,9 +294,9 @@ func.func @vecdim_reduction_minnumf(%in: memref<256x512xf32>, %out: memref<256xf
// CHECK-LABEL: func.func @vecdim_reduction_minnumf(
// CHECK-SAME: %[[input:.*]]: memref<256x512xf32>,
// CHECK-SAME: %[[output:.*]]: memref<256xf32>) {
-// CHECK: %[[cst:.*]] = arith.constant 0xFF800000 : f32
+// CHECK: %[[cst:.*]] = arith.constant -inf : f32
// CHECK: affine.for %{{.*}} = 0 to 256 {
-// CHECK: %[[vzero:.*]] = arith.constant dense<0x7FC00000> : vector<128xf32>
+// CHECK: %[[vzero:.*]] = arith.constant dense<+qnan> : vector<128xf32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vzero]]) -> (vector<128xf32>) {
// CHECK: %[[poison:.*]] = ub.poison : f32
// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] {in_bounds = [true]} : memref<256x512xf32>, vector<128xf32>
@@ -328,9 +328,9 @@ func.func @vecdim_reduction_maxnumf(%in: memref<256x512xf32>, %out: memref<256xf
// CHECK-LABEL: func.func @vecdim_reduction_maxnumf(
// CHECK-SAME: %[[input:.*]]: memref<256x512xf32>,
// CHECK-SAME: %[[output:.*]]: memref<256xf32>) {
-// CHECK: %[[cst:.*]] = arith.constant 0xFF800000 : f32
+// CHECK: %[[cst:.*]] = arith.constant -inf : f32
// CHECK: affine.for %{{.*}} = 0 to 256 {
-// CHECK: %[[vzero:.*]] = arith.constant dense<0xFFC00000> : vector<128xf32>
+// CHECK: %[[vzero:.*]] = arith.constant dense<-qnan> : vector<128xf32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vzero]]) -> (vector<128xf32>) {
// CHECK: %[[poison:.*]] = ub.poison : f32
// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] {in_bounds = [true]} : memref<256x512xf32>, vector<128xf32>
diff --git a/mlir/test/Dialect/Arith/emulate-wide-int.mlir b/mlir/test/Dialect/Arith/emulate-wide-int.mlir
index 695d8fd453fd7..b23121cf101cc 100644
--- a/mlir/test/Dialect/Arith/emulate-wide-int.mlir
+++ b/mlir/test/Dialect/Arith/emulate-wide-int.mlir
@@ -991,7 +991,7 @@ func.func @uitofp_i64_f64_vector(%a : vector<3xi64>) -> vector<3xf64> {
// CHECK-NEXT: [[HIEQ0:%.+]] = arith.cmpi eq, [[HI]], [[CST0]] : i32
// CHECK-NEXT: [[LOWFP:%.+]] = arith.uitofp [[LOW]] : i32 to f16
// CHECK-NEXT: [[HIFP:%.+]] = arith.uitofp [[HI]] : i32 to f16
-// CHECK-NEXT: [[POW:%.+]] = arith.constant 0x7C00 : f16
+// CHECK-NEXT: [[POW:%.+]] = arith.constant +inf : f16
// CHECK-NEXT: [[RESHI:%.+]] = arith.mulf [[HIFP]], [[POW]] : f16
// CHECK-NEXT: [[RES:%.+]] = arith.addf [[LOWFP]], [[RESHI]] : f16
// CHECK-NEXT: [[SEL:%.+]] = arith.select [[HIEQ0]], [[LOWFP]], [[RES]] : f16
diff --git a/mlir/test/Dialect/Builtin/Bytecode/attrs.mlir b/mlir/test/Dialect/Builtin/Bytecode/attrs.mlir
index 7dedfbdff10a7..978c29de3fc85 100644
--- a/mlir/test/Dialect/Builtin/Bytecode/attrs.mlir
+++ b/mlir/test/Dialect/Builtin/Bytecode/attrs.mlir
@@ -97,12 +97,12 @@ module @TestDenseStringElementsAttr attributes {
// CHECK-LABEL: @TestFloat
module @TestFloat attributes {
// CHECK: bytecode.float = 1.000000e+01 : f64
- // CHECK: bytecode.float1 = 0.10000{{.*}} : f80
- // CHECK: bytecode.float2 = 0.10000{{.*}} : f128
+ // CHECK: bytecode.float1 = 1.000000e-01 : f80
+ // CHECK: bytecode.float2 = 1.000000e-01 : f128
// CHECK: bytecode.float3 = -5.000000e-01 : bf16
- // CHECK: bytecode.inf = 0x7FF0000000000000 : f64
- // CHECK: bytecode.nan = 0x7FF8000000000000 : f64
- // CHECK: bytecode.ninf = 0xFFF0000000000000 : f64
+ // CHECK: bytecode.inf = +inf : f64
+ // CHECK: bytecode.nan = +qnan : f64
+ // CHECK: bytecode.ninf = -inf : f64
bytecode.float = 10.0 : f64,
bytecode.float1 = 0.1 : f80,
bytecode.float2 = 0.1 : f128,
diff --git a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
index d427035435277..ebb198456b3c1 100644
--- a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
+++ b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed.mlir
@@ -125,8 +125,8 @@ module @TestFloatAttr attributes {
// CHECK-DAG: bytecode.f16 = 1.500000e+00 : f16
// CHECK-DAG: bytecode.f32 = 3.140000e+00 : f32
// CHECK-DAG: bytecode.f64 = 1.000000e+01 : f64
- // CHECK-DAG: bytecode.f80 = 0.1{{.*}} : f80
- // CHECK-DAG: bytecode.f128 = 0.1{{.*}} : f128
+ // CHECK-DAG: bytecode.f80 = 1.000000e-01 : f80
+ // CHECK-DAG: bytecode.f128 = 1.000000e-01 : f128
// CHECK-DAG: bytecode.tf32 = 1.000000e+00 : tf32
// CHECK-DAG: bytecode.f8E5M2 = 1.000000e+00 : f8E5M2
// CHECK-DAG: bytecode.f8E4M3 = 1.000000e+00 : f8E4M3
diff --git a/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc b/mlir/test/Dialect/Builtin/Bytecode/builtin_fixed_0.mlirbc
index 95be4de8fd1ab202b51658ce69f8037276dd74e8..4f661b5a1d233336116b303958bc724529f88b5a 100644
GIT binary patch
delta 27
ecmcbobx&)<4<?S&XCPn_vo2F=+Gc%beIWqP@(kAi
delta 27
ecmcbobx&)<4<?TP5U_s|vo6#B_|5vv`a%Hd#SX&&
diff --git a/mlir/test/Dialect/Complex/canonicalize.mlir b/mlir/test/Dialect/Complex/canonicalize.mlir
index 1c5216c82e5c3..065e1a9cdb4c9 100644
--- a/mlir/test/Dialect/Complex/canonicalize.mlir
+++ b/mlir/test/Dialect/Complex/canonicalize.mlir
@@ -332,7 +332,7 @@ func.func @div_op_with_rhs_has_nan_real() -> complex<f32> {
%a = complex.constant [0x7fffffff : f32, 1.0 : f32]: complex<f32>
%b = complex.constant [1.0: f32, 0.0 : f32]: complex<f32>
%div = complex.div %a, %b : complex<f32>
- // CHECK: %[[DIV:.*]] = complex.constant [0x7FFFFFFF : f32, 0x7FFFFFFF : f32] : complex<f32>
+ // CHECK: %[[DIV:.*]] = complex.constant [+nan(0x3FFFFF) : f32, +nan(0x3FFFFF) : f32] : complex<f32>
// CHECK: return %[[DIV]] : complex<f32>
return %div : complex<f32>
}
@@ -342,7 +342,7 @@ func.func @div_op_with_rhs_has_nan_imag() -> complex<f32> {
%a = complex.constant [1.0 : f32, 0x7fffffff : f32]: complex<f32>
%b = complex.constant [1.0: f32, 0.0 : f32]: complex<f32>
%div = complex.div %a, %b : complex<f32>
- // CHECK: %[[DIV:.*]] = complex.constant [0x7FFFFFFF : f32, 0x7FFFFFFF : f32] : complex<f32>
+ // CHECK: %[[DIV:.*]] = complex.constant [+nan(0x3FFFFF) : f32, +nan(0x3FFFFF) : f32] : complex<f32>
// CHECK: return %[[DIV]] : complex<f32>
return %div : complex<f32>
}
@@ -352,7 +352,7 @@ func.func @div_op_with_rhs_has_nan_real_imag() -> complex<f32> {
%a = complex.constant [0x7fffffff : f32, 0x7fffffff : f32]: complex<f32>
%b = complex.constant [1.0: f32, 0.0 : f32]: complex<f32>
%div = complex.div %a, %b : complex<f32>
- // CHECK: %[[DIV:.*]] = complex.constant [0x7FFFFFFF : f32, 0x7FFFFFFF : f32] : complex<f32>
+ // CHECK: %[[DIV:.*]] = complex.constant [+nan(0x3FFFFF) : f32, +nan(0x3FFFFF) : f32] : complex<f32>
// CHECK: return %[[DIV]] : complex<f32>
return %div : complex<f32>
}
diff --git a/mlir/test/Dialect/Linalg/transform-op-decompose.mlir b/mlir/test/Dialect/Linalg/transform-op-decompose.mlir
index 3897f8502bb04..deb59e8fc3ab0 100644
--- a/mlir/test/Dialect/Linalg/transform-op-decompose.mlir
+++ b/mlir/test/Dialect/Linalg/transform-op-decompose.mlir
@@ -369,7 +369,7 @@ func.func @softmax(%arg0: tensor<2x16x32xf32>, %dst: tensor<2x16x32xf32>) -> ten
// CHECK-LABEL: func.func @softmax(
// CHECK-SAME: %[[ARG0:[a-zA-Z0-9_]+]]: tensor<2x16x32xf32>, %[[DST:[a-zA-Z0-9_]+]]: tensor<2x16x32xf32>) -> tensor<2x16x32xf32> {
// CHECK-DAG: %[[D1:.+]] = tensor.empty() : tensor<2x16xf32>
-// CHECK-DAG: %[[CST:.+]] = arith.constant 0xFFC00000 : f32
+// CHECK-DAG: %[[CST:.+]] = arith.constant -qnan : f32
// CHECK: %[[D2:.+]] = linalg.fill ins(%[[CST]] : f32) outs(%[[D1]] : tensor<2x16xf32>) -> tensor<2x16xf32>
// CHECK: %[[D3:.+]] = linalg.generic {indexing_maps = [#[[$MAP]], #[[$MAP1]]], iterator_types = ["parallel",
// CHECK-SAME: "parallel", "reduction"]} ins(%[[ARG0]] : tensor<2x16x32xf32>) outs(%[[D2]] : tensor<2x16xf32>) {
diff --git a/mlir/test/Dialect/Linalg/transform-op-split-reduction.mlir b/mlir/test/Dialect/Linalg/transform-op-split-reduction.mlir
index 9849f36285b16..a97f0a3327acb 100644
--- a/mlir/test/Dialect/Linalg/transform-op-split-reduction.mlir
+++ b/mlir/test/Dialect/Linalg/transform-op-split-reduction.mlir
@@ -118,7 +118,7 @@ func.func @generic_split_3d(%input: tensor<32x2xf32>, %input_2: tensor<5x32xf32>
// CHECK-DAG: #[[$MAP3:.*]] = affine_map<(d0, d1, d2) -> (d0, d1, d2)>
// CHECK-DAG: #[[$MAP4:.*]] = affine_map<(d0, d1, d2) -> (d0, d1)>
// CHECK-LABEL: func @generic_split_3d
-// CHECK-DAG: %[[ID:.*]] = arith.constant 0xFF800000 : f32
+// CHECK-DAG: %[[ID:.*]] = arith.constant -inf : f32
// CHECK-DAG: %[[I1:.*]] = tensor.expand_shape %{{.*}}[0, 1], [2]] output_shape [4, 8, 2] : tensor<32x2xf32> into tensor<4x8x2xf32>
// CHECK-DAG: %[[I2:.*]] = tensor.expand_shape %{{.*}}[0], [1, 2]] output_shape [5, 4, 8] : tensor<5x32xf32> into tensor<5x4x8xf32>
// CHECK-DAG: %[[INI:.*]] = tensor.empty() : tensor<5x2x4xf32>
@@ -323,7 +323,7 @@ func.func @generic_split_3d(%input: tensor<32x2xf32>, %input_2: tensor<5x32xf32>
// CHECK-DAG: #[[$MAP3:.*]] = affine_map<(d0, d1, d2) -> (d0, d1, d2)>
// CHECK-DAG: #[[$MAP4:.*]] = affine_map<(d0, d1, d2) -> (d0, d1)>
// CHECK-LABEL: func @generic_split_3d
-// CHECK-DAG: %[[ID:.*]] = arith.constant 0x7F800000 : f32
+// CHECK-DAG: %[[ID:.*]] = arith.constant +inf : f32
// CHECK-DAG: %[[I1:.*]] = tensor.expand_shape %{{.*}}[0, 1], [2]] output_shape [8, 4, 2] : tensor<32x2xf32> into tensor<8x4x2xf32>
// CHECK-DAG: %[[I2:.*]] = tensor.expand_shape %{{.*}}[0], [1, 2]] output_shape [5, 8, 4] : tensor<5x32xf32> into tensor<5x8x4xf32>
// CHECK-DAG: %[[INI:.*]] = tensor.empty() : tensor<5x2x4xf32>
@@ -429,7 +429,7 @@ func.func @generic_split_maxnumf(%in: tensor<32xf32>, %out: tensor<f32>) -> tens
// CHECK-DAG: #[[$MAP3:.*]] = affine_map<(d0) -> ()>
// CHECK-LABEL: func @generic_split_maxnumf
// The float value 0xFFC00000 that is filled into the init tensor represents negative NaN.
-// CHECK-DAG: %[[ID:.*]] = arith.constant 0xFFC00000 : f32
+// CHECK-DAG: %[[ID:.*]] = arith.constant -qnan : f32
// CHECK-DAG: %[[I1:.*]] = tensor.expand_shape %{{.*}}[0, 1]] output_shape [8, 4] : tensor<32xf32> into tensor<8x4xf32>
// CHECK-DAG: %[[INI:.*]] = tensor.empty() : tensor<4xf32>
// CHECK: %[[F:.*]] = linalg.fill ins(%[[ID]] : f32) outs(%[[INI]] : tensor<4xf32>) -> tensor<4xf32>
@@ -475,7 +475,7 @@ func.func @generic_split_minnumf(%in: tensor<32xf32>, %out: tensor<f32>) -> tens
// CHECK-DAG: #[[$MAP3:.*]] = affine_map<(d0) -> ()>
// CHECK-LABEL: func @generic_split_minnumf
// The float value 0x7FC00000 that is filled into the init tensor represents positive NaN.
-// CHECK-DAG: %[[ID:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK-DAG: %[[ID:.*]] = arith.constant +qnan : f32
// CHECK-DAG: %[[I1:.*]] = tensor.expand_shape %{{.*}}[0, 1]] output_shape [8, 4] : tensor<32xf32> into tensor<8x4xf32>
// CHECK-DAG: %[[INI:.*]] = tensor.empty() : tensor<4xf32>
// CHECK: %[[F:.*]] = linalg.fill ins(%[[ID]] : f32) outs(%[[INI]] : tensor<4xf32>) -> tensor<4xf32>
diff --git a/mlir/test/Dialect/Linalg/transform-tile-reduction.mlir b/mlir/test/Dialect/Linalg/transform-tile-reduction.mlir
index 25af6796d1f63..daa80a98c9af0 100644
--- a/mlir/test/Dialect/Linalg/transform-tile-reduction.mlir
+++ b/mlir/test/Dialect/Linalg/transform-tile-reduction.mlir
@@ -317,7 +317,7 @@ module attributes {transform.with_named_sequence} {
// CHECK: func @reduction_tile_multiple_results
// CHECK-DAG: %[[SUM_ID:.+]] = arith.constant 0.000000e+00 : f32
-// CHECK-DAG: %[[MAX_ID:.+]] = arith.constant 0xFF800000 : f32
+// CHECK-DAG: %[[MAX_ID:.+]] = arith.constant -inf : f32
// CHECK-DAG: %[[SUM_INIT:.+]] = linalg.fill ins(%[[SUM_ID]] : f32) outs(%{{.*}} : tensor<?x5xf32>) -> tensor<?x5xf32>
// CHECK-DAG: %[[MAX_INIT:.+]] = linalg.fill ins(%[[MAX_ID]] : f32) outs(%{{.*}} : tensor<?x5xf32>) -> tensor<?x5xf32>
// CHECK: %[[OUT:.+]]:2 = scf.for
diff --git a/mlir/test/Dialect/Math/canonicalize.mlir b/mlir/test/Dialect/Math/canonicalize.mlir
index 3459164c5c0a7..6ca81b47a0675 100644
--- a/mlir/test/Dialect/Math/canonicalize.mlir
+++ b/mlir/test/Dialect/Math/canonicalize.mlir
@@ -28,7 +28,7 @@ func.func @log2_fold() -> f32 {
}
// CHECK-LABEL: @log2_fold2
-// CHECK: %[[cst:.+]] = arith.constant 0xFF800000 : f32
+// CHECK: %[[cst:.+]] = arith.constant -inf : f32
// CHECK: return %[[cst]]
func.func @log2_fold2() -> f32 {
%c = arith.constant 0.0 : f32
@@ -56,7 +56,7 @@ func.func @log2_fold_64() -> f64 {
}
// CHECK-LABEL: @log2_fold2_64
-// CHECK: %[[cst:.+]] = arith.constant 0xFFF0000000000000 : f64
+// CHECK: %[[cst:.+]] = arith.constant -inf : f64
// CHECK: return %[[cst]]
func.func @log2_fold2_64() -> f64 {
%c = arith.constant 0.0 : f64
diff --git a/mlir/test/Dialect/Math/expand-math.mlir b/mlir/test/Dialect/Math/expand-math.mlir
index 84b0bb0aa314a..973eab6348d66 100644
--- a/mlir/test/Dialect/Math/expand-math.mlir
+++ b/mlir/test/Dialect/Math/expand-math.mlir
@@ -634,8 +634,8 @@ func.func @math_fpowi_neg_odd_power(%0 : tensor<8xf32>) -> tensor<8xf32> {
// CHECK-DAG: %[[CST1:.*]] = arith.constant dense<1.000000e+00> : tensor<8xf32>
// CHECK-DAG: %[[CST0:.*]] = arith.constant dense<0.000000e+00> : tensor<8xf32>
// CHECK-DAG: %[[CSTNEG0:.*]] = arith.constant dense<-0.000000e+00> : tensor<8xf32>
-// CHECK-DAG: %[[CSTINF:.*]] = arith.constant dense<0x7F800000> : tensor<8xf32>
-// CHECK-DAG: %[[CSTNEGINF:.*]] = arith.constant dense<0xFF800000> : tensor<8xf32>
+// CHECK-DAG: %[[CSTINF:.*]] = arith.constant dense<+inf> : tensor<8xf32>
+// CHECK-DAG: %[[CSTNEGINF:.*]] = arith.constant dense<-inf> : tensor<8xf32>
// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : tensor<8xf32>
// CHECK: %[[CUBE:.*]] = arith.mulf %[[SQ]], %[[ARG0]] : tensor<8xf32>
// CHECK: %[[CMP0:.*]] = arith.cmpf oeq, %[[CUBE]], %[[CST0]] : tensor<8xf32>
@@ -657,8 +657,8 @@ func.func @math_fpowi_neg_even_power(%0 : tensor<8xf32>) -> tensor<8xf32> {
// CHECK-DAG: %[[CST1:.*]] = arith.constant dense<1.000000e+00> : tensor<8xf32>
// CHECK-DAG: %[[CST0:.*]] = arith.constant dense<0.000000e+00> : tensor<8xf32>
// CHECK-DAG: %[[CSTNEG0:.*]] = arith.constant dense<-0.000000e+00> : tensor<8xf32>
-// CHECK-DAG: %[[CSTINF:.*]] = arith.constant dense<0x7F800000> : tensor<8xf32>
-// CHECK-DAG: %[[CSTNEGINF:.*]] = arith.constant dense<0xFF800000> : tensor<8xf32>
+// CHECK-DAG: %[[CSTINF:.*]] = arith.constant dense<+inf> : tensor<8xf32>
+// CHECK-DAG: %[[CSTNEGINF:.*]] = arith.constant dense<-inf> : tensor<8xf32>
// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : tensor<8xf32>
// CHECK: %[[PW4:.*]] = arith.mulf %[[SQ]], %[[SQ]] : tensor<8xf32>
// CHECK: %[[CMP0:.*]] = arith.cmpf oeq, %[[PW4]], %[[CST0]] : tensor<8xf32>
diff --git a/mlir/test/Dialect/Math/polynomial-approximation.mlir b/mlir/test/Dialect/Math/polynomial-approximation.mlir
index c14ed47853411..9f447ecd5f497 100644
--- a/mlir/test/Dialect/Math/polynomial-approximation.mlir
+++ b/mlir/test/Dialect/Math/polynomial-approximation.mlir
@@ -114,7 +114,7 @@ func.func @erf_scalar(%arg0: f32) -> f32 {
// CHECK-DAG: %[[cst_24:.*]] = arith.constant -4.000000e+00 : f32
// CHECK-DAG: %[[cst_25:.*]] = arith.constant -2.000000e+00 : f32
// CHECK-DAG: %[[cst_26:.*]] = arith.constant 2.000000e+00 : f32
-// CHECK-DAG: %[[cst_27:.*]] = arith.constant 0x7F800000 : f32
+// CHECK-DAG: %[[cst_27:.*]] = arith.constant +inf : f32
// CHECK-DAG: %[[cst_28:.*]] = arith.constant 10.0546875 : f32
// CHECK: %[[val_2:.*]] = math.absf %[[val_arg0]] : f32
// CHECK-NEXT: %[[val_3:.*]] = arith.addf %[[val_2]], %[[cst_26]] : f32
@@ -308,9 +308,9 @@ func.func @exp_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
// CHECK-DAG: %[[VAL_18:.*]] = arith.constant 0.000000e+00 : f32
// CHECK-DAG: %[[VAL_19:.*]] = arith.constant -5.000000e-01 : f32
// CHECK-DAG: %[[VAL_20:.*]] = arith.constant 1.17549435E-38 : f32
-// CHECK-DAG: %[[VAL_21:.*]] = arith.constant 0xFF800000 : f32
-// CHECK-DAG: %[[VAL_22:.*]] = arith.constant 0x7F800000 : f32
-// CHECK-DAG: %[[VAL_23:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK-DAG: %[[VAL_21:.*]] = arith.constant -inf : f32
+// CHECK-DAG: %[[VAL_22:.*]] = arith.constant +inf : f32
+// CHECK-DAG: %[[VAL_23:.*]] = arith.constant +qnan : f32
// CHECK-DAG: %[[VAL_24:.*]] = arith.constant 0.707106769 : f32
// CHECK-DAG: %[[VAL_25:.*]] = arith.constant 0.0703768358 : f32
// CHECK-DAG: %[[VAL_26:.*]] = arith.constant -0.115146101 : f32
@@ -434,9 +434,9 @@ func.func @expm1_scalable_vector(%arg0: vector<8x[8]xf32>) -> vector<8x[8]xf32>
// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
// CHECK-DAG: %[[VAL_3:.*]] = arith.constant -5.000000e-01 : f32
// CHECK-DAG: %[[VAL_4:.*]] = arith.constant 1.17549435E-38 : f32
-// CHECK-DAG: %[[VAL_5:.*]] = arith.constant 0xFF800000 : f32
-// CHECK-DAG: %[[VAL_6:.*]] = arith.constant 0x7F800000 : f32
-// CHECK-DAG: %[[VAL_7:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK-DAG: %[[VAL_5:.*]] = arith.constant -inf : f32
+// CHECK-DAG: %[[VAL_6:.*]] = arith.constant +inf : f32
+// CHECK-DAG: %[[VAL_7:.*]] = arith.constant +qnan : f32
// CHECK-DAG: %[[VAL_8:.*]] = arith.constant 0.707106769 : f32
// CHECK-DAG: %[[VAL_9:.*]] = arith.constant 0.0703768358 : f32
// CHECK-DAG: %[[VAL_10:.*]] = arith.constant -0.115146101 : f32
@@ -683,7 +683,7 @@ func.func @rsqrt_scalar(%arg0: f32) -> f32 {
// CHECK: math.rsqrt
// AVX2-LABEL: func @rsqrt_vector_8xf32(
// AVX2-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
-// AVX2: %[[VAL_1:.*]] = arith.constant dense<0x7F800000> : vector<8xf32>
+// AVX2: %[[VAL_1:.*]] = arith.constant dense<+inf> : vector<8xf32>
// AVX2: %[[VAL_2:.*]] = arith.constant dense<1.500000e+00> : vector<8xf32>
// AVX2: %[[VAL_3:.*]] = arith.constant dense<-5.000000e-01> : vector<8xf32>
// AVX2: %[[VAL_4:.*]] = arith.constant dense<1.17549435E-38> : vector<8xf32>
@@ -857,7 +857,7 @@ func.func @atan_scalar(%arg0: f32) -> f32 {
// CHECK-DAG: %[[VAL_17:.*]] = arith.constant 0.000000e+00 : f32
// CHECK-DAG: %[[VAL_18:.*]] = arith.constant 3.14159274 : f32
// CHECK-DAG: %[[VAL_19:.*]] = arith.constant -1.57079637 : f32
-// CHECK-DAG: %[[VAL_20:.*]] = arith.constant 0x7FC00000 : f32
+// CHECK-DAG: %[[VAL_20:.*]] = arith.constant +qnan : f32
// CHECK-DAG: %[[VAL_21:.*]] = arith.extf %[[VAL_0]] : f16 to f32
// CHECK-DAG: %[[VAL_22:.*]] = arith.extf %[[VAL_1]] : f16 to f32
// CHECK-DAG: %[[VAL_23:.*]] = arith.divf %[[VAL_21]], %[[VAL_22]] : f32
diff --git a/mlir/test/Dialect/SPIRV/IR/structure-ops.mlir b/mlir/test/Dialect/SPIRV/IR/structure-ops.mlir
index 37a9e97106de9..134ea627cf165 100644
--- a/mlir/test/Dialect/SPIRV/IR/structure-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/structure-ops.mlir
@@ -177,7 +177,7 @@ func.func @struct_constant_identified() -> () {
// -----
func.func @coop_matrix_const_non_dense() -> () {
- // expected-error @+2 {{floating point value not valid for specified type}}
+ // expected-error @below {{floating point value not valid for specified type}}
%0 = spirv.Constant 0.000000e+00 : !spirv.coopmatrix<16x16xf32, Subgroup, MatrixAcc>
return
}
diff --git a/mlir/test/Dialect/Tosa/constant-reciprocal-fold.mlir b/mlir/test/Dialect/Tosa/constant-reciprocal-fold.mlir
index 12a3aee428ac6..e17e1b09e9e2e 100644
--- a/mlir/test/Dialect/Tosa/constant-reciprocal-fold.mlir
+++ b/mlir/test/Dialect/Tosa/constant-reciprocal-fold.mlir
@@ -22,8 +22,8 @@ func.func @reciprocal_fold_splat() -> tensor<12x7xf32> {
// CHECK-LABEL: @reciprocal_div_zero
func.func @reciprocal_div_zero() -> tensor<f32> {
- // 0x7F800000 is the value for +infinity
- // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0x7F800000
+ // +inf is the value for +infinity
+ // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}+inf
// CHECK-NOT: tosa.reciprocal
// CHECK: return [[RES]]
%0 = "tosa.const"() {values = dense<0.0> : tensor<f32>} : () -> tensor<f32>
@@ -33,8 +33,8 @@ func.func @reciprocal_div_zero() -> tensor<f32> {
// CHECK-LABEL: @reciprocal_div_neg_zero
func.func @reciprocal_div_neg_zero() -> tensor<f32> {
- // 0xFF800000 is the value for -infinity
- // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0xFF800000
+ // -inf is the value for -infinity
+ // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}-inf
// CHECK-NOT: tosa.reciprocal
// CHECK: return [[RES]]
%0 = "tosa.const"() {values = dense<-0.0> : tensor<f32>} : () -> tensor<f32>
@@ -44,8 +44,8 @@ func.func @reciprocal_div_neg_zero() -> tensor<f32> {
// CHECK-LABEL: @reciprocal_div_nan
func.func @reciprocal_div_nan() -> tensor<f32> {
- // 0x7FC00000 is the value for NAN
- // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0x7FC00000
+ // +qnan is the value for NAN
+ // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}+qnan
// CHECK-NOT: tosa.reciprocal
// CHECK: return [[RES]]
%0 = "tosa.const"() {values = dense<0x7FC00000> : tensor<f32>} : () -> tensor<f32>
@@ -85,7 +85,7 @@ func.func @reciprocal_div_underflow() -> tensor<2xf16> {
// CHECK-LABEL: @reciprocal_div_overflow
func.func @reciprocal_div_overflow() -> tensor<2xf16> {
- // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0x7C00, 0xFC00
+ // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}+inf, -inf
// CHECK-NOT: tosa.reciprocal
// CHECK: return [[RES]]
%0 = "tosa.const"() {values = dense<[0.0000001, -0.0000001]> : tensor<2xf16>} : () -> tensor<2xf16>
diff --git a/mlir/test/Dialect/Tosa/invalid.mlir b/mlir/test/Dialect/Tosa/invalid.mlir
index e559ea5f3c0ab..26ac36f89e1f1 100644
--- a/mlir/test/Dialect/Tosa/invalid.mlir
+++ b/mlir/test/Dialect/Tosa/invalid.mlir
@@ -2019,7 +2019,7 @@ func.func @test_mul_out_i16(%arg0: tensor<13x21x3xi8>, %arg1: tensor<13x1x3xi8>,
// CHECK-LABEL: test_clamp_nan_min_val
func.func @test_clamp_nan_min_val(%arg0: tensor<13x21x3xf32>) -> tensor<13x21x3xf32> {
- // expected-error at +1 {{'tosa.clamp' op min/max attributes should not be 'NaN', got min_val=0xFFFFFFFF : f32, max_val=1.000000e+00 : f32}}
+ // expected-error at +1 {{'tosa.clamp' op min/max attributes should not be 'NaN', got min_val=-nan(0x3FFFFF) : f32, max_val=1.000000e+00 : f32}}
%0 = tosa.clamp %arg0 {min_val = 0xFFFFFFFF : f32, max_val = 1.0: f32} : (tensor<13x21x3xf32>) -> tensor<13x21x3xf32>
return %0 : tensor<13x21x3xf32>
}
@@ -2028,7 +2028,7 @@ func.func @test_clamp_nan_min_val(%arg0: tensor<13x21x3xf32>) -> tensor<13x21x3x
// CHECK-LABEL: test_clamp_nan_max_val
func.func @test_clamp_nan_max_val(%arg0: tensor<13x21x3xf32>) -> tensor<13x21x3xf32> {
- // expected-error at +1 {{'tosa.clamp' op min/max attributes should not be 'NaN', got min_val=2.300000e+00 : f32, max_val=0x7FFFFFFF : f32}}
+ // expected-error at +1 {{'tosa.clamp' op min/max attributes should not be 'NaN', got min_val=2.300000e+00 : f32, max_val=+nan(0x3FFFFF) : f32}}
%0 = tosa.clamp %arg0 {min_val = 2.3 : f32, max_val = 0x7FFFFFFF: f32} : (tensor<13x21x3xf32>) -> tensor<13x21x3xf32>
return %0 : tensor<13x21x3xf32>
}
diff --git a/mlir/test/Dialect/XeGPU/propagate-layout.mlir b/mlir/test/Dialect/XeGPU/propagate-layout.mlir
index 79a5d229263c5..ceb8123329cdb 100644
--- a/mlir/test/Dialect/XeGPU/propagate-layout.mlir
+++ b/mlir/test/Dialect/XeGPU/propagate-layout.mlir
@@ -776,7 +776,7 @@ func.func @vector_2d_reduction_with_fractional_subgroup_size_1x4(%arg0: memref<1
gpu.module @test {
// CHECK: func.func @vector_reduction_broadcast_transpose(%[[ARG0:.*]]: memref<1024x64xf32>, %[[ARG1:.*]]: memref<1024x64xf32>)
// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.slice<#xegpu.layout<lane_layout = [1, 16], lane_data = [1, 1]>, dims = [1]>} dense<0.000000e+00> : vector<1xf32>
-// CHECK: %[[CST_0:.*]] = arith.constant {layout_result_0 = #xegpu.layout<lane_layout = [1, 16], lane_data = [1, 1]>} dense<0xFF800000> : vector<1x16xf32>
+// CHECK: %[[CST_0:.*]] = arith.constant {layout_result_0 = #xegpu.layout<lane_layout = [1, 16], lane_data = [1, 1]>} dense<-inf> : vector<1x16xf32>
// CHECK: %[[CST_1:.*]] = arith.constant {layout_result_0 = #xegpu.slice<#xegpu.layout<lane_layout = [16, 1], lane_data = [1, 1], order = [0, 1]>, dims = [0]>} dense<0.000000e+00> : vector<8xf32>
// CHECK: %[[C0:.*]] = arith.constant 0 : index
// CHECK: %[[RED:.*]] = vector.multi_reduction <add>, %[[CST_0]], %[[CST]] {layout_result_0 = #xegpu.slice<#xegpu.layout<lane_layout = [1, 16], lane_data = [1, 1]>, dims = [1]>} [1] : vector<1x16xf32> to vector<1xf32>
diff --git a/mlir/test/IR/array-of-attr.mlir b/mlir/test/IR/array-of-attr.mlir
index 2c7b5009f74a2..96f7207170394 100644
--- a/mlir/test/IR/array-of-attr.mlir
+++ b/mlir/test/IR/array-of-attr.mlir
@@ -14,5 +14,5 @@ test.array_of_attr_op
test.array_of_attr_op a = [], b = [], c = []
// CHECK: "test.test_array_float"
-// CHECK-SAME: 1.000000e+00 : f32, 1.000000e+00, 0x7FF0000000000000 : f64
+// CHECK-SAME: 1.000000e+00 : f32, 1.000000e+00, +inf : f64
"test.test_array_float"() {test.float_arr = [1.0 : f32, 1.0 : f64, 0x7FF0000000000000 : f64]} : () -> ()
diff --git a/mlir/test/IR/custom-float-attr-roundtrip.mlir b/mlir/test/IR/custom-float-attr-roundtrip.mlir
index a8da89ba7372d..5cf82f493a7f8 100644
--- a/mlir/test/IR/custom-float-attr-roundtrip.mlir
+++ b/mlir/test/IR/custom-float-attr-roundtrip.mlir
@@ -8,11 +8,11 @@ func.func @test_enum_attr_roundtrip() -> () {
"test.op"() {attr = #test.custom_float<"double" : 2.>} : () -> ()
// CHECK: attr = #test.custom_float<"fp80" : 2.000000e+00>
"test.op"() {attr = #test.custom_float<"fp80" : 2.>} : () -> ()
- // CHECK: attr = #test.custom_float<"float" : 0x7FC00000>
+ // CHECK: attr = #test.custom_float<"float" : +qnan>
"test.op"() {attr = #test.custom_float<"float" : 0x7FC00000>} : () -> ()
- // CHECK: attr = #test.custom_float<"double" : 0x7FF0000001000000>
+ // CHECK: attr = #test.custom_float<"double" : +snan(0x1000000)>
"test.op"() {attr = #test.custom_float<"double" : 0x7FF0000001000000>} : () -> ()
- // CHECK: attr = #test.custom_float<"fp80" : 0x7FFFC000000000100000>
+ // CHECK: attr = #test.custom_float<"fp80" : +nan(0x100000)>
"test.op"() {attr = #test.custom_float<"fp80" : 0x7FFFC000000000100000>} : () -> ()
return
}
diff --git a/mlir/test/IR/float-literals-hex.mlir b/mlir/test/IR/float-literals-hex.mlir
new file mode 100644
index 0000000000000..601ea62e7ad6e
--- /dev/null
+++ b/mlir/test/IR/float-literals-hex.mlir
@@ -0,0 +1,50 @@
+// RUN: mlir-opt %s --mlir-print-float-special-literals-as-hex | FileCheck %s --check-prefix=HEX
+// RUN: mlir-opt %s --mlir-print-float-special-literals-as-hex | mlir-opt | FileCheck %s --check-prefix=ROUNDTRIP
+
+// The --mlir-print-float-special-literals-as-hex flag prints infinities and NaNs as a
+// hexadecimal bit pattern (the legacy form). The parser still accepts both the
+// hex and the human-readable spellings, so the hex output round-trips back to
+// the human-readable form.
+
+// HEX-LABEL: @infinities
+// ROUNDTRIP-LABEL: @infinities
+func.func @infinities() {
+ // HEX: arith.constant 0x7F800000 : f32
+ // ROUNDTRIP: arith.constant +inf : f32
+ %0 = arith.constant +inf : f32
+ // HEX: arith.constant 0xFF800000 : f32
+ // ROUNDTRIP: arith.constant -inf : f32
+ %1 = arith.constant -inf : f32
+ // HEX: arith.constant 0x7FF0000000000000 : f64
+ // ROUNDTRIP: arith.constant +inf : f64
+ %2 = arith.constant +inf : f64
+ return
+}
+
+// HEX-LABEL: @nans
+// ROUNDTRIP-LABEL: @nans
+func.func @nans() {
+ // HEX: arith.constant 0x7FC00000 : f32
+ // ROUNDTRIP: arith.constant +qnan : f32
+ %0 = arith.constant +qnan : f32
+ // HEX: arith.constant 0xFFF8000000000000 : f64
+ // ROUNDTRIP: arith.constant -qnan : f64
+ %1 = arith.constant -qnan : f64
+ // HEX: arith.constant 0x7FC00001 : f32
+ // ROUNDTRIP: arith.constant +nan(0x1) : f32
+ %2 = arith.constant +nan(0x1) : f32
+ // HEX: arith.constant 0x7FF0000000000001 : f64
+ // ROUNDTRIP: arith.constant +snan(0x1) : f64
+ %3 = arith.constant +snan(0x1) : f64
+ return
+}
+
+// Special values also print as hex inside dense elements attributes.
+// HEX-LABEL: @special_values_in_elements
+// ROUNDTRIP-LABEL: @special_values_in_elements
+func.func @special_values_in_elements() {
+ // HEX: dense<[0x7F800000, 0xFF800000, 0x7FC00000]> : tensor<3xf32>
+ // ROUNDTRIP: dense<[+inf, -inf, +qnan]> : tensor<3xf32>
+ %0 = arith.constant dense<[+inf, -inf, +qnan]> : tensor<3xf32>
+ return
+}
diff --git a/mlir/test/IR/float-literals.mlir b/mlir/test/IR/float-literals.mlir
new file mode 100644
index 0000000000000..d26ad638eeb13
--- /dev/null
+++ b/mlir/test/IR/float-literals.mlir
@@ -0,0 +1,117 @@
+// RUN: mlir-opt %s | mlir-opt | FileCheck %s
+
+// Human-readable floating point special values and C-style hexadecimal floats,
+// as accepted by the parser and produced by the printer.
+
+// CHECK-LABEL: @infinities
+func.func @infinities() {
+ // CHECK: arith.constant +inf : f32
+ %0 = arith.constant +inf : f32
+ // CHECK: arith.constant -inf : f32
+ %1 = arith.constant -inf : f32
+ // CHECK: arith.constant +inf : f64
+ %2 = arith.constant +inf : f64
+ // CHECK: arith.constant -inf : f16
+ %3 = arith.constant -inf : f16
+ // CHECK: arith.constant +inf : bf16
+ %4 = arith.constant +inf : bf16
+ return
+}
+
+// CHECK-LABEL: @quiet_nans
+func.func @quiet_nans() {
+ // CHECK: arith.constant +qnan : f32
+ %0 = arith.constant +qnan : f32
+ // CHECK: arith.constant -qnan : f64
+ %1 = arith.constant -qnan : f64
+ // CHECK: arith.constant +qnan : f16
+ %2 = arith.constant +qnan : f16
+ // CHECK: arith.constant -qnan : bf16
+ %3 = arith.constant -qnan : bf16
+ return
+}
+
+// CHECK-LABEL: @nan_payloads
+func.func @nan_payloads() {
+ // CHECK: arith.constant +nan(0x1) : f32
+ %0 = arith.constant +nan(0x1) : f32
+ // CHECK: arith.constant -nan(0x3FFFFF) : f32
+ %1 = arith.constant -nan(0x3FFFFF) : f32
+ // CHECK: arith.constant +snan(0x1) : f64
+ %2 = arith.constant +snan(0x1) : f64
+ // CHECK: arith.constant -snan(0x1000000) : f64
+ %3 = arith.constant -snan(0x1000000) : f64
+ return
+}
+
+// CHECK-LABEL: @hex_floats
+func.func @hex_floats() {
+ // 0x1.8p3 == 1.5 * 2^3 == 12.0; the exponent sign and 'p'/'P' case may vary.
+ // CHECK: arith.constant 1.200000e+01 : f64
+ %0 = arith.constant 0x1.8p3 : f64
+ // CHECK: arith.constant 1.200000e+01 : f64
+ %1 = arith.constant 0x1.8p+3 : f64
+ // CHECK: arith.constant 1.200000e+01 : f64
+ %2 = arith.constant 0x1.8P3 : f64
+ // CHECK: arith.constant -1.200000e+01 : f64
+ %3 = arith.constant -0x1.8p3 : f64
+ // 0x1.8p-3 == 1.5 * 2^-3 == 0.1875
+ // CHECK: arith.constant 1.875000e-01 : f64
+ %4 = arith.constant 0x1.8p-3 : f64
+ // No fractional part.
+ // CHECK: arith.constant 1.600000e+01 : f32
+ %5 = arith.constant 0x1p4 : f32
+ // CHECK: arith.constant 0.000000e+00 : f32
+ %6 = arith.constant 0x0p0 : f32
+ // Built directly in the (wider than double) target semantics.
+ // CHECK: arith.constant 1.200000e+01 : f80
+ %7 = arith.constant 0x1.8p3 : f80
+ // CHECK: arith.constant 1.200000e+01 : f128
+ %8 = arith.constant 0x1.8p3 : f128
+ // A value that needs full precision to round-trip.
+ // CHECK: arith.constant 3.1415926535897931 : f64
+ %9 = arith.constant 0x1.921fb54442d18p1 : f64
+ return
+}
+
+// CHECK-LABEL: @special_values_in_elements
+func.func @special_values_in_elements() {
+ // CHECK: dense<[+inf, -inf, +qnan]> : tensor<3xf32>
+ %0 = arith.constant dense<[+inf, -inf, +qnan]> : tensor<3xf32>
+ // A splat built from a single special value.
+ // CHECK: dense<-inf> : tensor<4xf64>
+ %1 = arith.constant dense<-inf> : tensor<4xf64>
+ return
+}
+
+// Low-precision and other builtin float types on the special-value path.
+// CHECK-LABEL: @low_precision_and_other_types
+func.func @low_precision_and_other_types() {
+ // f8E8M0FNU has zero mantissa bits: its NaN prints as the canonical qnan.
+ // CHECK: arith.constant +qnan : f8E8M0FNU
+ %0 = arith.constant +qnan : f8E8M0FNU
+ // Payload wider than the mantissa is masked (f8E5M2 keeps 1 payload bit).
+ // CHECK: arith.constant +nan(0x1) : f8E5M2
+ %1 = arith.constant +nan(0x7) : f8E5M2
+ // FNUZ formats have a single NaN encoding; a signaling request collapses to it.
+ // CHECK: arith.constant -nan(0x0) : f8E4M3FNUZ
+ %2 = arith.constant +snan(0x1) : f8E4M3FNUZ
+ // CHECK: arith.constant +inf : tf32
+ %3 = arith.constant +inf : tf32
+ return
+}
+
+// Payload spelling normalizations and overflow tolerance.
+// CHECK-LABEL: @nan_payload_and_overflow
+func.func @nan_payload_and_overflow() {
+ // A zero payload normalizes to the canonical quiet NaN.
+ // CHECK: arith.constant +qnan : f32
+ %0 = arith.constant +nan(0x0) : f32
+ // An unprefixed payload is decimal; it prints back as hex.
+ // CHECK: arith.constant +nan(0xA) : f32
+ %1 = arith.constant +nan(10) : f32
+ // Decimal overflow saturates to infinity rather than erroring.
+ // CHECK: arith.constant +inf : f16
+ %2 = arith.constant 1.0e40 : f16
+ return
+}
diff --git a/mlir/test/IR/invalid-builtin-attributes.mlir b/mlir/test/IR/invalid-builtin-attributes.mlir
index 0d00b3141fbc6..03a25f43f09b7 100644
--- a/mlir/test/IR/invalid-builtin-attributes.mlir
+++ b/mlir/test/IR/invalid-builtin-attributes.mlir
@@ -52,6 +52,16 @@ func.func @elementsattr_floattype2() -> () {
// -----
+// The diagnostic must point at the float literal, not the following token
+// (the `}` is on the next line, exposing a stale location).
+func.func @float_attr_non_float_type() -> () {
+ // expected-error at below {{floating point value not valid for specified type}}
+ "foo"(){bar = 1.0 : i32
+ } : () -> ()
+}
+
+// -----
+
func.func @elementsattr_toolarge1() -> () {
"foo"(){bar = dense<[777]> : tensor<1xi8>} : () -> () // expected-error {{integer constant out of range}}
}
@@ -675,3 +685,88 @@ func.func @expect_to_parse_literal() {
%0 = arith.constant dense<[23]> : tensor<1x!unknown<>>
return
}
+
+// -----
+
+func.func @hex_float_without_exponent() {
+ // expected-error at below {{expected binary exponent in hexadecimal floating point literal}}
+ %0 = arith.constant 0x1.8 : f64
+ return
+}
+
+// -----
+
+func.func @hex_float_missing_exponent_digits() {
+ // expected-error at below {{expected binary exponent in hexadecimal floating point literal}}
+ %0 = arith.constant 0x1.0p : f64
+ return
+}
+
+// -----
+
+func.func @unclosed_nan_literal() {
+ // expected-error at below {{expected ')' in NaN literal}}
+ %0 = arith.constant +nan(0x1 : f32
+ return
+}
+
+// -----
+
+func.func @invalid_nan_payload() {
+ // expected-error at below {{invalid floating point literal}}
+ %0 = arith.constant +nan(0xZZ) : f32
+ return
+}
+
+// -----
+
+func.func @inf_on_integer_type() {
+ // expected-error at below {{floating point value not valid for specified type}}
+ %0 = arith.constant +inf : i32
+ return
+}
+
+// -----
+
+func.func @doubly_signed_inf() {
+ // Doubly-signed literal: a '-' token before an already-signed inf/NaN.
+ // expected-error at below {{floating point literal has more than one sign}}
+ %0 = arith.constant -+inf : f64
+ return
+}
+
+// -----
+
+func.func @inf_on_type_without_inf() {
+ // f4E2M1FN has no Inf encoding: reject, do not crash APFloat.
+ // expected-error at below {{floating point type does not support infinity}}
+ %0 = arith.constant +inf : f4E2M1FN
+ return
+}
+
+// -----
+
+func.func @nan_on_type_without_nan() {
+ // f6E2M3FN has no NaN encoding.
+ // expected-error at below {{floating point type does not support NaN}}
+ %0 = arith.constant +qnan : f6E2M3FN
+ return
+}
+
+// -----
+
+func.func @inf_on_nan_only_type() {
+ // f8E4M3FN has NaN but no Inf.
+ // expected-error at below {{floating point type does not support infinity}}
+ %0 = arith.constant +inf : f8E4M3FN
+ return
+}
+
+// -----
+
+func.func @negative_on_unsigned_type() {
+ // f8E8M0FNU is unsigned: reject negatives, do not crash the printer.
+ // expected-error at below {{floating point type does not support negative values}}
+ %0 = arith.constant -1.0 : f8E8M0FNU
+ return
+}
diff --git a/mlir/test/IR/parser.mlir b/mlir/test/IR/parser.mlir
index e10dbf36e2797..1375c4edb11d0 100644
--- a/mlir/test/IR/parser.mlir
+++ b/mlir/test/IR/parser.mlir
@@ -1022,18 +1022,18 @@ func.func @dialect_attribute_with_type() {
// CHECK-LABEL: @f16_special_values
func.func @f16_special_values() {
// F16 NaNs.
- // CHECK: arith.constant 0x7C01 : f16
+ // CHECK: arith.constant +snan(0x1) : f16
%0 = arith.constant 0x7C01 : f16
- // CHECK: arith.constant 0x7FFF : f16
+ // CHECK: arith.constant +nan(0x1FF) : f16
%1 = arith.constant 0x7FFF : f16
- // CHECK: arith.constant 0xFFFF : f16
+ // CHECK: arith.constant -nan(0x1FF) : f16
%2 = arith.constant 0xFFFF : f16
// F16 positive infinity.
- // CHECK: arith.constant 0x7C00 : f16
+ // CHECK: arith.constant +inf : f16
%3 = arith.constant 0x7C00 : f16
// F16 negative infinity.
- // CHECK: arith.constant 0xFC00 : f16
+ // CHECK: arith.constant -inf : f16
%4 = arith.constant 0xFC00 : f16
return
@@ -1042,22 +1042,22 @@ func.func @f16_special_values() {
// CHECK-LABEL: @f32_special_values
func.func @f32_special_values() {
// F32 signaling NaNs.
- // CHECK: arith.constant 0x7F800001 : f32
+ // CHECK: arith.constant +snan(0x1) : f32
%0 = arith.constant 0x7F800001 : f32
- // CHECK: arith.constant 0x7FBFFFFF : f32
+ // CHECK: arith.constant +snan(0x3FFFFF) : f32
%1 = arith.constant 0x7FBFFFFF : f32
// F32 quiet NaNs.
- // CHECK: arith.constant 0x7FC00000 : f32
+ // CHECK: arith.constant +qnan : f32
%2 = arith.constant 0x7FC00000 : f32
- // CHECK: arith.constant 0xFFFFFFFF : f32
+ // CHECK: arith.constant -nan(0x3FFFFF) : f32
%3 = arith.constant 0xFFFFFFFF : f32
// F32 positive infinity.
- // CHECK: arith.constant 0x7F800000 : f32
+ // CHECK: arith.constant +inf : f32
%4 = arith.constant 0x7F800000 : f32
// F32 negative infinity.
- // CHECK: arith.constant 0xFF800000 : f32
+ // CHECK: arith.constant -inf : f32
%5 = arith.constant 0xFF800000 : f32
return
@@ -1066,22 +1066,22 @@ func.func @f32_special_values() {
// CHECK-LABEL: @f64_special_values
func.func @f64_special_values() {
// F64 signaling NaNs.
- // CHECK: arith.constant 0x7FF0000000000001 : f64
+ // CHECK: arith.constant +snan(0x1) : f64
%0 = arith.constant 0x7FF0000000000001 : f64
- // CHECK: arith.constant 0x7FF8000000000000 : f64
+ // CHECK: arith.constant +qnan : f64
%1 = arith.constant 0x7FF8000000000000 : f64
// F64 quiet NaNs.
- // CHECK: arith.constant 0x7FF0000001000000 : f64
+ // CHECK: arith.constant +snan(0x1000000) : f64
%2 = arith.constant 0x7FF0000001000000 : f64
- // CHECK: arith.constant 0xFFF0000001000000 : f64
+ // CHECK: arith.constant -snan(0x1000000) : f64
%3 = arith.constant 0xFFF0000001000000 : f64
// F64 positive infinity.
- // CHECK: arith.constant 0x7FF0000000000000 : f64
+ // CHECK: arith.constant +inf : f64
%4 = arith.constant 0x7FF0000000000000 : f64
// F64 negative infinity.
- // CHECK: arith.constant 0xFFF0000000000000 : f64
+ // CHECK: arith.constant -inf : f64
%5 = arith.constant 0xFFF0000000000000 : f64
// Check that values that can't be represented with the default format, use
@@ -1095,22 +1095,22 @@ func.func @f64_special_values() {
// CHECK-LABEL: @bfloat16_special_values
func.func @bfloat16_special_values() {
// bfloat16 signaling NaNs.
- // CHECK: arith.constant 0x7F81 : bf16
+ // CHECK: arith.constant +snan(0x1) : bf16
%0 = arith.constant 0x7F81 : bf16
- // CHECK: arith.constant 0xFF81 : bf16
+ // CHECK: arith.constant -snan(0x1) : bf16
%1 = arith.constant 0xFF81 : bf16
// bfloat16 quiet NaNs.
- // CHECK: arith.constant 0x7FC0 : bf16
+ // CHECK: arith.constant +qnan : bf16
%2 = arith.constant 0x7FC0 : bf16
- // CHECK: arith.constant 0xFFC0 : bf16
+ // CHECK: arith.constant -qnan : bf16
%3 = arith.constant 0xFFC0 : bf16
// bfloat16 positive infinity.
- // CHECK: arith.constant 0x7F80 : bf16
+ // CHECK: arith.constant +inf : bf16
%4 = arith.constant 0x7F80 : bf16
// bfloat16 negative infinity.
- // CHECK: arith.constant 0xFF80 : bf16
+ // CHECK: arith.constant -inf : bf16
%5 = arith.constant 0xFF80 : bf16
return
@@ -1119,22 +1119,22 @@ func.func @bfloat16_special_values() {
// CHECK-LABEL: @f80_special_values
func.func @f80_special_values() {
// F80 signaling NaNs.
- // CHECK: arith.constant 0x7FFFE000000000000001 : f80
+ // CHECK: arith.constant +nan(0x2000000000000001) : f80
%0 = arith.constant 0x7FFFE000000000000001 : f80
- // CHECK: arith.constant 0x7FFFB000000000000011 : f80
+ // CHECK: arith.constant +snan(0x3000000000000011) : f80
%1 = arith.constant 0x7FFFB000000000000011 : f80
// F80 quiet NaNs.
- // CHECK: arith.constant 0x7FFFC000000000100000 : f80
+ // CHECK: arith.constant +nan(0x100000) : f80
%2 = arith.constant 0x7FFFC000000000100000 : f80
- // CHECK: arith.constant 0x7FFFE000000001000000 : f80
+ // CHECK: arith.constant +nan(0x2000000001000000) : f80
%3 = arith.constant 0x7FFFE000000001000000 : f80
// F80 positive infinity.
- // CHECK: arith.constant 0x7FFF8000000000000000 : f80
+ // CHECK: arith.constant +inf : f80
%4 = arith.constant 0x7FFF8000000000000000 : f80
// F80 negative infinity.
- // CHECK: arith.constant 0xFFFF8000000000000000 : f80
+ // CHECK: arith.constant -inf : f80
%5 = arith.constant 0xFFFF8000000000000000 : f80
return
@@ -1152,14 +1152,14 @@ func.func @f32_potential_precision_loss() {
// CHECK-LABEL: @special_float_values_in_tensors
func.func @special_float_values_in_tensors() {
- // CHECK: dense<0xFFFFFFFF> : tensor<4x4xf32>
+ // CHECK: dense<-nan(0x3FFFFF)> : tensor<4x4xf32>
"foo"(){bar = dense<0xFFFFFFFF> : tensor<4x4xf32>} : () -> ()
- // CHECK: dense<[{{\[}}0xFFFFFFFF, 0x7F800000], [0x7FBFFFFF, 0x7F800001]]> : tensor<2x2xf32>
+ // CHECK: dense<[{{\[}}-nan(0x3FFFFF), +inf], [+snan(0x3FFFFF), +snan(0x1)]]> : tensor<2x2xf32>
"foo"(){bar = dense<[[0xFFFFFFFF, 0x7F800000], [0x7FBFFFFF, 0x7F800001]]> : tensor<2x2xf32>} : () -> ()
- // CHECK: dense<[0xFFFFFFFF, 0.000000e+00]> : tensor<2xf32>
+ // CHECK: dense<[-nan(0x3FFFFF), 0.000000e+00]> : tensor<2xf32>
"foo"(){bar = dense<[0xFFFFFFFF, 0.0]> : tensor<2xf32>} : () -> ()
- // CHECK: sparse<[{{\[}}1, 1, 0], [0, 1, 1]], [0xFFFFFFFF, 0x7F800001]>
+ // CHECK: sparse<[{{\[}}1, 1, 0], [0, 1, 1]], [-nan(0x3FFFFF), +snan(0x1)]>
"foo"(){bar = sparse<[[1,1,0],[0,1,1]], [0xFFFFFFFF, 0x7F800001]> : tensor<2x2x2xf32>} : () -> ()
}
More information about the flang-commits
mailing list