| //===- 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<Value(Value, Value, Type)> fn) { | |
| auto vecTy1 = dyn_cast<VectorType>(operand1.getType()); | |
| if (operand2) { | |
| // Sanity check: Operand types must match. | |
| assert(vecTy1 == dyn_cast<VectorType>(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<Value> 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<VectorType>(resultType); | |
| SmallVector<Value> 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<Value>(op->getOperands(), op->getResults())) { | |
| Type type = value.getType(); | |
| if (auto vecTy = dyn_cast<VectorType>(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(); | |
| } |