[Mlir-commits] [mlir] [MLIR][Arith] Add canonicalization rules for int-to-float of integer extension (PR #185386)
Adam Paszke
llvmlistbot at llvm.org
Tue Mar 10 02:57:42 PDT 2026
https://github.com/apaszke updated https://github.com/llvm/llvm-project/pull/185386
>From 7ea6f858bff916c2060166a668443aa8339cbd08 Mon Sep 17 00:00:00 2001
From: Adam Paszke <apaszke at google.com>
Date: Mon, 9 Mar 2026 10:13:50 +0000
Subject: [PATCH] [MLIR][Arith] Add canonicalization rules for int-to-float of
integer extension
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Three patterns are valid but were missing:
1. `sitofp(extsi(x)) → sitofp(x)`:
extsi preserves the sign and value, so it represents the
same signed integer as x.
2. `uitofp(extui(x)) → uitofp(x)`:
same reasoning as above, but for unsigned extension.
3. sitofp(extui(x)) → uitofp(x)
extui zero-extends, so the extended value is always non-negative.
For non-negative integers, sitofp and uitofp produce the same result,
meaning we could replace the left expression by `uitofp(extui(x))`. At
this point rule 2. above can be used to simplify further to `uitofp(x)`.
---
.../include/mlir/Dialect/Arith/IR/ArithOps.td | 2 +
.../Dialect/Arith/IR/ArithCanonicalization.td | 23 ++++++++++++
mlir/lib/Dialect/Arith/IR/ArithOps.cpp | 10 +++++
mlir/test/Dialect/Arith/canonicalize.mlir | 37 ++++++++++++++++++-
4 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
index ab85574069687..9f7bec97da6c4 100644
--- a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
+++ b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
@@ -1531,6 +1531,7 @@ def Arith_UIToFPOp :
$in (`nneg` $nonNeg^)? attr-dict `:` type($in) `to` type($out)
}];
let hasFolder = 1;
+ let hasCanonicalizer = 1;
}
//===----------------------------------------------------------------------===//
@@ -1546,6 +1547,7 @@ def Arith_SIToFPOp : Arith_IToFCastOp<"sitofp"> {
elementwise.
}];
let hasFolder = 1;
+ let hasCanonicalizer = 1;
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td b/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td
index f26af4816ce85..a3d77441d2942 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td
+++ b/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td
@@ -428,6 +428,29 @@ def TruncFUIToFPToUIToFP :
(Arith_UIToFPOp $x, $nneg),
[(Constraint<CPred<"$0 == nullptr">, "default rounding mode"> $rmf)]>;
+//===----------------------------------------------------------------------===//
+// SIToFPOp
+//===----------------------------------------------------------------------===//
+
+// sitofp(extsi(x)) -> sitofp(x)
+def SIToFPOfExtSI :
+ Pat<(Arith_SIToFPOp (Arith_ExtSIOp $x)),
+ (Arith_SIToFPOp $x)>;
+
+// sitofp(extui(x)) -> uitofp(x)
+def SIToFPOfExtUI :
+ Pat<(Arith_SIToFPOp (Arith_ExtUIOp $x, $nneg)),
+ (Arith_UIToFPOp $x, $nneg)>;
+
+//===----------------------------------------------------------------------===//
+// UIToFPOp
+//===----------------------------------------------------------------------===//
+
+// uitofp(extui(x)) -> uitofp(x)
+def UIToFPOfExtUI :
+ Pat<(Arith_UIToFPOp (Arith_ExtUIOp $x, $nneg1), $nneg2),
+ (Arith_UIToFPOp $x, $nneg1)>;
+
//===----------------------------------------------------------------------===//
// MulFOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index b99f77fdc8b30..6c68cb4eea452 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -1756,6 +1756,11 @@ OpFoldResult arith::UIToFPOp::fold(FoldAdaptor adaptor) {
});
}
+void arith::UIToFPOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+ MLIRContext *context) {
+ patterns.add<UIToFPOfExtUI>(context);
+}
+
//===----------------------------------------------------------------------===//
// SIToFPOp
//===----------------------------------------------------------------------===//
@@ -1778,6 +1783,11 @@ OpFoldResult arith::SIToFPOp::fold(FoldAdaptor adaptor) {
});
}
+void arith::SIToFPOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+ MLIRContext *context) {
+ patterns.add<SIToFPOfExtSI, SIToFPOfExtUI>(context);
+}
+
//===----------------------------------------------------------------------===//
// FPToUIOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/Arith/canonicalize.mlir b/mlir/test/Dialect/Arith/canonicalize.mlir
index 326afcae696cc..7ba22a17a76d1 100644
--- a/mlir/test/Dialect/Arith/canonicalize.mlir
+++ b/mlir/test/Dialect/Arith/canonicalize.mlir
@@ -939,7 +939,42 @@ func.func @truncUitofp_nneg(%arg0: i32) -> f32 {
return %trunc : f32
}
-// TODO: We should also add a test for not folding arith.extf on information loss.
+// CHECK-LABEL: @sitofpExtsi
+// CHECK: %[[SITOFP:.*]] = arith.sitofp %[[ARG0:.*]] : i8 to bf16
+// CHECK: return %[[SITOFP]]
+func.func @sitofpExtsi(%arg0: i8) -> bf16 {
+ %extsi = arith.extsi %arg0 : i8 to i32
+ %sitofp = arith.sitofp %extsi : i32 to bf16
+ return %sitofp : bf16
+}
+
+// CHECK-LABEL: @sitofpExtui
+// CHECK: %[[UITOFP:.*]] = arith.uitofp %[[ARG0:.*]] : i4 to bf16
+// CHECK-NOT: sitofp
+// CHECK: return %[[UITOFP]]
+func.func @sitofpExtui(%arg0: i4) -> bf16 {
+ %extui = arith.extui %arg0 : i4 to i8
+ %sitofp = arith.sitofp %extui : i8 to bf16
+ return %sitofp : bf16
+}
+
+// CHECK-LABEL: @uitofpExtui
+// CHECK: %[[UITOFP:.*]] = arith.uitofp %[[ARG0:.*]] : i8 to bf16
+// CHECK: return %[[UITOFP]]
+func.func @uitofpExtui(%arg0: i8) -> bf16 {
+ %extui = arith.extui %arg0 : i8 to i32
+ %uitofp = arith.uitofp %extui : i32 to bf16
+ return %uitofp : bf16
+}
+
+// CHECK-LABEL: @sitofpExtui_nneg
+// CHECK: %[[UITOFP:.*]] = arith.uitofp %[[ARG0:.*]] nneg : i4 to bf16
+// CHECK: return %[[UITOFP]]
+func.func @sitofpExtui_nneg(%arg0: i4) -> bf16 {
+ %extui = arith.extui %arg0 nneg : i4 to i8
+ %sitofp = arith.sitofp %extui : i8 to bf16
+ return %sitofp : bf16
+}
// This may happen when extending f8E5M2FNUZ to f16.
// CHECK-LABEL: @truncConstant
More information about the Mlir-commits
mailing list