17 #include "llvm/ADT/SmallBitVector.h"
31 llvm::SmallBitVector dimsToProject(shape.size());
32 for (
unsigned pos = 0, e = shape.size(); pos < e && rank > 0; ++pos) {
33 if (shape[pos] == 1) {
34 dimsToProject.set(pos);
43 if (
auto value = llvm::dyn_cast_if_present<Value>(ofr))
45 auto attr = dyn_cast<IntegerAttr>(llvm::dyn_cast_if_present<Attribute>(ofr));
46 assert(attr &&
"expect the op fold result casts to an integer attribute");
52 if (targetType == value.
getType())
55 bool targetIsIndex = targetType.
isIndex();
57 if (targetIsIndex ^ valueIsIndex)
58 return b.
create<arith::IndexCastOp>(loc, targetType, value);
60 auto targetIntegerType = dyn_cast<IntegerType>(targetType);
61 auto valueIntegerType = dyn_cast<IntegerType>(value.
getType());
62 assert(targetIntegerType && valueIntegerType &&
63 "unexpected cast between types other than integers and index");
64 assert(targetIntegerType.getSignedness() == valueIntegerType.getSignedness());
66 if (targetIntegerType.getWidth() > valueIntegerType.getWidth())
67 return b.
create<arith::ExtSIOp>(loc, targetIntegerType, value);
68 return b.
create<arith::TruncIOp>(loc, targetIntegerType, value);
72 IntegerType toType,
bool isUnsigned) {
74 if (isa<FloatType>(operand.
getType())) {
76 return b.
create<arith::FPToUIOp>(toType, operand);
77 return b.
create<arith::FPToSIOp>(toType, operand);
81 return b.
create<arith::IndexCastOp>(toType, operand);
82 if (
auto fromIntType = dyn_cast<IntegerType>(operand.
getType())) {
84 if (toType.getWidth() > fromIntType.getWidth()) {
86 return b.
create<arith::ExtUIOp>(toType, operand);
87 return b.
create<arith::ExtSIOp>(toType, operand);
89 if (toType.getWidth() < fromIntType.getWidth())
90 return b.
create<arith::TruncIOp>(toType, operand);
101 if (isa<IntegerType>(operand.
getType())) {
103 return b.
create<arith::UIToFPOp>(toType, operand);
104 return b.
create<arith::SIToFPOp>(toType, operand);
106 if (
auto fromFpTy = dyn_cast<FloatType>(operand.
getType())) {
107 if (toType.
getWidth() > fromFpTy.getWidth())
108 return b.
create<arith::ExtFOp>(toType, operand);
109 if (toType.
getWidth() < fromFpTy.getWidth())
110 return b.
create<arith::TruncFOp>(toType, operand);
118 ComplexType targetType,
120 if (
auto fromComplexType = dyn_cast<ComplexType>(operand.
getType())) {
121 if (isa<FloatType>(targetType.getElementType()) &&
122 isa<FloatType>(fromComplexType.getElementType())) {
125 Type targetETy = targetType.getElementType();
126 if (targetType.getElementType().getIntOrFloatBitWidth() <
127 fromComplexType.getElementType().getIntOrFloatBitWidth()) {
128 real = b.
create<arith::TruncFOp>(targetETy, real);
129 imag = b.
create<arith::TruncFOp>(targetETy, imag);
131 real = b.
create<arith::ExtFOp>(targetETy, real);
132 imag = b.
create<arith::ExtFOp>(targetETy, imag);
134 return b.
create<complex::CreateOp>(targetType, real, imag);
138 if (dyn_cast<FloatType>(operand.
getType())) {
139 FloatType toFpTy = cast<FloatType>(targetType.getElementType());
141 Value from = operand;
143 from = b.
create<arith::ExtFOp>(toFpTy, from);
146 from = b.
create<arith::TruncFOp>(toFpTy, from);
150 return b.
create<complex::CreateOp>(targetType, from, zero);
153 if (dyn_cast<IntegerType>(operand.
getType())) {
154 FloatType toFpTy = cast<FloatType>(targetType.getElementType());
155 Value from = operand;
157 from = b.
create<arith::UIToFPOp>(toFpTy, from);
159 from = b.
create<arith::SIToFPOp>(toFpTy, from);
163 return b.
create<complex::CreateOp>(targetType, from, zero);
170 Type toType,
bool isUnsignedCast) {
171 if (operand.
getType() == toType)
175 if (
auto intTy = dyn_cast<IntegerType>(toType)) {
177 }
else if (
auto floatTy = dyn_cast<FloatType>(toType)) {
179 }
else if (
auto complexTy = dyn_cast<ComplexType>(toType)) {
195 return llvm::to_vector<4>(
202 Type type,
const APInt &value) {
204 if (isa<IntegerType>(type)) {
207 auto vecTy = cast<ShapedType>(type);
211 return builder.
create<arith::ConstantOp>(loc, attr);
215 Type type, int64_t value) {
216 unsigned elementBitWidth = 0;
217 if (
auto intTy = dyn_cast<IntegerType>(type))
218 elementBitWidth = intTy.getWidth();
220 elementBitWidth = cast<ShapedType>(type).getElementTypeBitWidth();
223 APInt(elementBitWidth, value));
227 Type type,
const APFloat &value) {
228 if (isa<FloatType>(type))
232 return builder.
createOrFold<arith::ConstantOp>(loc, type, splat);
236 return b.
create<arith::AndIOp>(loc, lhs, rhs);
239 if (isa<FloatType>(lhs.
getType()))
240 return b.
create<arith::AddFOp>(loc, lhs, rhs);
241 return b.
create<arith::AddIOp>(loc, lhs, rhs);
244 if (isa<FloatType>(lhs.
getType()))
245 return b.
create<arith::SubFOp>(loc, lhs, rhs);
246 return b.
create<arith::SubIOp>(loc, lhs, rhs);
249 if (isa<FloatType>(lhs.
getType()))
250 return b.
create<arith::MulFOp>(loc, lhs, rhs);
251 return b.
create<arith::MulIOp>(loc, lhs, rhs);
254 if (isa<FloatType>(lhs.
getType()))
255 return b.
create<arith::CmpFOp>(loc, arith::CmpFPredicate::OGT, lhs, rhs);
256 return b.
create<arith::CmpIOp>(loc, arith::CmpIPredicate::sgt, lhs, rhs);
259 if (isa<FloatType>(lhs.
getType()))
260 return b.
create<arith::CmpFOp>(loc, arith::CmpFPredicate::OLT, lhs, rhs);
261 return b.
create<arith::CmpIOp>(loc, arith::CmpIPredicate::slt, lhs, rhs);
264 return b.
create<arith::SelectOp>(loc, cmp, lhs, rhs);
270 return createProduct(builder, loc, values, values.front().getType());
275 Value one = builder.
create<ConstantOp>(loc, resultType,
278 return std::accumulate(
279 values.begin(), values.end(), one,
280 [&arithBuilder](
Value acc,
Value v) { return arithBuilder.mul(acc, v); });
static Value convertScalarToComplexDtype(ImplicitLocOpBuilder &b, Value operand, ComplexType targetType, bool isUnsigned)
static Value convertScalarToIntDtype(ImplicitLocOpBuilder &b, Value operand, IntegerType toType, bool isUnsigned)
static Value convertScalarToFpDtype(ImplicitLocOpBuilder &b, Value operand, FloatType toType, bool isUnsigned)
IntegerAttr getIntegerAttr(Type type, int64_t value)
FloatAttr getFloatAttr(Type type, double value)
TypedAttr getOneAttr(Type type)
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
const llvm::fltSemantics & getFloatSemantics()
Return the floating semantics of this float type.
unsigned getWidth()
Return the bitwidth of this float type.
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.
void createOrFold(SmallVectorImpl< Value > &results, Location location, Args &&...args)
Create an operation of specific op type at the current insertion point, and immediately try to fold i...
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents a single result from folding an operation.
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.
Specialization of arith.constant op that returns a floating point value.
Specialization of arith.constant op that returns an integer of index type.
Value createProduct(OpBuilder &builder, Location loc, ArrayRef< Value > values)
Include the generated interface declarations.
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
Value convertScalarToDtype(OpBuilder &b, Location loc, Value operand, Type toType, bool isUnsignedCast)
Converts a scalar value operand to type toType.
Value createScalarOrSplatConstant(OpBuilder &builder, Location loc, Type type, const APInt &value)
Create a constant of type type at location loc whose value is value (an APInt or APFloat whose type m...
Value getValueOrCreateCastToIndexLike(OpBuilder &b, Location loc, Type targetType, Value value)
Create a cast from an index-like value (index or integer) to another index-like value.
Value getValueOrCreateConstantIndexOp(OpBuilder &b, Location loc, OpFoldResult ofr)
Converts an OpFoldResult to a Value.
llvm::SmallBitVector getPositionsOfShapeOne(unsigned rank, ArrayRef< int64_t > shape)
detail::op_matcher< arith::ConstantIndexOp > matchConstantIndex()
Matches a ConstantIndexOp.
Helper struct to build simple arithmetic quantities with minimal type inference support.
Value mul(Value lhs, Value rhs)
Value _and(Value lhs, Value rhs)
Value slt(Value lhs, Value rhs)
Value select(Value cmp, Value lhs, Value rhs)
Value add(Value lhs, Value rhs)
Value sgt(Value lhs, Value rhs)
Value sub(Value lhs, Value rhs)
The matcher that matches a certain kind of op.