Skip to content

Commit 7fe745f

Browse files
Enable volatile for declarations of volatile boxes
1 parent 1ea399d commit 7fe745f

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,35 @@ static bool hasExplicitLowerBounds(mlir::Value shape) {
207207
mlir::isa<fir::ShapeShiftType, fir::ShiftType>(shape.getType());
208208
}
209209

210+
static std::pair<mlir::Type, mlir::Value>
211+
updateTypeWithVolatility(mlir::Type inputType, mlir::Value memref,
212+
mlir::OpBuilder &builder,
213+
fir::FortranVariableFlagsAttr fortran_attrs) {
214+
if (mlir::isa<fir::BoxType, fir::ReferenceType>(inputType) && fortran_attrs &&
215+
bitEnumContainsAny(fortran_attrs.getFlags(),
216+
fir::FortranVariableFlagsEnum::fortran_volatile)) {
217+
const bool isPointer = bitEnumContainsAny(
218+
fortran_attrs.getFlags(), fir::FortranVariableFlagsEnum::pointer);
219+
auto updateType = [&](auto t) {
220+
using FIRT = decltype(t);
221+
// If an entity is a pointer, the entity it points to is volatile, as far
222+
// as consumers of the pointer are concerned.
223+
auto elementType = t.getEleTy();
224+
const bool elementTypeIsVolatile =
225+
isPointer || fir::isa_volatile_type(elementType);
226+
auto newEleTy =
227+
fir::updateTypeWithVolatility(elementType, elementTypeIsVolatile);
228+
inputType = FIRT::get(newEleTy, true);
229+
};
230+
llvm::TypeSwitch<mlir::Type>(inputType)
231+
.Case<fir::ReferenceType, fir::BoxType>(updateType)
232+
.Default([](mlir::Type t) { return t; });
233+
memref =
234+
builder.create<fir::VolatileCastOp>(memref.getLoc(), inputType, memref);
235+
}
236+
return std::make_pair(inputType, memref);
237+
}
238+
210239
void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
211240
mlir::OperationState &result, mlir::Value memref,
212241
llvm::StringRef uniq_name, mlir::Value shape,
@@ -217,22 +246,8 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
217246
auto nameAttr = builder.getStringAttr(uniq_name);
218247
mlir::Type inputType = memref.getType();
219248
bool hasExplicitLbs = hasExplicitLowerBounds(shape);
220-
if (auto refType = mlir::dyn_cast<fir::ReferenceType>(inputType);
221-
fortran_attrs && refType &&
222-
bitEnumContainsAny(fortran_attrs.getFlags(),
223-
fir::FortranVariableFlagsEnum::fortran_volatile)) {
224-
auto eleType = refType.getEleTy();
225-
const bool isPointer = bitEnumContainsAny(
226-
fortran_attrs.getFlags(), fir::FortranVariableFlagsEnum::pointer);
227-
if (isPointer) {
228-
// If an entity is a pointer, the entity it points to is volatile, as far
229-
// as consumers of the pointer are concerned.
230-
eleType = fir::updateTypeWithVolatility(eleType, true);
231-
}
232-
inputType = fir::ReferenceType::get(eleType, /*isVolatile=*/true);
233-
memref =
234-
builder.create<fir::VolatileCastOp>(memref.getLoc(), inputType, memref);
235-
}
249+
std::tie(inputType, memref) =
250+
updateTypeWithVolatility(inputType, memref, builder, fortran_attrs);
236251
mlir::Type hlfirVariableType =
237252
getHLFIRVariableType(inputType, hasExplicitLbs);
238253
build(builder, result, {hlfirVariableType, inputType}, memref, shape,

flang/test/Lower/volatile3.f90

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ subroutine sub_volatile_array_pointer(arr)
4444
end subroutine
4545
end program
4646

47+
4748
! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "p"} {
4849
! CHECK: %[[VAL_0:.*]] = arith.constant 10 : index
4950
! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFEnonvolatile_array) : !fir.ref<!fir.array<10xi32>>
@@ -117,9 +118,10 @@ subroutine sub_volatile_array_pointer(arr)
117118
! CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
118119
! CHECK: %[[VAL_2:.*]] = arith.constant 5 : i32
119120
! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope
120-
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_3]] {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFFsub_volatile_array_assumed_shapeEarr"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
121-
! CHECK: %[[VAL_5:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_1]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
122-
! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_5]] : i32, !fir.ref<i32>
121+
! CHECK: %[[VAL_4:.*]] = fir.volatile_cast %[[VAL_0]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>, volatile>
122+
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] dummy_scope %[[VAL_3]] {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFFsub_volatile_array_assumed_shapeEarr"} : (!fir.box<!fir.array<?xi32>, volatile>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>, volatile>, !fir.box<!fir.array<?xi32>, volatile>)
123+
! CHECK: %[[VAL_6:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_1]]) : (!fir.box<!fir.array<?xi32>, volatile>, index) -> !fir.ref<i32, volatile>
124+
! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_6]] : i32, !fir.ref<i32, volatile>
123125
! CHECK: return
124126
! CHECK: }
125127

0 commit comments

Comments
 (0)