[flang-commits] [flang] [Flang] Minloc elemental intrinsic lowering (PR #74828)
David Green via flang-commits
flang-commits at lists.llvm.org
Fri Jan 12 07:00:40 PST 2024
================
@@ -659,6 +677,194 @@ mlir::LogicalResult VariableAssignBufferization::matchAndRewrite(
return mlir::success();
}
+// Look for assign(minloc(mask=elemental)) and generate the minloc loop with
+// inlined elemental and no extra temporaries.
+// %e = hlfir.elemental %shape ({ ... })
+// %m = hlfir.minloc %array mask %e
+// hlfir.assign %m to %result
+// hlfir.destroy %m
+class AssignMinMaxlocElementalConversion
+ : public mlir::OpRewritePattern<hlfir::AssignOp> {
+public:
+ using mlir::OpRewritePattern<hlfir::AssignOp>::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(hlfir::AssignOp assign,
+ mlir::PatternRewriter &rewriter) const override {
+ auto minloc = assign.getOperand(0).getDefiningOp<hlfir::MinlocOp>();
+ if (!minloc || !minloc.getMask() || minloc.getDim() || minloc.getBack())
+ return rewriter.notifyMatchFailure(assign,
+ "Did not find minloc with kind");
+
+ auto elemental = minloc.getMask().getDefiningOp<hlfir::ElementalOp>();
+ if (!elemental || hlfir::elementalOpMustProduceTemp(elemental))
+ return rewriter.notifyMatchFailure(assign, "Did not find elemental");
+
+ mlir::Operation::user_range users = minloc->getUsers();
+ if (std::distance(users.begin(), users.end()) != 2)
+ return rewriter.notifyMatchFailure(assign, "Did not find minloc users");
+ auto destroy = mlir::dyn_cast<hlfir::DestroyOp>(
+ *users.begin() == minloc ? *++users.begin() : *users.begin());
+ if (!destroy)
+ return rewriter.notifyMatchFailure(assign, "Did not find destroy");
+
+ if (!checkForElementalEffectsBetween(elemental, assign, minloc.getArray(),
----------------
davemgreen wrote:
With the latest version of the code this is hopefully getting fixed in #77899.
https://github.com/llvm/llvm-project/pull/74828
More information about the flang-commits
mailing list