@@ -329,6 +329,31 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
329329} // namespace
330330
331331namespace {
332+
333+ static bool isInGlobalOp (mlir::ConversionPatternRewriter &rewriter) {
334+ auto *thisBlock = rewriter.getInsertionBlock ();
335+ return thisBlock && mlir::isa<mlir::LLVM::GlobalOp>(thisBlock->getParentOp ());
336+ }
337+
338+ // Inside a fir.global, the input box was produced as an llvm.struct<>
339+ // because objects cannot be handled in memory inside a fir.global body that
340+ // must be constant foldable. However, the type translation are not
341+ // contextual, so the fir.box<T> type of the operation that produced the
342+ // fir.box was translated to an llvm.ptr<llvm.struct<>> and the MLIR pass
343+ // manager inserted a builtin.unrealized_conversion_cast that was inserted
344+ // and needs to be removed here.
345+ // This should be called by any pattern operating on operations that are
346+ // accepting fir.box inputs and are used in fir.global.
347+ static mlir::Value
348+ fixBoxInputInsideGlobalOp (mlir::ConversionPatternRewriter &rewriter,
349+ mlir::Value box) {
350+ if (isInGlobalOp (rewriter))
351+ if (auto unrealizedCast =
352+ box.getDefiningOp <mlir::UnrealizedConversionCastOp>())
353+ return unrealizedCast.getInputs ()[0 ];
354+ return box;
355+ }
356+
332357// / Lower `fir.box_addr` to the sequence of operations to extract the first
333358// / element of the box.
334359struct BoxAddrOpConversion : public fir ::FIROpConversion<fir::BoxAddrOp> {
@@ -341,6 +366,7 @@ struct BoxAddrOpConversion : public fir::FIROpConversion<fir::BoxAddrOp> {
341366 auto loc = boxaddr.getLoc ();
342367 if (auto argty =
343368 mlir::dyn_cast<fir::BaseBoxType>(boxaddr.getVal ().getType ())) {
369+ a = fixBoxInputInsideGlobalOp (rewriter, a);
344370 TypePair boxTyPair = getBoxTypePair (argty);
345371 rewriter.replaceOp (boxaddr,
346372 getBaseAddrFromBox (loc, boxTyPair, a, rewriter));
@@ -1737,12 +1763,6 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
17371763 xbox.getSubcomponent ().size ());
17381764 }
17391765
1740- static bool isInGlobalOp (mlir::ConversionPatternRewriter &rewriter) {
1741- auto *thisBlock = rewriter.getInsertionBlock ();
1742- return thisBlock &&
1743- mlir::isa<mlir::LLVM::GlobalOp>(thisBlock->getParentOp ());
1744- }
1745-
17461766 // / If the embox is not in a globalOp body, allocate storage for the box;
17471767 // / store the value inside and return the generated alloca. Return the input
17481768 // / value otherwise.
@@ -2076,21 +2096,10 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
20762096 mlir::ConversionPatternRewriter &rewriter) const override {
20772097 mlir::Location loc = rebox.getLoc ();
20782098 mlir::Type idxTy = lowerTy ().indexType ();
2079- mlir::Value loweredBox = adaptor.getOperands ()[0 ];
2099+ mlir::Value loweredBox =
2100+ fixBoxInputInsideGlobalOp (rewriter, adaptor.getBox ());
20802101 mlir::ValueRange operands = adaptor.getOperands ();
20812102
2082- // Inside a fir.global, the input box was produced as an llvm.struct<>
2083- // because objects cannot be handled in memory inside a fir.global body that
2084- // must be constant foldable. However, the type translation are not
2085- // contextual, so the fir.box<T> type of the operation that produced the
2086- // fir.box was translated to an llvm.ptr<llvm.struct<>> and the MLIR pass
2087- // manager inserted a builtin.unrealized_conversion_cast that was inserted
2088- // and needs to be removed here.
2089- if (isInGlobalOp (rewriter))
2090- if (auto unrealizedCast =
2091- loweredBox.getDefiningOp <mlir::UnrealizedConversionCastOp>())
2092- loweredBox = unrealizedCast.getInputs ()[0 ];
2093-
20942103 TypePair inputBoxTyPair = getBoxTypePair (rebox.getBox ().getType ());
20952104
20962105 // Create new descriptor and fill its non-shape related data.
0 commit comments