8#ifndef MLIR_CONVERSION_GPUCOMMON_OPTOFUNCCALLLOWERING_H_
9#define MLIR_CONVERSION_GPUCOMMON_OPTOFUNCCALLLOWERING_H_
22using has_get_fastmath_t =
decltype(std::declval<T>().getFastmath());
54template <
typename SourceOp>
61 LLVM::cconv::CConv
cconv = LLVM::cconv::CConv::C)
68 ConversionPatternRewriter &rewriter)
const override {
69 using LLVM::LLVMFuncOp;
72 std::is_base_of<OpTrait::OneResult<SourceOp>, SourceOp>::value,
73 "expected single result op");
79 Type opResultType = op->getResultTypes().front();
81 return rewriter.notifyMatchFailure(op,
"expected scalar result type");
83 bool isResultBool = opResultType.
isInteger(1);
84 if constexpr (!std::is_base_of<OpTrait::SameOperandsAndResultType<SourceOp>,
86 assert(op->getNumOperands() > 0 &&
87 "expected op to take at least one operand");
88 assert((op->getResultTypes().front() == op->getOperand(0).getType() ||
90 "expected op with same operand and result types");
93 if (!op->template getParentOfType<FunctionOpInterface>()) {
94 return rewriter.notifyMatchFailure(
95 op,
"expected op to be within a function region");
99 for (
Value operand : adaptor.getOperands())
100 castedOperands.push_back(
maybeCast(operand, rewriter));
102 Type castedOperandType = castedOperands.front().getType();
106 isResultBool ? rewriter.getIntegerType(32) : castedOperandType;
109 if (funcName.empty())
114 LLVM::CallOp::create(rewriter, op->getLoc(), funcOp, castedOperands);
115 callOp.setCConv(
cconv);
117 if (resultType == adaptor.getOperands().front().getType()) {
118 rewriter.replaceOp(op, {callOp.getResult()});
127 Value zero = LLVM::ConstantOp::create(rewriter, op->getLoc(),
128 rewriter.getIntegerType(32),
129 rewriter.getI32IntegerAttr(0));
131 LLVM::ICmpOp::create(rewriter, op->getLoc(), LLVM::ICmpPredicate::ne,
132 callOp.getResult(), zero);
133 rewriter.replaceOp(op, {truncated});
137 assert(callOp.getResult().getType().isF32() &&
138 "only f32 types are supposed to be truncated back");
139 Value truncated = LLVM::FPTruncOp::create(
140 rewriter, op->getLoc(), adaptor.getOperands().front().getType(),
142 rewriter.replaceOp(op, {truncated});
148 if (!isa<Float16Type, BFloat16Type>(type))
152 if (!
f16Func.empty() && isa<Float16Type>(type))
155 return LLVM::FPExtOp::create(rewriter, operand.
getLoc(),
162 return LLVM::LLVMFunctionType::get(resultType, operandTypes);
167 using LLVM::LLVMFuncOp;
169 auto funcAttr = StringAttr::get(op->
getContext(), funcName);
176 assert(parentFunc &&
"expected there to be a parent function");
183 auto newFuncOp = LLVMFuncOp::create(
b, globalloc, funcName, funcType);
184 newFuncOp.setCConv(
cconv);
189 bool useApprox =
false;
190 if constexpr (llvm::is_detected<has_get_fastmath_t, SourceOp>::value) {
191 arith::FastMathFlags flag = op.getFastmath();
192 useApprox = ((uint32_t)arith::FastMathFlags::afn & (uint32_t)flag) &&
196 if (isa<Float16Type>(type))
198 if (isa<Float32Type>(type)) {
203 if (isa<Float64Type>(type))
MLIRContext * getContext() const
ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
An instance of this location represents a tuple of file, line number, and column number.
Conversion from types to the LLVM IR dialect.
LocationAttr findInstanceOfOrUnknown()
Return an instance of the given location type if one is nested under the current location else return...
This class helps build Operations.
Operation is the basic unit of execution within MLIR.
Location getLoc()
The source location the operation was defined or derived from.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
MLIRContext * getContext()
Return the context this operation is associated with.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
static Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isIntOrIndexOrFloat() const
Return true if this is an integer (of any signedness), index, or float type.
bool isInteger() const
Return true if this is an integer type (with the specified width).
This class provides an abstraction over the different types of ranges over Values.
type_range getTypes() const
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.
Location getLoc() const
Return the location of this value.
Include the generated interface declarations.
const LLVM::cconv::CConv cconv
const std::string f64Func
const std::string f32ApproxFunc
OpToFuncCallLowering(const LLVMTypeConverter &lowering, StringRef f32Func, StringRef f64Func, StringRef f32ApproxFunc, StringRef f16Func, StringRef i32Func="", PatternBenefit benefit=1, LLVM::cconv::CConv cconv=LLVM::cconv::CConv::C)
StringRef getFunctionName(Type type, SourceOp op) const
const std::string f32Func
LLVM::LLVMFuncOp appendOrGetFuncOp(StringRef funcName, Type funcType, Operation *op) const
const std::string f16Func
const std::string i32Func
LogicalResult matchAndRewrite(SourceOp op, typename SourceOp::Adaptor adaptor, ConversionPatternRewriter &rewriter) const override
Methods that operate on the SourceOp type.
Type getFunctionType(Type resultType, ValueRange operands) const
Value maybeCast(Value operand, PatternRewriter &rewriter) const