@@ -689,6 +689,20 @@ struct CmpcOpConversion : public fir::FIROpConversion<fir::CmpcOp> {
689689 }
690690};
691691
692+ // / fir.volatile_cast is only useful at the fir level. Once we lower to LLVM,
693+ // / volatility is described by setting volatile attributes on the LLVM ops.
694+ struct VolatileCastOpConversion
695+ : public fir::FIROpConversion<fir::VolatileCastOp> {
696+ using FIROpConversion::FIROpConversion;
697+
698+ llvm::LogicalResult
699+ matchAndRewrite (fir::VolatileCastOp volatileCast, OpAdaptor adaptor,
700+ mlir::ConversionPatternRewriter &rewriter) const override {
701+ rewriter.replaceOp (volatileCast, adaptor.getOperands ()[0 ]);
702+ return mlir::success ();
703+ }
704+ };
705+
692706// / convert value of from-type to value of to-type
693707struct ConvertOpConversion : public fir ::FIROpConversion<fir::ConvertOp> {
694708 using FIROpConversion::FIROpConversion;
@@ -3224,6 +3238,7 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
32243238 mlir::ConversionPatternRewriter &rewriter) const override {
32253239
32263240 mlir::Type llvmLoadTy = convertObjectType (load.getType ());
3241+ const bool isVolatile = fir::isa_volatile_type (load.getMemref ().getType ());
32273242 if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(load.getType ())) {
32283243 // fir.box is a special case because it is considered an ssa value in
32293244 // fir, but it is lowered as a pointer to a descriptor. So
@@ -3253,16 +3268,17 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
32533268 mlir::Value boxSize =
32543269 computeBoxSize (loc, boxTypePair, inputBoxStorage, rewriter);
32553270 auto memcpy = rewriter.create <mlir::LLVM::MemcpyOp>(
3256- loc, newBoxStorage, inputBoxStorage, boxSize, /* isVolatile= */ false );
3271+ loc, newBoxStorage, inputBoxStorage, boxSize, isVolatile);
32573272
32583273 if (std::optional<mlir::ArrayAttr> optionalTag = load.getTbaa ())
32593274 memcpy.setTBAATags (*optionalTag);
32603275 else
32613276 attachTBAATag (memcpy, boxTy, boxTy, nullptr );
32623277 rewriter.replaceOp (load, newBoxStorage);
32633278 } else {
3264- auto loadOp = rewriter.create <mlir::LLVM::LoadOp>(
3279+ mlir::LLVM::LoadOp loadOp = rewriter.create <mlir::LLVM::LoadOp>(
32653280 load.getLoc (), llvmLoadTy, adaptor.getOperands (), load->getAttrs ());
3281+ loadOp.setVolatile_ (isVolatile);
32663282 if (std::optional<mlir::ArrayAttr> optionalTag = load.getTbaa ())
32673283 loadOp.setTBAATags (*optionalTag);
32683284 else
@@ -3540,17 +3556,22 @@ struct StoreOpConversion : public fir::FIROpConversion<fir::StoreOp> {
35403556 mlir::Value llvmValue = adaptor.getValue ();
35413557 mlir::Value llvmMemref = adaptor.getMemref ();
35423558 mlir::LLVM::AliasAnalysisOpInterface newOp;
3559+ const bool isVolatile = fir::isa_volatile_type (store.getMemref ().getType ());
35433560 if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(storeTy)) {
35443561 mlir::Type llvmBoxTy = lowerTy ().convertBoxTypeAsStruct (boxTy);
35453562 // Always use memcpy because LLVM is not as effective at optimizing
35463563 // aggregate loads/stores as it is optimizing memcpy.
35473564 TypePair boxTypePair{boxTy, llvmBoxTy};
35483565 mlir::Value boxSize =
35493566 computeBoxSize (loc, boxTypePair, llvmValue, rewriter);
3550- newOp = rewriter.create <mlir::LLVM::MemcpyOp>(
3551- loc, llvmMemref, llvmValue, boxSize, /* isVolatile= */ false );
3567+ newOp = rewriter.create <mlir::LLVM::MemcpyOp>(loc, llvmMemref, llvmValue,
3568+ boxSize, isVolatile);
35523569 } else {
3553- newOp = rewriter.create <mlir::LLVM::StoreOp>(loc, llvmValue, llvmMemref);
3570+ mlir::LLVM::StoreOp storeOp =
3571+ rewriter.create <mlir::LLVM::StoreOp>(loc, llvmValue, llvmMemref);
3572+ if (isVolatile)
3573+ storeOp.setVolatile_ (true );
3574+ newOp = storeOp;
35543575 }
35553576 if (std::optional<mlir::ArrayAttr> optionalTag = store.getTbaa ())
35563577 newOp.setTBAATags (*optionalTag);
@@ -4193,21 +4214,22 @@ void fir::populateFIRToLLVMConversionPatterns(
41934214 BoxIsAllocOpConversion, BoxIsArrayOpConversion, BoxIsPtrOpConversion,
41944215 BoxOffsetOpConversion, BoxProcHostOpConversion, BoxRankOpConversion,
41954216 BoxTypeCodeOpConversion, BoxTypeDescOpConversion, CallOpConversion,
4196- CmpcOpConversion, ConvertOpConversion, CoordinateOpConversion,
4197- CopyOpConversion, DTEntryOpConversion, DeclareOpConversion,
4198- DivcOpConversion, EmboxOpConversion, EmboxCharOpConversion,
4199- EmboxProcOpConversion, ExtractValueOpConversion, FieldIndexOpConversion,
4200- FirEndOpConversion, FreeMemOpConversion, GlobalLenOpConversion,
4201- GlobalOpConversion, InsertOnRangeOpConversion, IsPresentOpConversion,
4202- LenParamIndexOpConversion, LoadOpConversion, MulcOpConversion,
4203- NegcOpConversion, NoReassocOpConversion, SelectCaseOpConversion,
4204- SelectOpConversion, SelectRankOpConversion, SelectTypeOpConversion,
4205- ShapeOpConversion, ShapeShiftOpConversion, ShiftOpConversion,
4206- SliceOpConversion, StoreOpConversion, StringLitOpConversion,
4207- SubcOpConversion, TypeDescOpConversion, TypeInfoOpConversion,
4208- UnboxCharOpConversion, UnboxProcOpConversion, UndefOpConversion,
4209- UnreachableOpConversion, XArrayCoorOpConversion, XEmboxOpConversion,
4210- XReboxOpConversion, ZeroOpConversion>(converter, options);
4217+ CmpcOpConversion, VolatileCastOpConversion, ConvertOpConversion,
4218+ CoordinateOpConversion, CopyOpConversion, DTEntryOpConversion,
4219+ DeclareOpConversion, DivcOpConversion, EmboxOpConversion,
4220+ EmboxCharOpConversion, EmboxProcOpConversion, ExtractValueOpConversion,
4221+ FieldIndexOpConversion, FirEndOpConversion, FreeMemOpConversion,
4222+ GlobalLenOpConversion, GlobalOpConversion, InsertOnRangeOpConversion,
4223+ IsPresentOpConversion, LenParamIndexOpConversion, LoadOpConversion,
4224+ MulcOpConversion, NegcOpConversion, NoReassocOpConversion,
4225+ SelectCaseOpConversion, SelectOpConversion, SelectRankOpConversion,
4226+ SelectTypeOpConversion, ShapeOpConversion, ShapeShiftOpConversion,
4227+ ShiftOpConversion, SliceOpConversion, StoreOpConversion,
4228+ StringLitOpConversion, SubcOpConversion, TypeDescOpConversion,
4229+ TypeInfoOpConversion, UnboxCharOpConversion, UnboxProcOpConversion,
4230+ UndefOpConversion, UnreachableOpConversion, XArrayCoorOpConversion,
4231+ XEmboxOpConversion, XReboxOpConversion, ZeroOpConversion>(converter,
4232+ options);
42114233
42124234 // Patterns that are populated without a type converter do not trigger
42134235 // target materializations for the operands of the root op.
0 commit comments