42 assert(!operands.empty() &&
"operands must be not empty");
43 assert(vectorWidth > 0 &&
"vector width must be larger than 0");
45 VectorType inputType = cast<VectorType>(operands[0].
getType());
51 return compute(operands);
55 int64_t innerDim = inputShape.back();
56 int64_t expansionDim = innerDim / vectorWidth;
57 assert((innerDim % vectorWidth == 0) &&
"invalid inner dimension size");
64 if (expansionDim > 1) {
66 expandedShape.insert(expandedShape.end() - 1, expansionDim);
67 expandedShape.back() = vectorWidth;
69 for (
unsigned i = 0; i < operands.size(); ++i) {
70 auto operand = operands[i];
71 auto eltType = cast<VectorType>(operand.getType()).getElementType();
72 auto expandedType = VectorType::get(expandedShape, eltType);
74 vector::ShapeCastOp::create(builder, expandedType, operand);
86 for (
int64_t i = 0; i < maxIndex; ++i) {
90 for (
const auto &tuple : llvm::enumerate(expandedOperands))
91 extracted[tuple.index()] =
92 vector::ExtractOp::create(builder, tuple.value(), offsets);
94 results[i] = compute(extracted);
98 Type resultEltType = cast<VectorType>(results[0].
getType()).getElementType();
99 Type resultExpandedType = VectorType::get(expandedShape, resultEltType);
101 builder, resultExpandedType, builder.
getZeroAttr(resultExpandedType));
103 for (
int64_t i = 0; i < maxIndex; ++i)
104 result = vector::InsertOp::create(builder, results[i],
result,
108 return vector::ShapeCastOp::create(
109 builder, VectorType::get(inputShape, resultEltType),
result);
116 LogicalResult matchAndRewrite(math::RsqrtOp op,
117 PatternRewriter &rewriter)
const final;
122RsqrtApproximation::matchAndRewrite(math::RsqrtOp op,
128 auto vectorType = dyn_cast<VectorType>(op.getOperand().getType());
129 if (!vectorType || vectorType.getRank() == 0 ||
130 vectorType.getShape().back() % 8 != 0)
133 ImplicitLocOpBuilder builder(op->getLoc(), rewriter);
134 auto bcastF32FromBits = [&](uint32_t bits) -> Value {
135 Value i32Value = arith::ConstantOp::create(
138 arith::BitcastOp::create(builder, builder.
getF32Type(), i32Value);
139 return vector::BroadcastOp::create(builder, vectorType, f32Value);
141 auto bcastF32 = [&](
float value) -> Value {
144 return vector::BroadcastOp::create(builder, vectorType, f32Value);
147 Value cstPosInf = bcastF32FromBits(0x7f800000u);
148 Value cstOnePointFive = bcastF32(1.5f);
149 Value cstNegHalf = bcastF32(-0.5f);
150 Value cstMinNormPos = bcastF32FromBits(0x00800000u);
152 Value negHalf = arith::MulFOp::create(builder, op.getOperand(), cstNegHalf);
156 Value ltMinMask = arith::CmpFOp::create(builder, arith::CmpFPredicate::OLT,
157 op.getOperand(), cstMinNormPos);
158 Value infMask = arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ,
159 op.getOperand(), cstPosInf);
160 Value notNormalFiniteMask = arith::OrIOp::create(builder, ltMinMask, infMask);
164 builder, op->getOperands(), 8, [&builder](
ValueRange operands) -> Value {
165 return x86::avx::RsqrtOp::create(builder, operands);
172 Value inner = arith::MulFOp::create(builder, negHalf, yApprox);
173 Value fma = math::FmaOp::create(builder, yApprox, inner, cstOnePointFive);
174 Value yNewton = arith::MulFOp::create(builder, yApprox, fma);
182 arith::SelectOp::create(builder, notNormalFiniteMask, yApprox, yNewton);
static Value handleMultidimensionalVectors(ImplicitLocOpBuilder &builder, ValueRange operands, int64_t vectorWidth, llvm::function_ref< Value(ValueRange)> compute)
IntegerAttr getI32IntegerAttr(int32_t value)
TypedAttr getZeroAttr(Type type)
FloatAttr getF32FloatAttr(float value)
ImplicitLocOpBuilder maintains a 'current location', allowing use of the create<> method without spec...
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
void populateMathRsqrtApproximationPatterns(RewritePatternSet &patterns)
Include the generated interface declarations.
SmallVector< int64_t > computeStrides(ArrayRef< int64_t > sizes)
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
SmallVector< int64_t > delinearize(int64_t linearIndex, ArrayRef< int64_t > strides)
Given the strides together with a linear index in the dimension space, return the vector-space offset...
Type getElementTypeOrSelf(Type type)
Return the element type or return the type itself.
int64_t computeMaxLinearIndex(ArrayRef< int64_t > basis)
Return the number of elements of basis (i.e.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...