@@ -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