Skip to content

Commit e73cf2f

Browse files
[flang] Remove materialization workaround in type converter (#98743)
This change is in preparation of #97903, which adds extra checks for materializations: it is now enforced that they produce an SSA value of the correct type, so the current workaround no longer works. The original workaround avoided target materializations by directly returning the to-be-converted SSA value from the materialization callback. This can be avoided by initializing the lowering patterns that insert the materializations without a type converter. For `cg::XEmboxOp`, the existing workaround that skips `unrealized_conversion_cast` ops is still in place. Also remove the lowering pattern for `unrealized_conversion_cast`. This pattern has no effect because `unrealized_conversion_cast` ops that are inserted by the dialect conversion framework are never matched by the pattern driver.
1 parent 075f754 commit e73cf2f

File tree

4 files changed

+30
-77
lines changed

4 files changed

+30
-77
lines changed

flang/include/flang/Tools/CLOptions.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
/// This file defines some shared command-line options that can be used when
1010
/// debugging the test tools. This file must be included into the tool.
1111

12+
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
1213
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
1314
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
1415
#include "mlir/Pass/PassManager.h"
@@ -223,6 +224,10 @@ inline void addFIRToLLVMPass(
223224
options.forceUnifiedTBAATree = useOldAliasTags;
224225
addPassConditionally(pm, disableFirToLlvmIr,
225226
[&]() { return fir::createFIRToLLVMPass(options); });
227+
// The dialect conversion framework may leave dead unrealized_conversion_cast
228+
// ops behind, so run reconcile-unrealized-casts to clean them up.
229+
addPassConditionally(pm, disableFirToLlvmIr,
230+
[&]() { return mlir::createReconcileUnrealizedCastsPass(); });
226231
}
227232

228233
inline void addLLVMDialectToLLVMPass(

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
3636
#include "mlir/Conversion/MathToLibm/MathToLibm.h"
3737
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
38-
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
3938
#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
4039
#include "mlir/Dialect/Arith/IR/Arith.h"
4140
#include "mlir/Dialect/DLTI/DLTI.h"
@@ -2042,13 +2041,13 @@ struct ExtractValueOpConversion
20422041
/// InsertValue is the generalized instruction for the composition of new
20432042
/// aggregate type values.
20442043
struct InsertValueOpConversion
2045-
: public fir::FIROpAndTypeConversion<fir::InsertValueOp>,
2044+
: public mlir::OpConversionPattern<fir::InsertValueOp>,
20462045
public ValueOpCommon {
2047-
using FIROpAndTypeConversion::FIROpAndTypeConversion;
2046+
using OpConversionPattern::OpConversionPattern;
20482047

20492048
llvm::LogicalResult
2050-
doRewrite(fir::InsertValueOp insertVal, mlir::Type ty, OpAdaptor adaptor,
2051-
mlir::ConversionPatternRewriter &rewriter) const override {
2049+
matchAndRewrite(fir::InsertValueOp insertVal, OpAdaptor adaptor,
2050+
mlir::ConversionPatternRewriter &rewriter) const override {
20522051
mlir::ValueRange operands = adaptor.getOperands();
20532052
auto indices = collectIndices(rewriter, insertVal.getCoor());
20542053
toRowMajor(indices, operands[0].getType());
@@ -2669,8 +2668,9 @@ struct TypeDescOpConversion : public fir::FIROpConversion<fir::TypeDescOp> {
26692668
};
26702669

26712670
/// Lower `fir.has_value` operation to `llvm.return` operation.
2672-
struct HasValueOpConversion : public fir::FIROpConversion<fir::HasValueOp> {
2673-
using FIROpConversion::FIROpConversion;
2671+
struct HasValueOpConversion
2672+
: public mlir::OpConversionPattern<fir::HasValueOp> {
2673+
using OpConversionPattern::OpConversionPattern;
26742674

26752675
llvm::LogicalResult
26762676
matchAndRewrite(fir::HasValueOp op, OpAdaptor adaptor,
@@ -3515,29 +3515,6 @@ struct MustBeDeadConversion : public fir::FIROpConversion<FromOp> {
35153515
}
35163516
};
35173517

3518-
struct UnrealizedConversionCastOpConversion
3519-
: public fir::FIROpConversion<mlir::UnrealizedConversionCastOp> {
3520-
using FIROpConversion::FIROpConversion;
3521-
3522-
llvm::LogicalResult
3523-
matchAndRewrite(mlir::UnrealizedConversionCastOp op, OpAdaptor adaptor,
3524-
mlir::ConversionPatternRewriter &rewriter) const override {
3525-
assert(op.getOutputs().getTypes().size() == 1 && "expect a single type");
3526-
mlir::Type convertedType = convertType(op.getOutputs().getTypes()[0]);
3527-
if (convertedType == adaptor.getInputs().getTypes()[0]) {
3528-
rewriter.replaceOp(op, adaptor.getInputs());
3529-
return mlir::success();
3530-
}
3531-
3532-
convertedType = adaptor.getInputs().getTypes()[0];
3533-
if (convertedType == op.getOutputs().getType()[0]) {
3534-
rewriter.replaceOp(op, adaptor.getInputs());
3535-
return mlir::success();
3536-
}
3537-
return mlir::failure();
3538-
}
3539-
};
3540-
35413518
struct ShapeOpConversion : public MustBeDeadConversion<fir::ShapeOp> {
35423519
using MustBeDeadConversion::MustBeDeadConversion;
35433520
};
@@ -3714,7 +3691,8 @@ class FIRToLLVMLowering
37143691
signalPassFailure();
37153692
}
37163693

3717-
// Run pass to add comdats to functions that have weak linkage on relevant platforms
3694+
// Run pass to add comdats to functions that have weak linkage on relevant
3695+
// platforms
37183696
if (fir::getTargetTriple(mod).supportsCOMDAT()) {
37193697
mlir::OpPassManager comdatPM("builtin.module");
37203698
comdatPM.addPass(mlir::LLVM::createLLVMAddComdats());
@@ -3789,16 +3767,19 @@ void fir::populateFIRToLLVMConversionPatterns(
37893767
DivcOpConversion, EmboxOpConversion, EmboxCharOpConversion,
37903768
EmboxProcOpConversion, ExtractValueOpConversion, FieldIndexOpConversion,
37913769
FirEndOpConversion, FreeMemOpConversion, GlobalLenOpConversion,
3792-
GlobalOpConversion, HasValueOpConversion, InsertOnRangeOpConversion,
3793-
InsertValueOpConversion, IsPresentOpConversion, LenParamIndexOpConversion,
3794-
LoadOpConversion, MulcOpConversion, NegcOpConversion,
3795-
NoReassocOpConversion, SelectCaseOpConversion, SelectOpConversion,
3796-
SelectRankOpConversion, SelectTypeOpConversion, ShapeOpConversion,
3797-
ShapeShiftOpConversion, ShiftOpConversion, SliceOpConversion,
3798-
StoreOpConversion, StringLitOpConversion, SubcOpConversion,
3799-
TypeDescOpConversion, TypeInfoOpConversion, UnboxCharOpConversion,
3800-
UnboxProcOpConversion, UndefOpConversion, UnreachableOpConversion,
3801-
UnrealizedConversionCastOpConversion, XArrayCoorOpConversion,
3802-
XEmboxOpConversion, XReboxOpConversion, ZeroOpConversion>(converter,
3803-
options);
3770+
GlobalOpConversion, InsertOnRangeOpConversion, IsPresentOpConversion,
3771+
LenParamIndexOpConversion, LoadOpConversion, MulcOpConversion,
3772+
NegcOpConversion, NoReassocOpConversion, SelectCaseOpConversion,
3773+
SelectOpConversion, SelectRankOpConversion, SelectTypeOpConversion,
3774+
ShapeOpConversion, ShapeShiftOpConversion, ShiftOpConversion,
3775+
SliceOpConversion, StoreOpConversion, StringLitOpConversion,
3776+
SubcOpConversion, TypeDescOpConversion, TypeInfoOpConversion,
3777+
UnboxCharOpConversion, UnboxProcOpConversion, UndefOpConversion,
3778+
UnreachableOpConversion, XArrayCoorOpConversion, XEmboxOpConversion,
3779+
XReboxOpConversion, ZeroOpConversion>(converter, options);
3780+
3781+
// Patterns that are populated without a type converter do not trigger
3782+
// target materializations for the operands of the root op.
3783+
patterns.insert<HasValueOpConversion, InsertValueOpConversion>(
3784+
patterns.getContext());
38043785
}

flang/lib/Optimizer/CodeGen/TypeConverter.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -122,40 +122,6 @@ LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
122122
// Convert it here to i1 just in case it survives.
123123
return mlir::IntegerType::get(&getContext(), 1);
124124
});
125-
// FIXME: https://reviews.llvm.org/D82831 introduced an automatic
126-
// materialization of conversion around function calls that is not working
127-
// well with fir lowering to llvm (incorrect llvm.mlir.cast are inserted).
128-
// Workaround until better analysis: register a handler that does not insert
129-
// any conversions.
130-
addSourceMaterialization(
131-
[&](mlir::OpBuilder &builder, mlir::Type resultType,
132-
mlir::ValueRange inputs,
133-
mlir::Location loc) -> std::optional<mlir::Value> {
134-
if (inputs.size() != 1)
135-
return std::nullopt;
136-
return inputs[0];
137-
});
138-
// Similar FIXME workaround here (needed for compare.fir/select-type.fir
139-
// as well as rebox-global.fir tests). This is needed to cope with the
140-
// the fact that codegen does not lower some operation results to the LLVM
141-
// type produced by this LLVMTypeConverter. For instance, inside FIR
142-
// globals, fir.box are lowered to llvm.struct, while the fir.box type
143-
// conversion translates it into an llvm.ptr<llvm.struct<>> because
144-
// descriptors are manipulated in memory outside of global initializers
145-
// where this is not possible. Hence, MLIR inserts
146-
// builtin.unrealized_conversion_cast after the translation of operations
147-
// producing fir.box in fir.global codegen. addSourceMaterialization and
148-
// addTargetMaterialization allow ignoring these ops and removing them
149-
// after codegen assuming the type discrepencies are intended (like for
150-
// fir.box inside globals).
151-
addTargetMaterialization(
152-
[&](mlir::OpBuilder &builder, mlir::Type resultType,
153-
mlir::ValueRange inputs,
154-
mlir::Location loc) -> std::optional<mlir::Value> {
155-
if (inputs.size() != 1)
156-
return std::nullopt;
157-
return inputs[0];
158-
});
159125
}
160126

161127
// i32 is used here because LLVM wants i32 constants when indexing into struct

flang/test/Fir/basic-program.fir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,5 @@ func.func @_QQmain() {
119119
// PASSES-NEXT: (S) 0 num-dce'd - Number of operations eliminated
120120
// PASSES-NEXT: TargetRewrite
121121
// PASSES-NEXT: FIRToLLVMLowering
122+
// PASSES-NEXT: ReconcileUnrealizedCasts
122123
// PASSES-NEXT: LLVMIRLoweringPass

0 commit comments

Comments
 (0)