[Mlir-commits] [mlir] [mlir][arith] Fix issue where setOperand is called inside the fold fu… (PR #204506)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Jun 17 20:54:32 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: donald chen (cxy-1993)
<details>
<summary>Changes</summary>
…nction
---
Full diff: https://github.com/llvm/llvm-project/pull/204506.diff
1 Files Affected:
- (modified) mlir/lib/Dialect/Arith/IR/ArithOps.cpp (+62-22)
``````````diff
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index dc3887c3e0b0e..92f4e519f51a4 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -1735,26 +1735,12 @@ OpFoldResult arith::TruncIOp::fold(FoldAdaptor adaptor) {
Value src = getOperand().getDefiningOp()->getOperand(0);
Type srcType = getElementTypeOrSelf(src.getType());
Type dstType = getElementTypeOrSelf(getType());
- // trunci(zexti(a)) -> trunci(a)
- // trunci(sexti(a)) -> trunci(a)
- if (llvm::cast<IntegerType>(srcType).getWidth() >
- llvm::cast<IntegerType>(dstType).getWidth()) {
- setOperand(src);
- return getResult();
- }
-
// trunci(zexti(a)) -> a
// trunci(sexti(a)) -> a
if (srcType == dstType)
return src;
}
- // trunci(trunci(a)) -> trunci(a))
- if (matchPattern(getOperand(), m_Op<arith::TruncIOp>())) {
- setOperand(getOperand().getDefiningOp()->getOperand(0));
- return getResult();
- }
-
Type resType = getElementTypeOrSelf(getType());
unsigned bitWidth = llvm::cast<IntegerType>(resType).getWidth();
return constFoldCastOp<IntegerAttr, IntegerAttr>(
@@ -1764,6 +1750,38 @@ OpFoldResult arith::TruncIOp::fold(FoldAdaptor adaptor) {
});
}
+struct TruncIOfExtI : public OpRewritePattern<arith::TruncIOp> {
+ using OpRewritePattern<arith::TruncIOp>::OpRewritePattern;
+
+ LogicalResult matchAndRewrite(arith::TruncIOp op,
+ PatternRewriter &rewriter) const override {
+ if (matchPattern(op.getOperand(), m_Op<arith::ExtUIOp>()) ||
+ matchPattern(op.getOperand(), m_Op<arith::ExtSIOp>())) {
+ Value src = op.getOperand().getDefiningOp()->getOperand(0);
+ Type srcType = getElementTypeOrSelf(src.getType());
+ Type dstType = getElementTypeOrSelf(op.getType());
+ // trunci(zexti(a)) -> trunci(a)
+ // trunci(sexti(a)) -> trunci(a)
+ if (llvm::cast<IntegerType>(srcType).getWidth() >
+ llvm::cast<IntegerType>(dstType).getWidth()) {
+ rewriter.modifyOpInPlace(op, [&](){
+ op.setOperand(src);
+ });
+ return success();
+ }
+ }
+
+ // trunci(trunci(a)) -> trunci(a))
+ if (matchPattern(op.getOperand(), m_Op<arith::TruncIOp>())) {
+ rewriter.modifyOpInPlace(op, [&](){
+ op.setOperand(op.getOperand().getDefiningOp()->getOperand(0));
+ });
+ return success();
+ }
+ return failure();
+ }
+};
+
bool arith::TruncIOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
return checkWidthChangeCast<std::less, IntegerType>(inputs, outputs);
}
@@ -1771,7 +1789,7 @@ bool arith::TruncIOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
void arith::TruncIOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
MLIRContext *context) {
patterns
- .add<TruncIExtSIToExtSI, TruncIExtUIToExtUI, TruncIShrSIToTrunciShrUI>(
+ .add<TruncIExtSIToExtSI, TruncIExtUIToExtUI, TruncIShrSIToTrunciShrUI, TruncIOfExtI>(
context);
}
@@ -1796,12 +1814,6 @@ OpFoldResult arith::TruncFOp::fold(FoldAdaptor adaptor) {
if (llvm::APFloatBase::isRepresentableBy(
srcType.getFloatSemantics(),
intermediateType.getFloatSemantics())) {
- // truncf(extf(a)) -> truncf(a)
- if (srcType.getWidth() > resElemType.getWidth()) {
- setOperand(src);
- return getResult();
- }
-
// truncf(extf(a)) -> a
if (srcType == resElemType)
return src;
@@ -1824,9 +1836,37 @@ OpFoldResult arith::TruncFOp::fold(FoldAdaptor adaptor) {
});
}
+struct TruncFOfExtF : public OpRewritePattern<arith::TruncFOp> {
+ using OpRewritePattern<arith::TruncFOp>::OpRewritePattern;
+
+ LogicalResult matchAndRewrite(arith::TruncFOp op,
+ PatternRewriter &rewriter) const override {
+ auto resElemType = cast<FloatType>(getElementTypeOrSelf(op.getType()));
+ if (auto extOp = op.getOperand().getDefiningOp<arith::ExtFOp>()) {
+ Value src = extOp.getIn();
+ auto srcType = cast<FloatType>(getElementTypeOrSelf(src.getType()));
+ auto intermediateType =
+ cast<FloatType>(getElementTypeOrSelf(extOp.getType()));
+ // Check if the srcType is representable in the intermediateType.
+ if (llvm::APFloatBase::isRepresentableBy(
+ srcType.getFloatSemantics(),
+ intermediateType.getFloatSemantics())) {
+ // truncf(extf(a)) -> truncf(a)
+ if (srcType.getWidth() > resElemType.getWidth()) {
+ rewriter.modifyOpInPlace(op, [&](){
+ op.setOperand(src);
+ });
+ return success();
+ }
+ }
+ }
+ return failure();
+ }
+};
+
void arith::TruncFOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
MLIRContext *context) {
- patterns.add<TruncFSIToFPToSIToFP, TruncFUIToFPToUIToFP>(context);
+ patterns.add<TruncFSIToFPToSIToFP, TruncFUIToFPToUIToFP, TruncFOfExtF>(context);
}
bool arith::TruncFOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/204506
More information about the Mlir-commits
mailing list