@@ -689,6 +689,20 @@ struct CmpcOpConversion : public fir::FIROpConversion<fir::CmpcOp> {
689
689
}
690
690
};
691
691
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
+
692
706
// / convert value of from-type to value of to-type
693
707
struct ConvertOpConversion : public fir ::FIROpConversion<fir::ConvertOp> {
694
708
using FIROpConversion::FIROpConversion;
@@ -3224,6 +3238,7 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
3224
3238
mlir::ConversionPatternRewriter &rewriter) const override {
3225
3239
3226
3240
mlir::Type llvmLoadTy = convertObjectType (load.getType ());
3241
+ const bool isVolatile = fir::isa_volatile_type (load.getMemref ().getType ());
3227
3242
if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(load.getType ())) {
3228
3243
// fir.box is a special case because it is considered an ssa value in
3229
3244
// fir, but it is lowered as a pointer to a descriptor. So
@@ -3253,16 +3268,17 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
3253
3268
mlir::Value boxSize =
3254
3269
computeBoxSize (loc, boxTypePair, inputBoxStorage, rewriter);
3255
3270
auto memcpy = rewriter.create <mlir::LLVM::MemcpyOp>(
3256
- loc, newBoxStorage, inputBoxStorage, boxSize, /* isVolatile= */ false );
3271
+ loc, newBoxStorage, inputBoxStorage, boxSize, isVolatile);
3257
3272
3258
3273
if (std::optional<mlir::ArrayAttr> optionalTag = load.getTbaa ())
3259
3274
memcpy.setTBAATags (*optionalTag);
3260
3275
else
3261
3276
attachTBAATag (memcpy, boxTy, boxTy, nullptr );
3262
3277
rewriter.replaceOp (load, newBoxStorage);
3263
3278
} else {
3264
- auto loadOp = rewriter.create <mlir::LLVM::LoadOp>(
3279
+ mlir::LLVM::LoadOp loadOp = rewriter.create <mlir::LLVM::LoadOp>(
3265
3280
load.getLoc (), llvmLoadTy, adaptor.getOperands (), load->getAttrs ());
3281
+ loadOp.setVolatile_ (isVolatile);
3266
3282
if (std::optional<mlir::ArrayAttr> optionalTag = load.getTbaa ())
3267
3283
loadOp.setTBAATags (*optionalTag);
3268
3284
else
@@ -3540,17 +3556,22 @@ struct StoreOpConversion : public fir::FIROpConversion<fir::StoreOp> {
3540
3556
mlir::Value llvmValue = adaptor.getValue ();
3541
3557
mlir::Value llvmMemref = adaptor.getMemref ();
3542
3558
mlir::LLVM::AliasAnalysisOpInterface newOp;
3559
+ const bool isVolatile = fir::isa_volatile_type (store.getMemref ().getType ());
3543
3560
if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(storeTy)) {
3544
3561
mlir::Type llvmBoxTy = lowerTy ().convertBoxTypeAsStruct (boxTy);
3545
3562
// Always use memcpy because LLVM is not as effective at optimizing
3546
3563
// aggregate loads/stores as it is optimizing memcpy.
3547
3564
TypePair boxTypePair{boxTy, llvmBoxTy};
3548
3565
mlir::Value boxSize =
3549
3566
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);
3552
3569
} 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;
3554
3575
}
3555
3576
if (std::optional<mlir::ArrayAttr> optionalTag = store.getTbaa ())
3556
3577
newOp.setTBAATags (*optionalTag);
@@ -4193,21 +4214,22 @@ void fir::populateFIRToLLVMConversionPatterns(
4193
4214
BoxIsAllocOpConversion, BoxIsArrayOpConversion, BoxIsPtrOpConversion,
4194
4215
BoxOffsetOpConversion, BoxProcHostOpConversion, BoxRankOpConversion,
4195
4216
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);
4211
4233
4212
4234
// Patterns that are populated without a type converter do not trigger
4213
4235
// target materializations for the operands of the root op.
0 commit comments