[flang-commits] [flang] [flang] Region-based HLFIR operation for conditional expressions lowering (PR #194411)
via flang-commits
flang-commits at lists.llvm.org
Mon May 4 07:42:25 PDT 2026
================
@@ -857,6 +858,137 @@ struct CharExtremumOpConversion
}
};
+struct ConditionalOpConversion
+ : public mlir::OpConversionPattern<hlfir::ConditionalOp> {
+ using mlir::OpConversionPattern<hlfir::ConditionalOp>::OpConversionPattern;
+ explicit ConditionalOpConversion(mlir::MLIRContext *ctx)
+ : mlir::OpConversionPattern<hlfir::ConditionalOp>{ctx} {
+ // This pattern recursively converts nested ConditionalOp's
+ // by cloning and then converting them, so we have to allow
+ // for recursive pattern application. The recursion is bounded
+ // by the nesting level of ConditionalOp's.
+ setHasBoundedRewriteRecursion();
+ }
+ /// Compute the MLIR type of the temp's DeclareOp base result,
+ /// given the hlfir.expr type of the conditional. This must match
+ /// what createAndDeclareTemp + hlfir::DeclareOp would produce.
+ static mlir::Type computeTempBaseType(fir::FirOpBuilder &builder,
+ hlfir::ExprType exprType) {
+ const mlir::Type eleTy{exprType.getEleTy()};
+ const bool isPolymorphic{exprType.isPolymorphic()};
+ const bool isArray{exprType.isArray()};
+ mlir::Type elemOrSeqType{eleTy};
+ if (isArray)
+ elemOrSeqType = fir::SequenceType::get(exprType.getShape(), eleTy);
+ // Polymorphic: runtime allocate produces fir.class<fir.heap<T>>,
+ // DeclareOp strips the heap attribute → fir.class<T>.
+ if (isPolymorphic)
+ return fir::ClassType::get(elemOrSeqType);
+ // Arrays (non-polymorphic): heap alloc → fir.heap<seqTy>,
+ // DeclareOp wraps in box → fir.box<seqTy>.
+ if (isArray)
+ return fir::BoxType::get(elemOrSeqType);
+ // Scalar, non-polymorphic.
+ if (auto charTy{mlir::dyn_cast<fir::CharacterType>(eleTy)})
+ if (charTy.hasDynamicLen())
+ return fir::BoxCharType::get(builder.getContext(), charTy.getFKind());
+ if (fir::isRecordWithTypeParameters(eleTy))
+ return fir::BoxType::get(eleTy);
+ return fir::ReferenceType::get(eleTy);
+ }
+
+ llvm::LogicalResult
+ matchAndRewrite(hlfir::ConditionalOp condOp, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const override {
+ const mlir::Location loc{condOp->getLoc()};
+ fir::FirOpBuilder builder(rewriter, condOp.getOperation());
+ HLFIRListener listener{builder, rewriter};
+ builder.setListener(&listener);
+ // Use ExprType to ensure both branches produce identical MLIR temp types.
+ const auto exprType{
+ mlir::cast<hlfir::ExprType>(condOp.getResult().getType())};
+ const bool isPolymorphic{exprType.isPolymorphic()};
+ const bool isArray{exprType.isArray()};
+ mlir::Type elemOrSeqType{exprType.getEleTy()};
+ if (isArray)
+ elemOrSeqType =
+ fir::SequenceType::get(exprType.getShape(), elemOrSeqType);
----------------
jeanPerier wrote:
mlir::Type elemOrSeqType = hlfir::getFortranElementOrSequenceType(exprType);
https://github.com/llvm/llvm-project/pull/194411
More information about the flang-commits
mailing list