//===- Utils.cpp - Utils for APFloat Conversion ---------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "Utils.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Vector/IR/VectorOps.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinTypeInterfaces.h" #include "mlir/IR/Location.h" #include "mlir/IR/PatternMatch.h" #include "mlir/IR/Value.h" using namespace mlir; Value mlir::getAPFloatSemanticsValue(OpBuilder &b, Location loc, FloatType floatTy) { int32_t sem = llvm::APFloatBase::SemanticsToEnum(floatTy.getFloatSemantics()); return arith::ConstantOp::create(b, loc, b.getI32Type(), b.getIntegerAttr(b.getI32Type(), sem)); } Value mlir::forEachScalarValue( mlir::RewriterBase &rewriter, Location loc, Value operand1, Value operand2, Type resultType, llvm::function_ref fn) { auto vecTy1 = dyn_cast(operand1.getType()); if (operand2) { // Sanity check: Operand types must match. assert(vecTy1 == dyn_cast(operand2.getType()) && "expected same vector types"); } if (!vecTy1) { // Not a vector. Call the function directly. return fn(operand1, operand2, resultType); } // Prepare scalar operands. ResultRange sclars1 = vector::ToElementsOp::create(rewriter, loc, operand1)->getResults(); SmallVector scalars2; if (!operand2) { // No second operand. Create a vector of empty values. scalars2.assign(vecTy1.getNumElements(), Value()); } else { llvm::append_range( scalars2, vector::ToElementsOp::create(rewriter, loc, operand2)->getResults()); } // Call the function for each pair of scalar operands. auto resultVecType = cast(resultType); SmallVector results; for (auto [scalar1, scalar2] : llvm::zip_equal(sclars1, scalars2)) { Value result = fn(scalar1, scalar2, resultVecType.getElementType()); results.push_back(result); } // Package the results into a vector. return vector::FromElementsOp::create( rewriter, loc, vecTy1.cloneWith(/*shape=*/std::nullopt, results.front().getType()), results); } LogicalResult mlir::checkPreconditions(RewriterBase &rewriter, Operation *op) { for (Value value : llvm::concat(op->getOperands(), op->getResults())) { Type type = value.getType(); if (auto vecTy = dyn_cast(type)) { type = vecTy.getElementType(); } if (!type.isIntOrFloat()) { return rewriter.notifyMatchFailure( op, "only integers and floats (or vectors thereof) are supported"); } if (type.getIntOrFloatBitWidth() > 64) return rewriter.notifyMatchFailure(op, "bitwidth > 64 bits is not supported"); } return success(); }