[Mlir-commits] [mlir] [mlir][tosa]: Add Binary Shape Ops folders (PR #178877)
Luke Hutton
llvmlistbot at llvm.org
Fri Jan 30 06:38:43 PST 2026
================
@@ -1018,6 +1018,104 @@ struct FoldSubAdaptor {
}
};
+struct MulFoldAdaptor {
+ static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
+ const bool isUnsigned) {
+
+ const unsigned originalWidth = lhs.getBitWidth();
+
+ // Check same type
+ if (lhs.getBitWidth() != rhs.getBitWidth()) {
+ return failure();
+ }
+
+ // If either is `0`
+ if (lhs == 0 || rhs == 0)
+ return APInt::getZero(originalWidth);
+
+ bool overflow = false;
+ APInt const result =
+ isUnsigned ? lhs.umul_ov(rhs, overflow) : lhs.smul_ov(rhs, overflow);
+
+ if (overflow)
+ return failure();
+
+ return result.trunc(originalWidth);
+ }
+
+ static FailureOr<APFloat> fold(const APFloat &lhs, const APFloat &rhs) {
+ return lhs * rhs;
+ }
+};
+
+static bool signsDiffer(const APInt &a, const APInt &b) {
+ return a.isNegative() != b.isNegative();
+}
+
+template <bool Ceil>
+struct DivFoldAdaptor {
+ static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
+ bool isUnsigned) {
+ if (lhs.getBitWidth() != rhs.getBitWidth())
+ return failure();
+ if (rhs.isZero())
+ return failure();
+
+ if (isUnsigned) {
+ APInt q{};
+ APInt r{};
+ APInt::udivrem(lhs, rhs, q, r);
+ if (!r.isZero() && Ceil) {
+ return q + 1;
+ }
+ return q;
+ }
+
+ // Signed: start from trunc-toward-zero, then adjust to ceil.
+ bool overflow{false};
+ APInt const q = lhs.sdiv_ov(rhs, overflow);
+ if (overflow)
+ return failure();
+ APInt const r = lhs.srem(rhs);
+
+ if (Ceil && !r.isZero() && !signsDiffer(lhs, rhs)) {
+ // Same sign => exact quotient is positive; trunc is below ceil =>
+ // increment q.
+ return q + 1;
+ }
+ return q;
+ }
+
+ static FailureOr<APFloat> fold(const APFloat &lhs, const APFloat &rhs) {
+ return lhs / rhs;
+ }
+};
+
+struct ModFoldAdaptor {
+ static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
+ bool isUnsigned) {
+ if (lhs.getBitWidth() != rhs.getBitWidth())
+ return failure();
+ if (lhs.isNegative() || (!rhs.isStrictlyPositive()))
+ return failure();
+
+ if (isUnsigned) {
+ return lhs.urem(rhs);
+ }
+
+ return lhs.srem(rhs);
+ }
+
+ static FailureOr<APFloat> fold(const APFloat &lhs, const APFloat &rhs) {
+ auto t = lhs;
+ auto const r = t.mod(rhs);
+ if (llvm::APFloatBase::opStatus::opOK == r) {
+ return t;
+ }
+ return failure();
+ }
+};
+
struct FoldGreaterAdaptor {
----------------
lhutton1 wrote:
nit: If we're going the direction of `AddFoldAdaptor` rather than `FoldAddAdaptor` we should rename these as well (happy for it to be included in a follow-up patch rather than here)
https://github.com/llvm/llvm-project/pull/178877
More information about the Mlir-commits
mailing list