28 bool losesInfo =
false;
31 value.convert(cast<FloatType>(eltType).getFloatSemantics(),
32 APFloat::rmNearestTiesToEven, &losesInfo);
34 if (
auto shapedTy = dyn_cast<ShapedType>(type)) {
35 return b.
create<arith::ConstantOp>(loc,
39 return b.
create<arith::ConstantOp>(loc, attr);
51 if (
auto shapedTy = dyn_cast<ShapedType>(type)) {
52 return b.
create<arith::ConstantOp>(loc,
56 return b.
create<arith::ConstantOp>(loc, attr);
62 if (
auto shapedTy = dyn_cast<ShapedType>(opType))
63 i64Ty = shapedTy.clone(i64Ty);
64 Value fixedConvert = b.
create<arith::FPToSIOp>(i64Ty, operand);
65 Value fpFixedConvert = b.
create<arith::SIToFPOp>(opType, fixedConvert);
68 return b.
create<math::CopySignOp>(fpFixedConvert, operand);
120 loc, arith::CmpFPredicate::OLT, op.
getOperand(), zero);
121 Value isNegativeFloat =
122 rewriter.
create<arith::UIToFPOp>(loc, floatType, isNegative);
123 Value isNegativeTimesNegTwo =
124 rewriter.
create<arith::MulFOp>(loc, isNegativeFloat, negTwo);
125 Value sign = rewriter.
create<arith::AddFOp>(loc, isNegativeTimesNegTwo, one);
131 Value negDoubledX = rewriter.
create<arith::MulFOp>(loc, negTwo, positiveX);
132 Value exp2x = rewriter.
create<math::ExpOp>(loc, negDoubledX);
133 Value dividend = rewriter.
create<arith::SubFOp>(loc, one, exp2x);
134 Value divisor = rewriter.
create<arith::AddFOp>(loc, one, exp2x);
135 Value positiveRes = rewriter.
create<arith::DivFOp>(loc, dividend, divisor);
150 Value div = b.
create<arith::DivFOp>(type, sin, cos);
160 Type type = op.getType();
161 Value mult = b.
create<arith::MulFOp>(type, operandA, operandB);
162 Value add = b.
create<arith::AddFOp>(type, mult, operandC);
184 b.
create<arith::CmpFOp>(arith::CmpFPredicate::OLT, operand, zero);
186 b.
create<arith::SelectOp>(op->
getLoc(), negCheck, negOne, zero);
187 Value ret = b.
create<arith::AddFOp>(opType, fpFixedConvert, incrValue);
207 Value gtCheck = b.
create<arith::CmpFOp>(arith::CmpFPredicate::OGT, operand,
211 Value ret = b.
create<arith::AddFOp>(opType, fpFixedConvert, incrValue);
228 Value castPowerToFp =
229 rewriter.
create<arith::SIToFPOp>(op.
getLoc(), baseType, power);
238 return convertFPowItoPowf();
242 return convertFPowItoPowf();
244 int64_t powerInt = value.getSExtValue();
245 bool isNegative = powerInt < 0;
246 int64_t absPower =
std::abs(powerInt);
250 while (absPower > 0) {
252 res = b.
create<arith::MulFOp>(baseType, base, res);
254 base = b.
create<arith::MulFOp>(baseType, base, base);
260 .getFloatSemantics();
269 APFloat::getInf(sem,
false), rewriter);
272 APFloat::getInf(sem,
true), rewriter);
274 b.
create<arith::CmpFOp>(arith::CmpFPredicate::OEQ, res, zero);
275 Value negZeroEqCheck =
276 b.
create<arith::CmpFOp>(arith::CmpFPredicate::OEQ, res, negZero);
277 res = b.
create<arith::DivFOp>(baseType, one, res);
279 b.
create<arith::SelectOp>(op->
getLoc(), zeroEqCheck, posInfinity, res);
280 res = b.
create<arith::SelectOp>(op->
getLoc(), negZeroEqCheck, negInfinity,
297 Value opASquared = b.
create<arith::MulFOp>(opType, operandA, operandA);
298 Value opBHalf = b.
create<arith::DivFOp>(opType, operandB, two);
300 Value logA = b.
create<math::LogOp>(opType, opASquared);
301 Value mult = b.
create<arith::MulFOp>(opType, opBHalf, logA);
302 Value expResult = b.
create<math::ExpOp>(opType, mult);
303 Value negExpResult = b.
create<arith::MulFOp>(opType, expResult, negOne);
304 Value remainder = b.
create<arith::RemFOp>(opType, operandB, two);
306 b.
create<arith::CmpFOp>(arith::CmpFPredicate::OLT, operandA, zero);
308 b.
create<arith::CmpFOp>(arith::CmpFPredicate::ONE, remainder, zero);
327 Value mult = b.
create<arith::MulFOp>(opType, operand, ln2);
341 if (!opEType.
isF32()) {
346 if (
auto shapedTy = dyn_cast<ShapedType>(opType))
347 i32Ty = shapedTy.clone(i32Ty);
354 Value incrValue = b.
create<math::CopySignOp>(half, operand);
355 Value add = b.
create<arith::AddFOp>(opType, operand, incrValue);
378 Value operandBitcast = b.
create<arith::BitcastOp>(i32Ty, operand);
380 b.
create<arith::ShRUIOp>(operandBitcast, c23), expMask);
381 Value operandBiasedExp = b.
create<arith::SubIOp>(operandExp, c127);
382 Value isSpecialValOrLargeVal =
383 b.
create<arith::CmpIOp>(arith::CmpIPredicate::sge, operandBiasedExp, c23);
385 Value result = b.
create<arith::SelectOp>(isSpecialValOrLargeVal, operand,
396 auto operandTy = operand.
getType();
400 int32_t bitwidth = eTy.getIntOrFloatBitWidth();
404 uint64_t allbits = -1;
406 allbits = allbits >> (64 - bitwidth);
411 for (int32_t bw = bitwidth; bw > 1; bw = bw / 2) {
414 auto mask =
createIntConst(loc, operandTy, allbits >> half, rewriter);
417 rewriter.
create<arith::CmpIOp>(loc, arith::CmpIPredicate::ule, x, mask);
418 Value add = rewriter.
create<arith::AddIOp>(loc, count, bits);
419 Value shift = rewriter.
create<arith::ShLIOp>(loc, x, bits);
421 x = rewriter.
create<arith::SelectOp>(loc, pred, shift, x);
422 count = rewriter.
create<arith::SelectOp>(loc, pred, add, count);
426 Value pred = rewriter.
create<arith::CmpIOp>(loc, arith::CmpIPredicate::eq,
430 Value sel = rewriter.
create<arith::SelectOp>(loc, pred, bwval, count);
441 Type operandTy = operand.getType();
442 Type resultTy = op.getType();
446 if (!isa<FloatType>(operandETy) || !isa<FloatType>(resultETy)) {
450 Type fTy = operandTy;
452 if (
auto shapedTy = dyn_cast<ShapedType>(fTy)) {
453 iTy = shapedTy.clone(iTy);
458 unsigned mantissaWidth =
459 llvm::cast<FloatType>(operandETy).getFPMantissaWidth() - 1;
460 unsigned exponentWidth = bitWidth - mantissaWidth - 1;
477 Value operandBitcast = b.
create<arith::BitcastOp>(iTy, operand);
483 b.
create<arith::ShRUIOp>(operandBitcast, c23), expMask);
484 Value operandBiasedExp = b.
create<arith::SubIOp>(operandExp, c127);
486 b.
create<arith::ShRUIOp>(roundBitcast, c23), expMask);
487 Value roundBiasedExp = b.
create<arith::SubIOp>(roundExp, c127);
491 Value clampedShift = b.
create<arith::MaxSIOp>(shift, c0);
492 clampedShift = b.
create<arith::MinSIOp>(clampedShift, c31);
493 return b.
create<arith::ShRUIOp>(x, clampedShift);
496 auto maskMantissa = [&](
Value mantissa,
498 Value shiftedMantissaMask = safeShiftRight(c23Mask, mantissaMaskRightShift);
499 return b.
create<arith::AndIOp>(mantissa, shiftedMantissaMask);
516 Value roundBiasedExpEq0 =
517 b.
create<arith::CmpIOp>(arith::CmpIPredicate::eq, roundBiasedExp, c0);
518 Value roundBiasedExpMinus1 = b.
create<arith::SubIOp>(roundBiasedExp, c1);
519 Value roundMaskedMantissa = maskMantissa(roundBitcast, roundBiasedExpMinus1);
520 Value roundIsNotEvenOrSpecialVal = b.
create<arith::CmpIOp>(
521 arith::CmpIPredicate::ne, roundMaskedMantissa, c0);
522 roundIsNotEvenOrSpecialVal =
523 b.
create<arith::OrIOp>(roundIsNotEvenOrSpecialVal, roundBiasedExpEq0);
532 Value operandBiasedExpEqNeg1 = b.
create<arith::CmpIOp>(
533 arith::CmpIPredicate::eq, operandBiasedExp, cNeg1);
534 Value expectedOperandMaskedMantissa = b.
create<arith::SelectOp>(
535 operandBiasedExpEqNeg1, c0, safeShiftRight(c2To22, operandBiasedExp));
536 Value operandMaskedMantissa = maskMantissa(operandBitcast, operandBiasedExp);
537 Value operandIsHalfway =
538 b.
create<arith::CmpIOp>(arith::CmpIPredicate::eq, operandMaskedMantissa,
539 expectedOperandMaskedMantissa);
541 Value operandBiasedExpGeNeg1 = b.
create<arith::CmpIOp>(
542 arith::CmpIPredicate::sge, operandBiasedExp, cNeg1);
543 Value operandBiasedExpLt23 =
544 b.
create<arith::CmpIOp>(arith::CmpIPredicate::slt, operandBiasedExp, c23);
546 b.
create<arith::AndIOp>(operandIsHalfway, operandBiasedExpLt23);
548 b.
create<arith::AndIOp>(operandIsHalfway, operandBiasedExpGeNeg1);
552 Value sign = b.
create<math::CopySignOp>(c1Float, operand);
557 b.
create<arith::AndIOp>(roundIsNotEvenOrSpecialVal, operandIsHalfway);
562 result = b.
create<math::CopySignOp>(result, operand);
static Value getZero(OpBuilder &b, Location loc, Type elementType)
Get zero value for an element type.
static Value createTruncatedFPValue(Value operand, ImplicitLocOpBuilder &b)
static LogicalResult convertFPowIOp(math::FPowIOp op, PatternRewriter &rewriter)
static LogicalResult convertPowfOp(math::PowFOp op, PatternRewriter &rewriter)
static LogicalResult convertRoundOp(math::RoundOp op, PatternRewriter &rewriter)
static LogicalResult convertTanOp(math::TanOp op, PatternRewriter &rewriter)
static LogicalResult convertCtlzOp(math::CountLeadingZerosOp op, PatternRewriter &rewriter)
static LogicalResult convertFmaFOp(math::FmaOp op, PatternRewriter &rewriter)
static LogicalResult convertFloorOp(math::FloorOp op, PatternRewriter &rewriter)
static LogicalResult convertCeilOp(math::CeilOp op, PatternRewriter &rewriter)
static LogicalResult convertRoundEvenOp(math::RoundEvenOp op, PatternRewriter &rewriter)
static LogicalResult convertCoshOp(math::CoshOp op, PatternRewriter &rewriter)
static LogicalResult convertSinhOp(math::SinhOp op, PatternRewriter &rewriter)
static Value createFloatConst(Location loc, Type type, APFloat value, OpBuilder &b)
Create a float constant.
static Value createIntConst(Location loc, Type type, int64_t value, OpBuilder &b)
Create an integer constant.
static LogicalResult convertTanhOp(math::TanhOp op, PatternRewriter &rewriter)
Expands tanh op into 1-exp^{-2x} / 1+exp^{-2x} To avoid overflow we exploit the reflection symmetry t...
static LogicalResult convertExp2fOp(math::Exp2Op op, PatternRewriter &rewriter)
Attributes are known-constant values of operations.
IntegerAttr getIntegerAttr(Type type, int64_t value)
FloatAttr getFloatAttr(Type type, double value)
IntegerType getIntegerType(unsigned width)
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
ImplicitLocOpBuilder maintains a 'current location', allowing use of the create<> method without spec...
OpTy create(Args &&...args)
Create an operation of specific op type at the current insertion point and location.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This class helps build Operations.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Value getOperand(unsigned idx)
Location getLoc()
The source location the operation was defined or derived from.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
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,...
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
MPInt round(const Fraction &f)
Fraction abs(const Fraction &f)
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
void populateExpandSinhPattern(RewritePatternSet &patterns)
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
detail::constant_int_value_binder m_ConstantInt(IntegerAttr::ValueType *bind_value)
Matches a constant holding a scalar/vector/tensor integer (splat) and writes the integer value to bin...
void populateExpandTanhPattern(RewritePatternSet &patterns)
void populateExpandFmaFPattern(RewritePatternSet &patterns)
void populateExpandFPowIPattern(RewritePatternSet &patterns)
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
void populateExpandPowFPattern(RewritePatternSet &patterns)
Type getElementTypeOrSelf(Type type)
Return the element type or return the type itself.
void populateExpandTanPattern(RewritePatternSet &patterns)
void populateExpandCoshPattern(RewritePatternSet &patterns)
void populateExpandRoundFPattern(RewritePatternSet &patterns)
void populateExpandExp2FPattern(RewritePatternSet &patterns)
void populateExpandCeilFPattern(RewritePatternSet &patterns)
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
void populateExpandCtlzPattern(RewritePatternSet &patterns)
void populateExpandRoundEvenPattern(RewritePatternSet &patterns)
void populateExpandFloorFPattern(RewritePatternSet &patterns)
This class represents an efficient way to signal success or failure.