Skip to content

Commit 54c9d53

Browse files
Allow volatility mismatch when converting to llvm
1 parent 56a09d7 commit 54c9d53

File tree

3 files changed

+81
-18
lines changed

3 files changed

+81
-18
lines changed

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,12 @@ bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) {
15291529
llvm::LogicalResult fir::ConvertOp::verify() {
15301530
mlir::Type inType = getValue().getType();
15311531
mlir::Type outType = getType();
1532-
if (fir::isa_volatile_type(inType) != fir::isa_volatile_type(outType))
1532+
// If we're converting to an LLVM pointer type in code generation, we don't
1533+
// need to check for volatility mismatch - volatility will be handled by the
1534+
// memory operations themselves at that point.
1535+
const bool toLLVMPointer = mlir::isa<mlir::LLVM::LLVMPointerType>(outType);
1536+
if (fir::isa_volatile_type(inType) != fir::isa_volatile_type(outType) &&
1537+
!toLLVMPointer)
15331538
return emitOpError("cannot convert between volatile and non-volatile "
15341539
"types, use fir.volatile_cast instead ")
15351540
<< inType << " / " << outType;

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static llvm::LogicalResult areMatchingTypes(Op &op, mlir::Type type1,
9696
}
9797

9898
//===----------------------------------------------------------------------===//
99-
// DeclareOp
99+
// AssignOp
100100
//===----------------------------------------------------------------------===//
101101

102102
/// Is this a fir.[ref/ptr/heap]<fir.[box/class]<fir.heap<T>>> type?
@@ -207,10 +207,9 @@ 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) {
210+
static std::pair<mlir::Type, mlir::Value> updateDeclareInputTypeWithVolatility(
211+
mlir::Type inputType, mlir::Value memref, mlir::OpBuilder &builder,
212+
fir::FortranVariableFlagsAttr fortran_attrs) {
214213
if (mlir::isa<fir::BoxType, fir::ReferenceType>(inputType) && fortran_attrs &&
215214
bitEnumContainsAny(fortran_attrs.getFlags(),
216215
fir::FortranVariableFlagsEnum::fortran_volatile)) {
@@ -246,8 +245,8 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
246245
auto nameAttr = builder.getStringAttr(uniq_name);
247246
mlir::Type inputType = memref.getType();
248247
bool hasExplicitLbs = hasExplicitLowerBounds(shape);
249-
std::tie(inputType, memref) =
250-
updateTypeWithVolatility(inputType, memref, builder, fortran_attrs);
248+
std::tie(inputType, memref) = updateDeclareInputTypeWithVolatility(
249+
inputType, memref, builder, fortran_attrs);
251250
mlir::Type hlfirVariableType =
252251
getHLFIRVariableType(inputType, hasExplicitLbs);
253252
build(builder, result, {hlfirVariableType, inputType}, memref, shape,

flang/test/Lower/volatile-string.f90

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,81 @@
11
! RUN: bbc %s -o - | FileCheck %s
22
program p
3-
character(3), volatile :: string = 'foo'
4-
call bar(string)
3+
character(3), volatile :: string = 'foo'
4+
character(3) :: nonvolatile_string
5+
integer :: i
6+
call bar(string)
7+
i = index(string, 'o')
8+
i = len(string)
9+
string = adjustl(string)
10+
nonvolatile_string = trim(string)
11+
nonvolatile_string = string
512
contains
613
subroutine bar(x)
714
character(3), volatile :: x
815
x = 'bar'
916
end subroutine
1017
end program
11-
1218
! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "p"} {
13-
! CHECK: %[[VAL_0:.*]] = arith.constant 3 : index
14-
! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFEstring) : !fir.ref<!fir.char<1,3>>
15-
! CHECK: %[[VAL_2:.*]] = fir.volatile_cast %[[VAL_1]] : (!fir.ref<!fir.char<1,3>>) -> !fir.ref<!fir.char<1,3>, volatile>
16-
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_0]] {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFEstring"} : (!fir.ref<!fir.char<1,3>, volatile>, index) -> (!fir.ref<!fir.char<1,3>, volatile>, !fir.ref<!fir.char<1,3>, volatile>)
17-
! CHECK: %[[VAL_4:.*]] = fir.volatile_cast %[[VAL_3]]#0 : (!fir.ref<!fir.char<1,3>, volatile>) -> !fir.ref<!fir.char<1,3>>
18-
! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_0]] : (!fir.ref<!fir.char<1,3>>, index) -> !fir.boxchar<1>
19-
! CHECK: fir.call @_QFPbar(%[[VAL_5]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
19+
! CHECK: %[[VAL_0:.*]] = arith.constant 10 : i32
20+
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : index
21+
! CHECK: %[[VAL_2:.*]] = arith.constant true
22+
! CHECK: %[[VAL_3:.*]] = arith.constant 9 : i32
23+
! CHECK: %[[VAL_4:.*]] = arith.constant 3 : i32
24+
! CHECK: %[[VAL_5:.*]] = arith.constant false
25+
! CHECK: %[[VAL_6:.*]] = arith.constant 1 : index
26+
! CHECK: %[[VAL_7:.*]] = arith.constant 3 : index
27+
! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
28+
! CHECK: %[[VAL_9:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,3>>>
29+
! CHECK: %[[VAL_10:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
30+
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
31+
! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.char<1,3> {bindc_name = "nonvolatile_string", uniq_name = "_QFEnonvolatile_string"}
32+
! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_12]] typeparams %[[VAL_7]] {uniq_name = "_QFEnonvolatile_string"} : (!fir.ref<!fir.char<1,3>>, index) -> (!fir.ref<!fir.char<1,3>>, !fir.ref<!fir.char<1,3>>)
33+
! CHECK: %[[VAL_14:.*]] = fir.address_of(@_QFEstring) : !fir.ref<!fir.char<1,3>>
34+
! CHECK: %[[VAL_15:.*]] = fir.volatile_cast %[[VAL_14]] : (!fir.ref<!fir.char<1,3>>) -> !fir.ref<!fir.char<1,3>, volatile>
35+
! CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_15]] typeparams %[[VAL_7]] {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFEstring"} : (!fir.ref<!fir.char<1,3>, volatile>, index) -> (!fir.ref<!fir.char<1,3>, volatile>, !fir.ref<!fir.char<1,3>, volatile>)
36+
! CHECK: %[[VAL_17:.*]] = fir.volatile_cast %[[VAL_16]]#0 : (!fir.ref<!fir.char<1,3>, volatile>) -> !fir.ref<!fir.char<1,3>>
37+
! CHECK: %[[VAL_18:.*]] = fir.emboxchar %[[VAL_17]], %[[VAL_7]] : (!fir.ref<!fir.char<1,3>>, index) -> !fir.boxchar<1>
38+
! CHECK: fir.call @_QFPbar(%[[VAL_18]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
39+
! CHECK: %[[VAL_19:.*]] = fir.address_of(@_QQclX6F) : !fir.ref<!fir.char<1>>
40+
! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_19]] typeparams %[[VAL_6]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX6F"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
41+
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_17]] : (!fir.ref<!fir.char<1,3>>) -> !fir.ref<i8>
42+
! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_7]] : (index) -> i64
43+
! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
44+
! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_6]] : (index) -> i64
45+
! CHECK: %[[VAL_25:.*]] = fir.call @_FortranAIndex1(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i8>, i64, !fir.ref<i8>, i64, i1) -> i64
46+
! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i64) -> i32
47+
! CHECK: hlfir.assign %[[VAL_26]] to %[[VAL_11]]#0 : i32, !fir.ref<i32>
48+
! CHECK: hlfir.assign %[[VAL_4]] to %[[VAL_11]]#0 : i32, !fir.ref<i32>
49+
! CHECK: %[[VAL_27:.*]] = fir.embox %[[VAL_16]]#0 : (!fir.ref<!fir.char<1,3>, volatile>) -> !fir.box<!fir.char<1,3>, volatile>
50+
! CHECK: %[[VAL_28:.*]] = fir.zero_bits !fir.heap<!fir.char<1,3>>
51+
! CHECK: %[[VAL_29:.*]] = fir.embox %[[VAL_28]] : (!fir.heap<!fir.char<1,3>>) -> !fir.box<!fir.heap<!fir.char<1,3>>>
52+
! CHECK: fir.store %[[VAL_29]] to %[[VAL_9]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,3>>>>
53+
! CHECK: %[[VAL_30:.*]] = fir.address_of(@_QQclXd1ee14519ece0b1bf697ca53870092e5) : !fir.ref<!fir.char<1,85>>
54+
! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<!fir.box<!fir.heap<!fir.char<1,3>>>>) -> !fir.ref<!fir.box<none>>
55+
! CHECK: %[[VAL_32:.*]] = fir.volatile_cast %[[VAL_27]] : (!fir.box<!fir.char<1,3>, volatile>) -> !fir.box<!fir.char<1,3>>
56+
! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.box<!fir.char<1,3>>) -> !fir.box<none>
57+
! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_30]] : (!fir.ref<!fir.char<1,85>>) -> !fir.ref<i8>
58+
! CHECK: fir.call @_FortranAAdjustl(%[[VAL_31]], %[[VAL_33]], %[[VAL_34]], %[[VAL_3]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
59+
! CHECK: %[[VAL_35:.*]] = fir.load %[[VAL_9]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,3>>>>
60+
! CHECK: %[[VAL_36:.*]] = fir.box_elesize %[[VAL_35]] : (!fir.box<!fir.heap<!fir.char<1,3>>>) -> index
61+
! CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_35]] : (!fir.box<!fir.heap<!fir.char<1,3>>>) -> !fir.heap<!fir.char<1,3>>
62+
! CHECK: %[[VAL_38:.*]]:2 = hlfir.declare %[[VAL_37]] typeparams %[[VAL_36]] {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap<!fir.char<1,3>>, index) -> (!fir.heap<!fir.char<1,3>>, !fir.heap<!fir.char<1,3>>)
63+
! CHECK: %[[VAL_39:.*]] = hlfir.as_expr %[[VAL_38]]#0 move %[[VAL_2]] : (!fir.heap<!fir.char<1,3>>, i1) -> !hlfir.expr<!fir.char<1,3>>
64+
! CHECK: hlfir.assign %[[VAL_39]] to %[[VAL_16]]#0 : !hlfir.expr<!fir.char<1,3>>, !fir.ref<!fir.char<1,3>, volatile>
65+
! CHECK: hlfir.destroy %[[VAL_39]] : !hlfir.expr<!fir.char<1,3>>
66+
! CHECK: %[[VAL_40:.*]] = fir.zero_bits !fir.heap<!fir.char<1,?>>
67+
! CHECK: %[[VAL_41:.*]] = fir.embox %[[VAL_40]] typeparams %[[VAL_1]] : (!fir.heap<!fir.char<1,?>>, index) -> !fir.box<!fir.heap<!fir.char<1,?>>>
68+
! CHECK: fir.store %[[VAL_41]] to %[[VAL_8]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
69+
! CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>) -> !fir.ref<!fir.box<none>>
70+
! CHECK: fir.call @_FortranATrim(%[[VAL_42]], %[[VAL_33]], %[[VAL_34]], %[[VAL_0]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
71+
! CHECK: %[[VAL_43:.*]] = fir.load %[[VAL_8]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
72+
! CHECK: %[[VAL_44:.*]] = fir.box_elesize %[[VAL_43]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> index
73+
! CHECK: %[[VAL_45:.*]] = fir.box_addr %[[VAL_43]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
74+
! CHECK: %[[VAL_46:.*]]:2 = hlfir.declare %[[VAL_45]] typeparams %[[VAL_44]] {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.heap<!fir.char<1,?>>)
75+
! CHECK: %[[VAL_47:.*]] = hlfir.as_expr %[[VAL_46]]#0 move %[[VAL_2]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
76+
! CHECK: hlfir.assign %[[VAL_47]] to %[[VAL_13]]#0 : !hlfir.expr<!fir.char<1,?>>, !fir.ref<!fir.char<1,3>>
77+
! CHECK: hlfir.destroy %[[VAL_47]] : !hlfir.expr<!fir.char<1,?>>
78+
! CHECK: hlfir.assign %[[VAL_16]]#0 to %[[VAL_13]]#0 : !fir.ref<!fir.char<1,3>, volatile>, !fir.ref<!fir.char<1,3>>
2079
! CHECK: return
2180
! CHECK: }
2281

0 commit comments

Comments
 (0)