17 #include "llvm/ADT/SmallBitVector.h"
30 llvm::SmallBitVector dimsToProject(shape.size());
31 for (
unsigned pos = 0, e = shape.size(); pos < e && rank > 0; ++pos) {
32 if (shape[pos] == 1) {
33 dimsToProject.set(pos);
42 if (
auto value = llvm::dyn_cast_if_present<Value>(ofr))
44 auto attr = dyn_cast<IntegerAttr>(llvm::dyn_cast_if_present<Attribute>(ofr));
45 assert(attr &&
"expect the op fold result casts to an integer attribute");
51 if (targetType == value.
getType())
54 bool targetIsIndex = targetType.
isIndex();
56 if (targetIsIndex ^ valueIsIndex)
57 return b.
create<arith::IndexCastOp>(loc, targetType, value);
59 auto targetIntegerType = dyn_cast<IntegerType>(targetType);
60 auto valueIntegerType = dyn_cast<IntegerType>(value.
getType());
61 assert(targetIntegerType && valueIntegerType &&
62 "unexpected cast between types other than integers and index");
63 assert(targetIntegerType.getSignedness() == valueIntegerType.getSignedness());
65 if (targetIntegerType.getWidth() > valueIntegerType.getWidth())
66 return b.
create<arith::ExtSIOp>(loc, targetIntegerType, value);
67 return b.
create<arith::TruncIOp>(loc, targetIntegerType, value);
71 IntegerType toType,
bool isUnsigned) {
73 if (isa<FloatType>(operand.
getType())) {
75 return b.
create<arith::FPToUIOp>(toType, operand);
76 return b.
create<arith::FPToSIOp>(toType, operand);
80 return b.
create<arith::IndexCastOp>(toType, operand);
81 if (
auto fromIntType = dyn_cast<IntegerType>(operand.
getType())) {
83 if (toType.getWidth() > fromIntType.getWidth()) {
85 return b.
create<arith::ExtUIOp>(toType, operand);
86 return b.
create<arith::ExtSIOp>(toType, operand);
88 if (toType.getWidth() < fromIntType.getWidth())
89 return b.
create<arith::TruncIOp>(toType, operand);
100 if (isa<IntegerType>(operand.
getType())) {
102 return b.
create<arith::UIToFPOp>(toType, operand);
103 return b.
create<arith::SIToFPOp>(toType, operand);
105 if (
auto fromFpTy = dyn_cast<FloatType>(operand.
getType())) {
106 if (toType.
getWidth() > fromFpTy.getWidth())
107 return b.
create<arith::ExtFOp>(toType, operand);
108 if (toType.
getWidth() < fromFpTy.getWidth())
109 return b.
create<arith::TruncFOp>(toType, operand);
117 ComplexType targetType,
119 if (
auto fromComplexType = dyn_cast<ComplexType>(operand.
getType())) {
120 if (isa<FloatType>(targetType.getElementType()) &&
121 isa<FloatType>(fromComplexType.getElementType())) {
124 Type targetETy = targetType.getElementType();
125 if (targetType.getElementType().getIntOrFloatBitWidth() <
126 fromComplexType.getElementType().getIntOrFloatBitWidth()) {
127 real = b.
create<arith::TruncFOp>(targetETy, real);
128 imag = b.
create<arith::TruncFOp>(targetETy, imag);
130 real = b.
create<arith::ExtFOp>(targetETy, real);
131 imag = b.
create<arith::ExtFOp>(targetETy, imag);
133 return b.
create<complex::CreateOp>(targetType, real, imag);
137 if (dyn_cast<FloatType>(operand.
getType())) {
138 FloatType toFpTy = cast<FloatType>(targetType.getElementType());
140 Value from = operand;
142 from = b.
create<arith::ExtFOp>(toFpTy, from);
145 from = b.
create<arith::TruncFOp>(toFpTy, from);
149 return b.
create<complex::CreateOp>(targetType, from, zero);
152 if (dyn_cast<IntegerType>(operand.
getType())) {
153 FloatType toFpTy = cast<FloatType>(targetType.getElementType());
154 Value from = operand;
156 from = b.
create<arith::UIToFPOp>(toFpTy, from);
158 from = b.
create<arith::SIToFPOp>(toFpTy, from);
162 return b.
create<complex::CreateOp>(targetType, from, zero);
169 Type toType,
bool isUnsignedCast) {
170 if (operand.
getType() == toType)
174 if (
auto intTy = dyn_cast<IntegerType>(toType)) {
176 }
else if (
auto floatTy = dyn_cast<FloatType>(toType)) {
178 }
else if (
auto complexTy = dyn_cast<ComplexType>(toType)) {
194 return llvm::to_vector<4>(
201 return b.
create<arith::AndIOp>(loc, lhs, rhs);
204 if (isa<FloatType>(lhs.
getType()))
205 return b.
create<arith::AddFOp>(loc, lhs, rhs);
206 return b.
create<arith::AddIOp>(loc, lhs, rhs);
209 if (isa<FloatType>(lhs.
getType()))
210 return b.
create<arith::SubFOp>(loc, lhs, rhs);
211 return b.
create<arith::SubIOp>(loc, lhs, rhs);
214 if (isa<FloatType>(lhs.
getType()))
215 return b.
create<arith::MulFOp>(loc, lhs, rhs);
216 return b.
create<arith::MulIOp>(loc, lhs, rhs);
219 if (isa<FloatType>(lhs.
getType()))
220 return b.
create<arith::CmpFOp>(loc, arith::CmpFPredicate::OGT, lhs, rhs);
221 return b.
create<arith::CmpIOp>(loc, arith::CmpIPredicate::sgt, lhs, rhs);
224 if (isa<FloatType>(lhs.
getType()))
225 return b.
create<arith::CmpFOp>(loc, arith::CmpFPredicate::OLT, lhs, rhs);
226 return b.
create<arith::CmpIOp>(loc, arith::CmpIPredicate::slt, lhs, rhs);
229 return b.
create<arith::SelectOp>(loc, cmp, lhs, rhs);
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)
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.
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.
This header declares functions that assist transformations in the MemRef dialect.
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 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.
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.