[Mlir-commits] [mlir] [mlir][wasm] Support for saturating FP truncations (PR #212709)

Max Graey llvmlistbot at llvm.org
Sat Aug 1 05:48:23 PDT 2026


================
@@ -1504,17 +1461,38 @@ BUILD_CONVERSION_OP(int32_t, int64_t, extendU, ExtendUI32Op)
 
 #undef BUILD_CONVERSION_OP
 
+parsed_inst_t parse(OpCode<WasmBinaryEncoding::OpCode::saturatedTruncate>,
+                    OpBuilder &builder,
+                    ExpressionParser::ExprParserProxy &parser,
+                    std::uint32_t subOpCode) {
+  if (subOpCode > 7)
+    return emitError(parser.getCurrentOpLoc())
+           << "invalid sub-opcode for trunc_saturate: " << subOpCode;
+  LDBG() << "Sub subOpcode for operation: " << subOpCode;
+  bool isDestUnsigned = subOpCode & 1;
+  bool isSrcF64 = subOpCode & 2;
+  bool isDestI64 = subOpCode & 4;
+  auto srcTypeBuilder =
+      isSrcF64 ? buildLiteralType<double> : buildLiteralType<float>;
+  auto destTypeBuilder =
+      isDestI64 ? buildLiteralType<uint64_t> : buildLiteralType<int32_t>;
+  auto srcOp = parser.popOperands(srcTypeBuilder(builder));
+  if (failed(srcOp))
+    return failure();
+  Operation *op =
+      isDestUnsigned
+          ? TruncSatUIOp::create(builder, parser.getCurrentOpLoc(),
+                                 destTypeBuilder(builder), srcOp->front())
+          : TruncSatSIOp::create(builder, parser.getCurrentOpLoc(),
+                                 destTypeBuilder(builder), srcOp->front());
+  LDBG() << "Built operation: " << op;
+  return {{op->getResult(0)}};
+}
----------------
MaxGraey wrote:

This code really challanging to read and understand. Much better to extract generic:
```cpp
template <typename OpT>
parsed_inst_t buildUnaryOp(OpBuilder &builder, Location loc, Type resultType,
                           Value operand);
```
and utilize it here.

Also whole code could be declated in much simpler way. Like:
```cpp
parse(OpCode<WasmBinaryEncoding::OpCode::saturatedTruncate>,
      OpBuilder &builder, ExpressionParser::ExprParserProxy &parser,
      std::uint32_t subOpcode) {
  auto loc = parser.getCurrentOpLoc();
  if (subOpcode > 7)
    return emitError(loc)
           << "invalid sub-opcode for trunc_sat: " << subOpcode;

  const bool isUnsigned = (subOpcode & 1) != 0;
  const bool srcIsF64 = (subOpcode & 2) != 0;
  const bool destIsI64 = (subOpcode & 4) != 0;

  Type srcType = srcIsF64 ? builder.getF64Type() : builder.getF32Type();
  Type destType = destIsI64 ? builder.getI64Type() : builder.getI32Type();

  LDBG() << "Sub subOpcode for operation: " << subOpcode;

  auto srcOperands = parser.popOperands(srcType);
  if (failed(srcOperands))
    return failure();

  Operation *op;
  if (isUnsigned) {
    op = TruncSatUIOp::create(builder, loc, destType,
                              srcOperands->front());
  } else {
    op = TruncSatSIOp::create(builder, loc, destType,
                              srcOperands->front());
  }

  LDBG() << "Built operation: " << *op;
  return {{op->getResult(0)}};
}
```

https://github.com/llvm/llvm-project/pull/212709


More information about the Mlir-commits mailing list