Skip to content

[flang] Add lowering of volatile references #132486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8a5c284
[flang] Add represention of volatile references
ashermancinelli Mar 20, 2025
2526bf2
comments
ashermancinelli Apr 9, 2025
91094f7
Merge branch 'main' of https://github.com/llvm/llvm-project into ajm/…
ashermancinelli Apr 10, 2025
a9b8676
Add tests, handle more memcpy cases
ashermancinelli Apr 11, 2025
8da078b
Fix tests on windows
ashermancinelli Apr 11, 2025
dd7908a
Fix file path string in filecheck tests
ashermancinelli Apr 11, 2025
47e51b0
Merge branch 'main' of https://github.com/llvm/llvm-project into ajm/…
ashermancinelli Apr 15, 2025
bdc3036
Test all combos of volatile pointer and target
ashermancinelli Apr 15, 2025
1ea399d
Refine lowering tests
ashermancinelli Apr 15, 2025
7fe745f
Enable volatile for declarations of volatile boxes
ashermancinelli Apr 15, 2025
e2955cc
Propagate volatile from other kinds of symbols
ashermancinelli Apr 16, 2025
56a09d7
Cast user argument char boxes
ashermancinelli Apr 16, 2025
54c9d53
Allow volatility mismatch when converting to llvm
ashermancinelli Apr 16, 2025
616804e
Fix volatile pointer assignments to null
ashermancinelli Apr 17, 2025
047150c
Handle select rank constructs
ashermancinelli Apr 17, 2025
8d36f3c
Handle character assignments
ashermancinelli Apr 17, 2025
0040f32
Remove hashed filepath from test
ashermancinelli Apr 17, 2025
2be1324
Merge branch 'main' of https://github.com/llvm/llvm-project into ajm/…
ashermancinelli Apr 22, 2025
2735369
Add loc() tests and relax convert op verification
ashermancinelli Apr 22, 2025
394dc51
Fix volatile type handling in openmp target data mappings
ashermancinelli Apr 22, 2025
8aa2b10
Add CSE tests for hlfir assign and dotprod
ashermancinelli Apr 22, 2025
417c97e
Merge branch 'main' of https://github.com/llvm/llvm-project into ajm/…
ashermancinelli Apr 29, 2025
a07d976
Merge branch 'main' into ajm/flang-support-volatile
ashermancinelli Apr 29, 2025
3af3481
Merge branch 'ajm/flang-support-volatile' of github.com:ashermancinel…
ashermancinelli Apr 29, 2025
b11dbda
Update documentation
ashermancinelli Apr 30, 2025
911fb3d
Merge branch 'main' of https://github.com/llvm/llvm-project into ajm/…
ashermancinelli Apr 30, 2025
904d16c
Update documentation
ashermancinelli Apr 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion flang/docs/FortranStandardsSupport.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ All features except those listed in the following table are supported.
|------------------------------------------------------------|--------|---------------------------------------------------------|
| Parameterized Derived Types | P | PDT with length type parameters is not supported. See [Proposal](ParameterizedDerivedTypes.md) |
| Assignment to allocatable | P | Assignment to whole allocatable in FORALL is not implemented |
| The VOLATILE attribute | P | VOLATILE in procedure interfaces is not implemented |
| Asynchronous input/output | P | IO will happen synchronously |
| MIN/MAX extensions for CHARACTER | P | Some variants are not supported |

Expand Down
2 changes: 2 additions & 0 deletions flang/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ page](https://llvm.org/releases/).

## Major New Features

* Initial support for VOLATILE variables and procedure interface arguments has been added.

## Bug Fixes

## Non-comprehensive list of changes in this release
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Optimizer/Builder/BoxValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class AbstractIrBox : public AbstractBox, public AbstractArrayBox {
auto ty = getBoxTy().getEleTy();
if (fir::isa_ref_type(ty))
return ty;
return fir::ReferenceType::get(ty, fir::isa_volatile_type(ty));
return fir::ReferenceType::get(ty, fir::isa_volatile_type(getBoxTy()));
}

/// Get the scalar type related to the described entity
Expand Down
6 changes: 4 additions & 2 deletions flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -829,14 +829,16 @@ template <int N, typename A>
void createArguments(llvm::SmallVectorImpl<mlir::Value> &result,
fir::FirOpBuilder &builder, mlir::Location loc,
mlir::FunctionType fTy, A arg) {
result.emplace_back(builder.createConvert(loc, fTy.getInput(N), arg));
result.emplace_back(
builder.createConvertWithVolatileCast(loc, fTy.getInput(N), arg));
}

template <int N, typename A, typename... As>
void createArguments(llvm::SmallVectorImpl<mlir::Value> &result,
fir::FirOpBuilder &builder, mlir::Location loc,
mlir::FunctionType fTy, A arg, As... args) {
result.emplace_back(builder.createConvert(loc, fTy.getInput(N), arg));
result.emplace_back(
builder.createConvertWithVolatileCast(loc, fTy.getInput(N), arg));
createArguments<N + 1>(result, builder, loc, fTy, args...);
}
} // namespace helper
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Optimizer/Dialect/FIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2755,7 +2755,7 @@ def fir_AddrOfOp : fir_OneResultOp<"address_of", [NoMemoryEffect]> {
let assemblyFormat = "`(` $symbol `)` attr-dict `:` type($resTy)";
}

def fir_VolatileCastOp : fir_SimpleOneResultOp<"volatile_cast", [NoMemoryEffect]> {
def fir_VolatileCastOp : fir_SimpleOneResultOp<"volatile_cast", [Pure]> {
let summary = "cast between volatile and non-volatile types";
let description = [{
Cast between volatile and non-volatile types. The types must be otherwise
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Optimizer/Dialect/FIRType.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@ inline mlir::Type wrapInClassOrBoxType(mlir::Type eleTy,
return fir::BoxType::get(eleTy);
}

/// Re-create the given type with the given volatility, if this is a type
/// that can represent volatility.
mlir::Type updateTypeWithVolatility(mlir::Type type, bool isVolatile);

/// Return the elementType where intrinsic types are replaced with none for
/// unlimited polymorphic entities.
///
Expand Down
5 changes: 5 additions & 0 deletions flang/include/flang/Optimizer/Dialect/FIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ def fir_ReferenceType : FIR_Type<"Reference", "ref"> {

let description = [{
The type of a reference to an entity in memory.

References can be volatile. Any ops taking an operand of a volatile
reference must set their memory effects appropriately. Accesses of
volatile references are currently modeled as read and write effects
to a specific memory resource.
}];

let parameters = (ins "mlir::Type":$eleTy, "bool":$isVolatile);
Expand Down
16 changes: 10 additions & 6 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// tags all result variables with one of the largest types to allow
// them to share the same storage. Convert this to the actual type.
if (resultRef.getType() != resultRefType)
resultRef = builder->createConvert(loc, resultRefType, resultRef);
resultRef = builder->createConvertWithVolatileCast(
loc, resultRefType, resultRef);
return builder->create<fir::LoadOp>(loc, resultRef);
});
genExitRoutine(false, resultVal);
Expand Down Expand Up @@ -3732,10 +3733,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
builder->createMinusOneInteger(loc, builder->getIndexType())};
mlir::Value baseAddr =
hlfir::genVariableRawAddress(loc, *builder, selector);
const bool isVolatile = fir::isa_volatile_type(selector.getType());
mlir::Type eleType =
fir::unwrapSequenceType(fir::unwrapRefType(baseAddr.getType()));
mlir::Type rank1Type =
fir::ReferenceType::get(builder->getVarLenSeqTy(eleType, 1));
mlir::Type rank1Type = fir::ReferenceType::get(
builder->getVarLenSeqTy(eleType, 1), isVolatile);
baseAddr = builder->createConvert(loc, rank1Type, baseAddr);
if (selector.isCharacter()) {
mlir::Value len = hlfir::genCharLength(loc, *builder, selector);
Expand All @@ -3755,7 +3757,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
mlir::cast<fir::BaseBoxType>(fir::unwrapRefType(selector.getType()));
mlir::Type newBoxType = boxTy.getBoxTypeWithNewShape(rank);
if (fir::isa_ref_type(selector.getType()))
newBoxType = fir::ReferenceType::get(newBoxType);
newBoxType = fir::ReferenceType::get(
newBoxType, fir::isa_volatile_type(selector.getType()));
// Give rank info to value via cast, and get rid of the box if not needed
// (simple scalars, contiguous arrays... This is done by
// translateVariableToExtendedValue).
Expand Down Expand Up @@ -5491,8 +5494,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// return, PassBy::AddressAndLength should be retired.
mlir::Location loc = toLocation();
fir::factory::CharacterExprHelper charHelp{*builder, loc};
mlir::Value box =
charHelp.createEmboxChar(arg.firArgument, arg.firLength);
mlir::Value casted =
builder->createVolatileCast(loc, false, arg.firArgument);
mlir::Value box = charHelp.createEmboxChar(casted, arg.firLength);
mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult);
} else {
if (arg.entity.has_value()) {
Expand Down
8 changes: 3 additions & 5 deletions flang/lib/Lower/CallInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1111,10 +1111,7 @@ class Fortran::lower::CallInterfaceImpl {
addMLIRAttr(fir::getContiguousAttrName());
if (obj.attrs.test(Attrs::Value))
isValueAttr = true; // TODO: do we want an mlir::Attribute as well?
if (obj.attrs.test(Attrs::Volatile)) {
TODO(loc, "VOLATILE in procedure interface");
addMLIRAttr(fir::getVolatileAttrName());
}

// obj.attrs.test(Attrs::Asynchronous) does not impact the way the argument
// is passed given flang implement asynch IO synchronously. However, it's
// added to determine whether the argument is captured.
Expand Down Expand Up @@ -1151,7 +1148,8 @@ class Fortran::lower::CallInterfaceImpl {

if (obj.attrs.test(Attrs::Allocatable) || obj.attrs.test(Attrs::Pointer)) {
// Pass as fir.ref<fir.box> or fir.ref<fir.class>
mlir::Type boxRefType = fir::ReferenceType::get(boxType);
const bool isVolatile = obj.attrs.test(Attrs::Volatile);
mlir::Type boxRefType = fir::ReferenceType::get(boxType, isVolatile);
addFirOperand(boxRefType, nextPassedArgPosition(), Property::MutableBox,
attrs);
addPassedArg(PassEntityBy::MutableBox, entity, characteristics);
Expand Down
5 changes: 4 additions & 1 deletion flang/lib/Lower/ConvertCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,7 +1369,10 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
// it according to the interface.
mlir::Value addr;
if (mlir::isa<fir::BoxCharType>(dummyTypeWithActualRank)) {
addr = hlfir::genVariableBoxChar(loc, builder, entity);
// Cast the argument to match the volatility of the dummy argument.
auto nonVolatileEntity = hlfir::Entity{builder.createVolatileCast(
loc, fir::isa_volatile_type(dummyType), entity)};
addr = hlfir::genVariableBoxChar(loc, builder, nonVolatileEntity);
} else if (mlir::isa<fir::BaseBoxType>(dummyTypeWithActualRank)) {
entity = hlfir::genVariableBox(loc, builder, entity);
// Ensures the box has the right attributes and that it holds an
Expand Down
12 changes: 8 additions & 4 deletions flang/lib/Lower/ConvertExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2705,7 +2705,7 @@ class ScalarExprLowering {
mlir::isa<fir::BoxCharType>(funcTy.getResult(0))) {
auto boxTy =
mlir::cast<fir::BoxCharType>(funcTy.getResult(0));
mlir::Value ref = builder.createConvert(
mlir::Value ref = builder.createConvertWithVolatileCast(
loc, builder.getRefType(boxTy.getEleTy()), x.getAddr());
auto len = builder.create<fir::UndefOp>(
loc, builder.getCharacterLengthType());
Expand Down Expand Up @@ -6306,7 +6306,8 @@ class ArrayExprLowering {
mlir::Value buffi = computeCoordinate(buff, off);
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
builder, loc, memcpyType(), buffi, v.getAddr(), byteSz);
createCallMemcpy(args, /*isVolatile=*/false);
const bool isVolatile = fir::isa_volatile_type(v.getAddr().getType());
createCallMemcpy(args, isVolatile);

// Save the incremented buffer position.
builder.create<fir::StoreOp>(loc, endOff, buffPos);
Expand Down Expand Up @@ -6356,7 +6357,9 @@ class ArrayExprLowering {
mlir::Value buffi = computeCoordinate(buff, off);
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
builder, loc, memcpyType(), buffi, v.getAddr(), eleSz);
createCallMemcpy(args, /*isVolatile=*/false);
const bool isVolatile =
fir::isa_volatile_type(v.getAddr().getType());
createCallMemcpy(args, isVolatile);

builder.create<fir::StoreOp>(loc, plusOne, buffPos);
}
Expand Down Expand Up @@ -7013,7 +7016,8 @@ class ArrayExprLowering {
components.resetExtendCoorRef();
auto ptrEleTy = fir::PointerType::get(eleTy);
auto ptrAddr = builder.createConvert(loc, ptrEleTy, addr);
auto boxTy = fir::BoxType::get(ptrEleTy);
auto boxTy = fir::BoxType::get(
ptrEleTy, fir::isa_volatile_type(addr.getType()));
// FIXME: The typeparams to the load may be different than those of
// the subobject.
if (components.hasExtendCoorRef())
Expand Down
32 changes: 30 additions & 2 deletions flang/lib/Lower/ConvertExprToHLFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class HlfirDesignatorBuilder {
!partInfo.resultShape)
partInfo.resultShape =
hlfir::genShape(getLoc(), getBuilder(), *partInfo.base);

// Dynamic type of polymorphic base must be kept if the designator is
// polymorphic.
if (isPolymorphic(designatorNode))
Expand All @@ -215,7 +216,25 @@ class HlfirDesignatorBuilder {
return fir::BoxCharType::get(charType.getContext(), charType.getFKind());

// When volatile is enabled, enable volatility on the designatory type.
const bool isVolatile = false;
bool isVolatile = false;

// Check if this should be a volatile reference
if constexpr (std::is_same_v<std::decay_t<T>,
Fortran::evaluate::SymbolRef>) {
if (designatorNode.get().GetUltimate().attrs().test(
Fortran::semantics::Attr::VOLATILE))
isVolatile = true;
} else if constexpr (std::is_same_v<std::decay_t<T>,
Fortran::evaluate::ArrayRef>) {
if (designatorNode.base().GetLastSymbol().attrs().test(
Fortran::semantics::Attr::VOLATILE))
isVolatile = true;
} else if constexpr (std::is_same_v<std::decay_t<T>,
Fortran::evaluate::Component>) {
if (designatorNode.GetLastSymbol().attrs().test(
Fortran::semantics::Attr::VOLATILE))
isVolatile = true;
}

// Arrays with non default lower bounds or dynamic length or dynamic extent
// need a fir.box to hold the dynamic or lower bound information.
Expand All @@ -230,6 +249,12 @@ class HlfirDesignatorBuilder {
/*namedConstantSectionsAreAlwaysContiguous=*/false))
return fir::BoxType::get(resultValueType, isVolatile);

// Check if the base type is volatile
if (partInfo.base.has_value()) {
mlir::Type baseType = partInfo.base.value().getType();
isVolatile = fir::isa_volatile_type(baseType);
}

// Other designators can be handled as raw addresses.
return fir::ReferenceType::get(resultValueType, isVolatile);
}
Expand Down Expand Up @@ -441,7 +466,10 @@ class HlfirDesignatorBuilder {
// hlfir.designate result will be a pointer/allocatable.
PartInfo partInfo;
mlir::Type componentType = visitComponentImpl(component, partInfo).second;
mlir::Type designatorType = fir::ReferenceType::get(componentType);
const auto isVolatile =
fir::isa_volatile_type(partInfo.base.value().getBase().getType());
mlir::Type designatorType =
fir::ReferenceType::get(componentType, isVolatile);
fir::FortranVariableFlagsAttr attributes =
Fortran::lower::translateSymbolAttributes(getBuilder().getContext(),
component.GetLastSymbol());
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Lower/HostAssociations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ class CapturedSimpleScalars : public CapturedSymbols<CapturedSimpleScalars> {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
mlir::Type typeInTuple = fir::dyn_cast_ptrEleTy(args.addrInTuple.getType());
assert(typeInTuple && "addrInTuple must be an address");
mlir::Value castBox = builder.createConvert(args.loc, typeInTuple,
fir::getBase(args.hostValue));
mlir::Value castBox = builder.createConvertWithVolatileCast(
args.loc, typeInTuple, fir::getBase(args.hostValue));
builder.create<fir::StoreOp>(args.loc, castBox, args.addrInTuple);
}

Expand Down
6 changes: 5 additions & 1 deletion flang/lib/Lower/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,11 @@ createIoRuntimeCallForItem(Fortran::lower::AbstractConverter &converter,
} else {
mlir::Value itemAddr = fir::getBase(item);
mlir::Type itemTy = fir::unwrapPassByRefType(itemAddr.getType());
inputFuncArgs.push_back(builder.createConvert(loc, argType, itemAddr));

// Handle conversion between volatile and non-volatile reference types
// Need to explicitly cast when volatility qualification differs
inputFuncArgs.push_back(
builder.createConvertWithVolatileCast(loc, argType, itemAddr));
fir::factory::CharacterExprHelper charHelper{builder, loc};
if (charHelper.isCharacterScalar(itemTy)) {
mlir::Value len = fir::getLen(item);
Expand Down
8 changes: 6 additions & 2 deletions flang/lib/Optimizer/Builder/Character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ fir::factory::CharacterExprHelper::createElementAddr(mlir::Value buffer,
auto extent = fir::SequenceType::getUnknownExtent();
if (charTy.getLen() != fir::CharacterType::unknownLen())
extent = charTy.getLen();
auto coorTy = builder.getRefType(fir::SequenceType::get({extent}, singleTy));
const bool isVolatile = fir::isa_volatile_type(buffer.getType());
auto sequenceType = fir::SequenceType::get({extent}, singleTy);
auto coorTy = builder.getRefType(sequenceType, isVolatile);

auto coor = builder.createConvert(loc, coorTy, buffer);
auto i = builder.createConvert(loc, builder.getIndexType(), index);
Expand Down Expand Up @@ -330,6 +332,8 @@ void fir::factory::CharacterExprHelper::createCopy(
// If the src and dest are the same KIND, then use memmove to move the bits.
// We don't have to worry about overlapping ranges with memmove.
if (getCharacterKind(dest.getBuffer().getType()) == kind) {
const bool isVolatile = fir::isa_volatile_type(fromBuff.getType()) ||
fir::isa_volatile_type(toBuff.getType());
auto bytes = builder.getKindMap().getCharacterBitsize(kind) / 8;
auto i64Ty = builder.getI64Type();
auto kindBytes = builder.createIntegerConstant(loc, i64Ty, bytes);
Expand All @@ -341,7 +345,7 @@ void fir::factory::CharacterExprHelper::createCopy(
auto toPtr = builder.createConvert(loc, llvmPointerType, toBuff);
auto fromPtr = builder.createConvert(loc, llvmPointerType, fromBuff);
builder.create<mlir::LLVM::MemmoveOp>(loc, toPtr, fromPtr, totalBytes,
/*isVolatile=*/false);
isVolatile);
return;
}

Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Optimizer/Builder/FIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,9 @@ mlir::Value fir::FirOpBuilder::createConvert(mlir::Location loc,
void fir::FirOpBuilder::createStoreWithConvert(mlir::Location loc,
mlir::Value val,
mlir::Value addr) {
mlir::Value cast =
createConvert(loc, fir::unwrapRefType(addr.getType()), val);
mlir::Type unwrapedRefType = fir::unwrapRefType(addr.getType());
val = createVolatileCast(loc, fir::isa_volatile_type(unwrapedRefType), val);
mlir::Value cast = createConvert(loc, unwrapedRefType, val);
create<fir::StoreOp>(loc, cast, addr);
}

Expand Down
1 change: 1 addition & 0 deletions flang/lib/Optimizer/Builder/HLFIRTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "flang/Optimizer/Builder/MutableBox.h"
#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "mlir/IR/IRMapping.h"
#include "mlir/Support/LLVM.h"
Expand Down
11 changes: 8 additions & 3 deletions flang/lib/Optimizer/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3556,7 +3556,9 @@ struct StoreOpConversion : public fir::FIROpConversion<fir::StoreOp> {
mlir::Value llvmValue = adaptor.getValue();
mlir::Value llvmMemref = adaptor.getMemref();
mlir::LLVM::AliasAnalysisOpInterface newOp;
const bool isVolatile = fir::isa_volatile_type(store.getMemref().getType());
const bool isVolatile =
fir::isa_volatile_type(store.getMemref().getType()) ||
fir::isa_volatile_type(store.getValue().getType());
if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(storeTy)) {
mlir::Type llvmBoxTy = lowerTy().convertBoxTypeAsStruct(boxTy);
// Always use memcpy because LLVM is not as effective at optimizing
Expand Down Expand Up @@ -3595,6 +3597,9 @@ struct CopyOpConversion : public fir::FIROpConversion<fir::CopyOp> {
matchAndRewrite(fir::CopyOp copy, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
mlir::Location loc = copy.getLoc();
const bool isVolatile =
fir::isa_volatile_type(copy.getSource().getType()) ||
fir::isa_volatile_type(copy.getDestination().getType());
mlir::Value llvmSource = adaptor.getSource();
mlir::Value llvmDestination = adaptor.getDestination();
mlir::Type i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
Expand All @@ -3605,10 +3610,10 @@ struct CopyOpConversion : public fir::FIROpConversion<fir::CopyOp> {
mlir::LLVM::AliasAnalysisOpInterface newOp;
if (copy.getNoOverlap())
newOp = rewriter.create<mlir::LLVM::MemcpyOp>(
loc, llvmDestination, llvmSource, copySize, /*isVolatile=*/false);
loc, llvmDestination, llvmSource, copySize, isVolatile);
else
newOp = rewriter.create<mlir::LLVM::MemmoveOp>(
loc, llvmDestination, llvmSource, copySize, /*isVolatile=*/false);
loc, llvmDestination, llvmSource, copySize, isVolatile);

// TODO: propagate TBAA once FirAliasTagOpInterface added to CopyOp.
attachTBAATag(newOp, copyTy, copyTy, nullptr);
Expand Down
Loading