MLIR 23.0.0git
ArithToAPFloat.cpp
Go to the documentation of this file.
1//===- ArithToAPFloat.cpp - Arithmetic to APFloat Conversion --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Utils.h"
10
18#include "mlir/IR/Verifier.h"
20
21namespace mlir {
22#define GEN_PASS_DEF_ARITHTOAPFLOATCONVERSIONPASS
23#include "mlir/Conversion/Passes.h.inc"
24} // namespace mlir
25
26using namespace mlir;
27using namespace mlir::func;
28
29/// Helper function to look up or create the symbol for a runtime library
30/// function for a binary arithmetic operation.
31///
32/// Parameter 1: APFloat semantics
33/// Parameter 2: Left-hand side operand
34/// Parameter 3: Right-hand side operand
35///
36/// This function will return a failure if the function is found but has an
37/// unexpected signature.
38///
39static FailureOr<FuncOp>
40lookupOrCreateBinaryFn(OpBuilder &b, SymbolOpInterface symTable, StringRef name,
41 SymbolTableCollection *symbolTables = nullptr) {
42 auto i32Type = IntegerType::get(symTable->getContext(), 32);
43 auto i64Type = IntegerType::get(symTable->getContext(), 64);
44 std::string funcName = (llvm::Twine("_mlir_apfloat_") + name).str();
45 return lookupOrCreateFnDecl(b, symTable, funcName,
46 {i32Type, i64Type, i64Type}, symbolTables);
47}
48
49/// Rewrite a binary arithmetic operation to an APFloat function call.
50template <typename OpTy>
53 const char *APFloatName,
54 SymbolOpInterface symTable,
55 PatternBenefit benefit = 1)
56 : OpRewritePattern<OpTy>(context, benefit), symTable(symTable),
58
59 LogicalResult matchAndRewrite(OpTy op,
60 PatternRewriter &rewriter) const override {
61 if (failed(checkPreconditions(rewriter, op)))
62 return failure();
63
64 // Get APFloat function from runtime library.
65 FailureOr<FuncOp> fn =
67 if (failed(fn))
68 return fn;
69
70 // Scalarize and convert to APFloat runtime calls.
71 Location loc = op.getLoc();
72 rewriter.setInsertionPoint(op);
74 rewriter, loc, op.getLhs(), op.getRhs(), op.getType(),
75 [&](Value lhs, Value rhs, Type resultType) {
76 // Cast operands to 64-bit integers.
77 auto floatTy = cast<FloatType>(resultType);
78 auto intWType = rewriter.getIntegerType(floatTy.getWidth());
79 auto int64Type = rewriter.getI64Type();
80 Value lhsBits = arith::ExtUIOp::create(
81 rewriter, loc, int64Type,
82 arith::BitcastOp::create(rewriter, loc, intWType, lhs));
83 Value rhsBits = arith::ExtUIOp::create(
84 rewriter, loc, int64Type,
85 arith::BitcastOp::create(rewriter, loc, intWType, rhs));
86
87 // Call APFloat function.
88 Value semValue = getAPFloatSemanticsValue(rewriter, loc, floatTy);
89 SmallVector<Value> params = {semValue, lhsBits, rhsBits};
90 auto resultOp = func::CallOp::create(rewriter, loc,
91 TypeRange(rewriter.getI64Type()),
92 SymbolRefAttr::get(*fn), params);
93
94 // Truncate result to the original width.
95 Value truncatedBits = arith::TruncIOp::create(rewriter, loc, intWType,
96 resultOp->getResult(0));
97 return arith::BitcastOp::create(rewriter, loc, floatTy,
98 truncatedBits);
99 });
100 rewriter.replaceOp(op, repl);
101 return success();
102 }
103
104 SymbolOpInterface symTable;
105 const char *APFloatName;
106};
107
108template <typename OpTy>
109struct FpToFpConversion final : OpRewritePattern<OpTy> {
110 FpToFpConversion(MLIRContext *context, SymbolOpInterface symTable,
111 PatternBenefit benefit = 1)
112 : OpRewritePattern<OpTy>(context, benefit), symTable(symTable) {}
113
114 LogicalResult matchAndRewrite(OpTy op,
115 PatternRewriter &rewriter) const override {
116 if (failed(checkPreconditions(rewriter, op)))
117 return failure();
118
119 // Get APFloat function from runtime library.
120 auto i32Type = IntegerType::get(symTable->getContext(), 32);
121 auto i64Type = IntegerType::get(symTable->getContext(), 64);
122 FailureOr<FuncOp> fn =
123 lookupOrCreateFnDecl(rewriter, symTable, "_mlir_apfloat_convert",
124 {i32Type, i32Type, i64Type});
125 if (failed(fn))
126 return fn;
127
128 // Scalarize and convert to APFloat runtime calls.
129 Location loc = op.getLoc();
130 rewriter.setInsertionPoint(op);
132 rewriter, loc, op.getOperand(), /*operand2=*/Value(), op.getType(),
133 [&](Value operand1, Value operand2, Type resultType) {
134 // Cast operands to 64-bit integers.
135 auto inFloatTy = cast<FloatType>(operand1.getType());
136 auto inIntWType = rewriter.getIntegerType(inFloatTy.getWidth());
137 Value operandBits = arith::ExtUIOp::create(
138 rewriter, loc, i64Type,
139 arith::BitcastOp::create(rewriter, loc, inIntWType, operand1));
140
141 // Call APFloat function.
142 Value inSemValue = getAPFloatSemanticsValue(rewriter, loc, inFloatTy);
143 auto outFloatTy = cast<FloatType>(resultType);
144 Value outSemValue =
145 getAPFloatSemanticsValue(rewriter, loc, outFloatTy);
146 std::array<Value, 3> params = {inSemValue, outSemValue, operandBits};
147 auto resultOp = func::CallOp::create(rewriter, loc,
148 TypeRange(rewriter.getI64Type()),
149 SymbolRefAttr::get(*fn), params);
150
151 // Truncate result to the original width.
152 auto outIntWType = rewriter.getIntegerType(outFloatTy.getWidth());
153 Value truncatedBits = arith::TruncIOp::create(
154 rewriter, loc, outIntWType, resultOp->getResult(0));
155 return arith::BitcastOp::create(rewriter, loc, outFloatTy,
156 truncatedBits);
157 });
158 rewriter.replaceOp(op, repl);
159 return success();
160 }
161
162 SymbolOpInterface symTable;
163};
164
165template <typename OpTy>
167 FpToIntConversion(MLIRContext *context, SymbolOpInterface symTable,
168 bool isUnsigned, PatternBenefit benefit = 1)
169 : OpRewritePattern<OpTy>(context, benefit), symTable(symTable),
171
172 LogicalResult matchAndRewrite(OpTy op,
173 PatternRewriter &rewriter) const override {
174 if (failed(checkPreconditions(rewriter, op)))
175 return failure();
176
177 // Get APFloat function from runtime library.
178 auto i1Type = IntegerType::get(symTable->getContext(), 1);
179 auto i32Type = IntegerType::get(symTable->getContext(), 32);
180 auto i64Type = IntegerType::get(symTable->getContext(), 64);
181 FailureOr<FuncOp> fn =
182 lookupOrCreateFnDecl(rewriter, symTable, "_mlir_apfloat_convert_to_int",
183 {i32Type, i32Type, i1Type, i64Type});
184 if (failed(fn))
185 return fn;
186
187 // Scalarize and convert to APFloat runtime calls.
188 Location loc = op.getLoc();
189 rewriter.setInsertionPoint(op);
191 rewriter, loc, op.getOperand(), /*operand2=*/Value(), op.getType(),
192 [&](Value operand1, Value operand2, Type resultType) {
193 // Cast operands to 64-bit integers.
194 auto inFloatTy = cast<FloatType>(operand1.getType());
195 auto inIntWType = rewriter.getIntegerType(inFloatTy.getWidth());
196 Value operandBits = arith::ExtUIOp::create(
197 rewriter, loc, i64Type,
198 arith::BitcastOp::create(rewriter, loc, inIntWType, operand1));
199
200 // Call APFloat function.
201 Value inSemValue = getAPFloatSemanticsValue(rewriter, loc, inFloatTy);
202 auto outIntTy = cast<IntegerType>(resultType);
203 Value outWidthValue = arith::ConstantOp::create(
204 rewriter, loc, i32Type,
205 rewriter.getIntegerAttr(i32Type, outIntTy.getWidth()));
206 Value isUnsignedValue = arith::ConstantOp::create(
207 rewriter, loc, i1Type,
208 rewriter.getIntegerAttr(i1Type, isUnsigned));
209 SmallVector<Value> params = {inSemValue, outWidthValue,
210 isUnsignedValue, operandBits};
211 auto resultOp = func::CallOp::create(rewriter, loc,
212 TypeRange(rewriter.getI64Type()),
213 SymbolRefAttr::get(*fn), params);
214
215 // Truncate result to the original width.
216 return arith::TruncIOp::create(rewriter, loc, outIntTy,
217 resultOp->getResult(0));
218 });
219 rewriter.replaceOp(op, repl);
220 return success();
221 }
222
223 SymbolOpInterface symTable;
225};
226
227template <typename OpTy>
229 IntToFpConversion(MLIRContext *context, SymbolOpInterface symTable,
230 bool isUnsigned, PatternBenefit benefit = 1)
231 : OpRewritePattern<OpTy>(context, benefit), symTable(symTable),
233
234 LogicalResult matchAndRewrite(OpTy op,
235 PatternRewriter &rewriter) const override {
236 if (failed(checkPreconditions(rewriter, op)))
237 return failure();
238
239 // Get APFloat function from runtime library.
240 auto i1Type = IntegerType::get(symTable->getContext(), 1);
241 auto i32Type = IntegerType::get(symTable->getContext(), 32);
242 auto i64Type = IntegerType::get(symTable->getContext(), 64);
243 FailureOr<FuncOp> fn = lookupOrCreateFnDecl(
244 rewriter, symTable, "_mlir_apfloat_convert_from_int",
245 {i32Type, i32Type, i1Type, i64Type});
246 if (failed(fn))
247 return fn;
248
249 // Scalarize and convert to APFloat runtime calls.
250 Location loc = op.getLoc();
251 rewriter.setInsertionPoint(op);
253 rewriter, loc, op.getOperand(), /*operand2=*/Value(), op.getType(),
254 [&](Value operand1, Value operand2, Type resultType) {
255 // Cast operands to 64-bit integers.
256 auto inIntTy = cast<IntegerType>(operand1.getType());
257 Value operandBits = operand1;
258 if (operandBits.getType().getIntOrFloatBitWidth() < 64) {
259 if (isUnsigned) {
260 operandBits =
261 arith::ExtUIOp::create(rewriter, loc, i64Type, operandBits);
262 } else {
263 operandBits =
264 arith::ExtSIOp::create(rewriter, loc, i64Type, operandBits);
265 }
266 }
267
268 // Call APFloat function.
269 auto outFloatTy = cast<FloatType>(resultType);
270 Value outSemValue =
271 getAPFloatSemanticsValue(rewriter, loc, outFloatTy);
272 Value inWidthValue = arith::ConstantOp::create(
273 rewriter, loc, i32Type,
274 rewriter.getIntegerAttr(i32Type, inIntTy.getWidth()));
275 Value isUnsignedValue = arith::ConstantOp::create(
276 rewriter, loc, i1Type,
277 rewriter.getIntegerAttr(i1Type, isUnsigned));
278 SmallVector<Value> params = {outSemValue, inWidthValue,
279 isUnsignedValue, operandBits};
280 auto resultOp = func::CallOp::create(rewriter, loc,
281 TypeRange(rewriter.getI64Type()),
282 SymbolRefAttr::get(*fn), params);
283
284 // Truncate result to the original width.
285 auto outIntWType = rewriter.getIntegerType(outFloatTy.getWidth());
286 Value truncatedBits = arith::TruncIOp::create(
287 rewriter, loc, outIntWType, resultOp->getResult(0));
288 return arith::BitcastOp::create(rewriter, loc, outFloatTy,
289 truncatedBits);
290 });
291 rewriter.replaceOp(op, repl);
292 return success();
293 }
294
295 SymbolOpInterface symTable;
297};
298
299struct CmpFOpToAPFloatConversion final : OpRewritePattern<arith::CmpFOp> {
300 CmpFOpToAPFloatConversion(MLIRContext *context, SymbolOpInterface symTable,
301 PatternBenefit benefit = 1)
302 : OpRewritePattern<arith::CmpFOp>(context, benefit), symTable(symTable) {}
303
304 LogicalResult matchAndRewrite(arith::CmpFOp op,
305 PatternRewriter &rewriter) const override {
306 if (failed(checkPreconditions(rewriter, op)))
307 return failure();
308
309 // Get APFloat function from runtime library.
310 auto i1Type = IntegerType::get(symTable->getContext(), 1);
311 auto i8Type = IntegerType::get(symTable->getContext(), 8);
312 auto i32Type = IntegerType::get(symTable->getContext(), 32);
313 auto i64Type = IntegerType::get(symTable->getContext(), 64);
314 FailureOr<FuncOp> fn =
315 lookupOrCreateFnDecl(rewriter, symTable, "_mlir_apfloat_compare",
316 {i32Type, i64Type, i64Type}, nullptr, i8Type);
317 if (failed(fn))
318 return fn;
319
320 // Scalarize and convert to APFloat runtime calls.
321 Location loc = op.getLoc();
322 rewriter.setInsertionPoint(op);
324 rewriter, loc, op.getLhs(), op.getRhs(), op.getType(),
325 [&](Value lhs, Value rhs, Type resultType) {
326 // Cast operands to 64-bit integers.
327 auto floatTy = cast<FloatType>(lhs.getType());
328 auto intWType = rewriter.getIntegerType(floatTy.getWidth());
329 Value lhsBits = arith::ExtUIOp::create(
330 rewriter, loc, i64Type,
331 arith::BitcastOp::create(rewriter, loc, intWType, lhs));
332 Value rhsBits = arith::ExtUIOp::create(
333 rewriter, loc, i64Type,
334 arith::BitcastOp::create(rewriter, loc, intWType, rhs));
335
336 // Call APFloat function.
337 Value semValue = getAPFloatSemanticsValue(rewriter, loc, floatTy);
338 SmallVector<Value> params = {semValue, lhsBits, rhsBits};
339 Value comparisonResult =
340 func::CallOp::create(rewriter, loc, TypeRange(i8Type),
341 SymbolRefAttr::get(*fn), params)
342 ->getResult(0);
343
344 // Generate an i1 SSA value that is "true" if the comparison result
345 // matches the given `val`.
346 auto checkResult = [&](llvm::APFloat::cmpResult val) {
347 return arith::CmpIOp::create(
348 rewriter, loc, arith::CmpIPredicate::eq, comparisonResult,
349 arith::ConstantOp::create(
350 rewriter, loc, i8Type,
351 rewriter.getIntegerAttr(i8Type, static_cast<int8_t>(val)))
352 .getResult());
353 };
354 // Generate an i1 SSA value that is "true" if the comparison result
355 // matches any of the given `vals`.
357 checkResults = [&](ArrayRef<llvm::APFloat::cmpResult> vals) {
358 Value first = checkResult(vals.front());
359 if (vals.size() == 1)
360 return first;
361 Value rest = checkResults(vals.drop_front());
362 return arith::OrIOp::create(rewriter, loc, first, rest)
363 .getResult();
364 };
365
366 // This switch-case statement was taken from arith::applyCmpPredicate.
368 switch (op.getPredicate()) {
369 case arith::CmpFPredicate::AlwaysFalse:
370 result =
371 arith::ConstantOp::create(rewriter, loc, i1Type,
372 rewriter.getIntegerAttr(i1Type, 0))
373 .getResult();
374 break;
375 case arith::CmpFPredicate::OEQ:
376 result = checkResult(llvm::APFloat::cmpEqual);
377 break;
378 case arith::CmpFPredicate::OGT:
379 result = checkResult(llvm::APFloat::cmpGreaterThan);
380 break;
381 case arith::CmpFPredicate::OGE:
382 result = checkResults(
383 {llvm::APFloat::cmpGreaterThan, llvm::APFloat::cmpEqual});
384 break;
385 case arith::CmpFPredicate::OLT:
386 result = checkResult(llvm::APFloat::cmpLessThan);
387 break;
388 case arith::CmpFPredicate::OLE:
389 result = checkResults(
390 {llvm::APFloat::cmpLessThan, llvm::APFloat::cmpEqual});
391 break;
392 case arith::CmpFPredicate::ONE:
393 // Not cmpUnordered and not cmpUnordered.
394 result = checkResults(
395 {llvm::APFloat::cmpLessThan, llvm::APFloat::cmpGreaterThan});
396 break;
397 case arith::CmpFPredicate::ORD:
398 // Not cmpUnordered.
399 result = checkResults({llvm::APFloat::cmpLessThan,
400 llvm::APFloat::cmpGreaterThan,
401 llvm::APFloat::cmpEqual});
402 break;
403 case arith::CmpFPredicate::UEQ:
404 result = checkResults(
405 {llvm::APFloat::cmpUnordered, llvm::APFloat::cmpEqual});
406 break;
407 case arith::CmpFPredicate::UGT:
408 result = checkResults(
409 {llvm::APFloat::cmpUnordered, llvm::APFloat::cmpGreaterThan});
410 break;
411 case arith::CmpFPredicate::UGE:
412 result = checkResults({llvm::APFloat::cmpUnordered,
413 llvm::APFloat::cmpGreaterThan,
414 llvm::APFloat::cmpEqual});
415 break;
416 case arith::CmpFPredicate::ULT:
417 result = checkResults(
418 {llvm::APFloat::cmpUnordered, llvm::APFloat::cmpLessThan});
419 break;
420 case arith::CmpFPredicate::ULE:
421 result = checkResults({llvm::APFloat::cmpUnordered,
422 llvm::APFloat::cmpLessThan,
423 llvm::APFloat::cmpEqual});
424 break;
425 case arith::CmpFPredicate::UNE:
426 // Not cmpEqual.
427 result = checkResults({llvm::APFloat::cmpLessThan,
428 llvm::APFloat::cmpGreaterThan,
429 llvm::APFloat::cmpUnordered});
430 break;
431 case arith::CmpFPredicate::UNO:
432 result = checkResult(llvm::APFloat::cmpUnordered);
433 break;
434 case arith::CmpFPredicate::AlwaysTrue:
435 result =
436 arith::ConstantOp::create(rewriter, loc, i1Type,
437 rewriter.getIntegerAttr(i1Type, 1))
438 .getResult();
439 break;
440 }
441 return result;
442 });
443 rewriter.replaceOp(op, repl);
444 return success();
445 }
446
447 SymbolOpInterface symTable;
448};
449
450struct NegFOpToAPFloatConversion final : OpRewritePattern<arith::NegFOp> {
451 NegFOpToAPFloatConversion(MLIRContext *context, SymbolOpInterface symTable,
452 PatternBenefit benefit = 1)
453 : OpRewritePattern<arith::NegFOp>(context, benefit), symTable(symTable) {}
454
455 LogicalResult matchAndRewrite(arith::NegFOp op,
456 PatternRewriter &rewriter) const override {
457 if (failed(checkPreconditions(rewriter, op)))
458 return failure();
459
460 // Get APFloat function from runtime library.
461 auto i32Type = IntegerType::get(symTable->getContext(), 32);
462 auto i64Type = IntegerType::get(symTable->getContext(), 64);
463 FailureOr<FuncOp> fn = lookupOrCreateFnDecl(
464 rewriter, symTable, "_mlir_apfloat_neg", {i32Type, i64Type});
465 if (failed(fn))
466 return fn;
467
468 // Scalarize and convert to APFloat runtime calls.
469 Location loc = op.getLoc();
470 rewriter.setInsertionPoint(op);
472 rewriter, loc, op.getOperand(), /*operand2=*/Value(), op.getType(),
473 [&](Value operand1, Value operand2, Type resultType) {
474 // Cast operands to 64-bit integers.
475 auto floatTy = cast<FloatType>(operand1.getType());
476 auto intWType = rewriter.getIntegerType(floatTy.getWidth());
477 Value operandBits = arith::ExtUIOp::create(
478 rewriter, loc, i64Type,
479 arith::BitcastOp::create(rewriter, loc, intWType, operand1));
480
481 // Call APFloat function.
482 Value semValue = getAPFloatSemanticsValue(rewriter, loc, floatTy);
483 SmallVector<Value> params = {semValue, operandBits};
484 Value negatedBits =
485 func::CallOp::create(rewriter, loc, TypeRange(i64Type),
486 SymbolRefAttr::get(*fn), params)
487 ->getResult(0);
488
489 // Truncate result to the original width.
490 Value truncatedBits =
491 arith::TruncIOp::create(rewriter, loc, intWType, negatedBits);
492 return arith::BitcastOp::create(rewriter, loc, floatTy,
493 truncatedBits);
494 });
495 rewriter.replaceOp(op, repl);
496 return success();
497 }
498
499 SymbolOpInterface symTable;
500};
501
502namespace {
503struct ArithToAPFloatConversionPass final
504 : impl::ArithToAPFloatConversionPassBase<ArithToAPFloatConversionPass> {
505 using Base::Base;
506
507 void runOnOperation() override;
508};
509
510void ArithToAPFloatConversionPass::runOnOperation() {
511 MLIRContext *context = &getContext();
512 RewritePatternSet patterns(context);
513 patterns.add<BinaryArithOpToAPFloatConversion<arith::AddFOp>>(context, "add",
514 getOperation());
515 patterns.add<BinaryArithOpToAPFloatConversion<arith::SubFOp>>(
516 context, "subtract", getOperation());
517 patterns.add<BinaryArithOpToAPFloatConversion<arith::MulFOp>>(
518 context, "multiply", getOperation());
519 patterns.add<BinaryArithOpToAPFloatConversion<arith::DivFOp>>(
520 context, "divide", getOperation());
521 patterns.add<BinaryArithOpToAPFloatConversion<arith::RemFOp>>(
522 context, "remainder", getOperation());
523 patterns.add<BinaryArithOpToAPFloatConversion<arith::MinNumFOp>>(
524 context, "minnum", getOperation());
525 patterns.add<BinaryArithOpToAPFloatConversion<arith::MaxNumFOp>>(
526 context, "maxnum", getOperation());
527 patterns.add<BinaryArithOpToAPFloatConversion<arith::MinimumFOp>>(
528 context, "minimum", getOperation());
529 patterns.add<BinaryArithOpToAPFloatConversion<arith::MaximumFOp>>(
530 context, "maximum", getOperation());
532 .add<FpToFpConversion<arith::ExtFOp>, FpToFpConversion<arith::TruncFOp>,
533 CmpFOpToAPFloatConversion, NegFOpToAPFloatConversion>(
534 context, getOperation());
535 patterns.add<FpToIntConversion<arith::FPToSIOp>>(context, getOperation(),
536 /*isUnsigned=*/false);
537 patterns.add<FpToIntConversion<arith::FPToUIOp>>(context, getOperation(),
538 /*isUnsigned=*/true);
539 patterns.add<IntToFpConversion<arith::SIToFPOp>>(context, getOperation(),
540 /*isUnsigned=*/false);
541 patterns.add<IntToFpConversion<arith::UIToFPOp>>(context, getOperation(),
542 /*isUnsigned=*/true);
543 LogicalResult result = success();
544 ScopedDiagnosticHandler scopedHandler(context, [&result](Diagnostic &diag) {
545 if (diag.getSeverity() == DiagnosticSeverity::Error) {
546 result = failure();
547 }
548 // NB: if you don't return failure, no other diag handlers will fire (see
549 // mlir/lib/IR/Diagnostics.cpp:DiagnosticEngineImpl::emit).
550 return failure();
551 });
552 walkAndApplyPatterns(getOperation(), std::move(patterns));
553 if (failed(result))
554 return signalPassFailure();
555}
556} // namespace
return success()
static FailureOr< FuncOp > lookupOrCreateBinaryFn(OpBuilder &b, SymbolOpInterface symTable, StringRef name, SymbolTableCollection *symbolTables=nullptr)
Helper function to look up or create the symbol for a runtime library function for a binary arithmeti...
lhs
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
b getContext())
static std::string diag(const llvm::Value &value)
IntegerAttr getIntegerAttr(Type type, int64_t value)
Definition Builders.cpp:228
IntegerType getI64Type()
Definition Builders.cpp:65
IntegerType getIntegerType(unsigned width)
Definition Builders.cpp:67
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class helps build Operations.
Definition Builders.h:207
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Definition Builders.h:398
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...
This class represents a collection of SymbolTables.
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:37
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Type getType() const
Return the type of this value.
Definition Value.h:105
FailureOr< FuncOp > lookupOrCreateFnDecl(OpBuilder &b, SymbolOpInterface symTable, StringRef name, TypeRange paramTypes, SymbolTableCollection *symbolTables=nullptr, Type resultType={})
Helper function to look up or create the symbol for a runtime library function with the given paramet...
Definition Utils.cpp:302
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:573
Include the generated interface declarations.
LogicalResult checkPreconditions(RewriterBase &rewriter, Operation *op)
Check preconditions for the conversion:
Definition Utils.cpp:70
Value getAPFloatSemanticsValue(OpBuilder &b, Location loc, FloatType floatTy)
Definition Utils.cpp:21
Value forEachScalarValue(mlir::RewriterBase &rewriter, Location loc, Value operand1, Value operand2, Type resultType, llvm::function_ref< Value(Value, Value, Type)> fn)
Given two operands of vector type and vector result type (with the same shape), call the given functi...
Definition Utils.cpp:28
const FrozenRewritePatternSet & patterns
void walkAndApplyPatterns(Operation *op, const FrozenRewritePatternSet &patterns, RewriterBase::Listener *listener=nullptr)
A fast walk-based pattern rewrite driver.
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
BinaryArithOpToAPFloatConversion(MLIRContext *context, const char *APFloatName, SymbolOpInterface symTable, PatternBenefit benefit=1)
LogicalResult matchAndRewrite(arith::CmpFOp op, PatternRewriter &rewriter) const override
CmpFOpToAPFloatConversion(MLIRContext *context, SymbolOpInterface symTable, PatternBenefit benefit=1)
SymbolOpInterface symTable
FpToFpConversion(MLIRContext *context, SymbolOpInterface symTable, PatternBenefit benefit=1)
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
SymbolOpInterface symTable
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
FpToIntConversion(MLIRContext *context, SymbolOpInterface symTable, bool isUnsigned, PatternBenefit benefit=1)
SymbolOpInterface symTable
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
IntToFpConversion(MLIRContext *context, SymbolOpInterface symTable, bool isUnsigned, PatternBenefit benefit=1)
LogicalResult matchAndRewrite(arith::NegFOp op, PatternRewriter &rewriter) const override
NegFOpToAPFloatConversion(MLIRContext *context, SymbolOpInterface symTable, PatternBenefit benefit=1)
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})