diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp --- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp @@ -351,10 +351,12 @@ mlir::Operation *endAssociate) { for (mlir::Operation *useOp : value.getUsers()) if (!mlir::isa(useOp) && useOp != currentUse) { - // hlfir.shape_of will not disrupt cleanup so it is safe for - // hlfir.associate. hlfir.shape_of might read the box dimensions and so it - // needs to come before the hflir.end_associate (which may deallocate). - if (mlir::isa(useOp)) { + // hlfir.shape_of and hlfir.get_length will not disrupt cleanup so it is + // safe for hlfir.associate. These operations might read from the box and + // so they need to come before the hflir.end_associate (which may + // deallocate). + if (mlir::isa(useOp) || + mlir::isa(useOp)) { if (!endAssociate) continue; // not known to occur in practice: diff --git a/flang/test/HLFIR/associate-codegen.fir b/flang/test/HLFIR/associate-codegen.fir --- a/flang/test/HLFIR/associate-codegen.fir +++ b/flang/test/HLFIR/associate-codegen.fir @@ -338,6 +338,30 @@ // CHECK: return // CHECK: } +// test that we support a hlfir.associate operation where the expr is also used in a hlfir.get_length op +func.func @test_get_length(%arg0: !fir.ref>) { + %0 = hlfir.as_expr %arg0 : (!fir.ref>) -> !hlfir.expr> + %1 = hlfir.get_length %0 : (!hlfir.expr>) -> index + %c2 = arith.constant 2 : index + %2:3 = hlfir.associate %0 typeparams %c2 {uniq_name = "adapt.valuebyref"} : (!hlfir.expr>, index) -> (!fir.ref>, !fir.ref>, i1) + // ... + hlfir.end_associate %2#1, %2#2 : !fir.ref>, i1 + return +} +// CHECK-LABEL: func.func @test_get_length( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1,2> {bindc_name = ".tmp"} +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant false +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] typeparams %[[VAL_2]] {uniq_name = ".tmp"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_4]]#0 temporary_lhs : !fir.ref>, !fir.ref> +// CHECK: %[[VAL_5:.*]] = fir.undefined tuple>, i1> +// CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_3]], [1 : index] : (tuple>, i1>, i1) -> tuple>, i1> +// CHECK: %[[VAL_7:.*]] = fir.insert_value %[[VAL_6]], %[[VAL_4]]#0, [0 : index] : (tuple>, i1>, !fir.ref>) -> tuple>, i1> +// CHECK: %[[VAL_8:.*]] = arith.constant 2 : index +// CHECK: return +// CHECK: } + func.func private @take_i4(!fir.ref) func.func private @take_r4(!fir.ref) func.func private @take_l4(!fir.ref>)