Skip to content

Commit c0e8eb9

Browse files
authored
[MLIR][Vector] Fix RewriteAlignedSubByteIntExt/Trunc producing invalid IR when source is already i8 (#188941)
When the conversion destination type is i8 (e.g., extsi i4->i8), RewriteAlignedSubByteIntExt was unconditionally creating a new ConversionOp with identical source and result types (vector<8xi8> -> vector<8xi8>), which is invalid IR. Similarly, RewriteAlignedSubByteIntTrunc was creating arith.trunci from vector<Nxi8> to vector<Nxi8> when the source was already i8. Fix by: - In RewriteAlignedSubByteIntExt: replace the op directly with subByteExt when it already has the destination type, instead of wrapping in a new conversion op. - In RewriteAlignedSubByteIntTrunc: skip the intermediate truncation to i8 when the source is already i8, passing srcValue directly to the i8->i4 rewrite logic. This matches the existing test expectations in vector-rewrite-subbyte-ext-and-trunci.mlir. Assisted-by: Claude Code Fix a failure present with MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS=ON.
1 parent 329432b commit c0e8eb9

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

mlir/lib/Dialect/Vector/Transforms/VectorEmulateNarrowType.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,9 +2163,14 @@ struct RewriteAlignedSubByteIntExt : OpRewritePattern<ConversionOpType> {
21632163
return failure();
21642164
}
21652165

2166-
// Finalize the rewrite.
2167-
rewriter.replaceOpWithNewOp<ConversionOpType>(
2168-
conversionOp, conversionOp.getType(), subByteExt);
2166+
// Finalize the rewrite. If subByteExt already has the destination type
2167+
// (e.g. extsi i4->i8 where the container is i8), replace directly without
2168+
// creating a new conversion op that would have identical src and dst types.
2169+
if (subByteExt.getType() == conversionOp.getType())
2170+
rewriter.replaceOp(conversionOp, subByteExt);
2171+
else
2172+
rewriter.replaceOpWithNewOp<ConversionOpType>(
2173+
conversionOp, conversionOp.getType(), subByteExt);
21692174
return success();
21702175
}
21712176
};
@@ -2213,11 +2218,13 @@ struct RewriteAlignedSubByteIntTrunc : OpRewritePattern<arith::TruncIOp> {
22132218
/*containerTy=*/rewriter.getI8Type(), truncOp)))
22142219
return failure();
22152220

2216-
// Create a new iX -> i8 truncation op.
2221+
// Create a new iX -> i8 truncation op, unless the source is already i8.
22172222
Location loc = truncOp.getLoc();
22182223
auto i8VecType = srcVecType.cloneWith(std::nullopt, rewriter.getI8Type());
22192224
Value i8TruncVal =
2220-
arith::TruncIOp::create(rewriter, loc, i8VecType, srcValue);
2225+
srcVecType == i8VecType
2226+
? srcValue
2227+
: arith::TruncIOp::create(rewriter, loc, i8VecType, srcValue);
22212228

22222229
// Rewrite the i8 -> i4 truncation part.
22232230
Value subByteTrunc = rewriteI8ToI4Trunc(rewriter, loc, i8TruncVal);

0 commit comments

Comments
 (0)