Skip to content

Commit 02f61ab

Browse files
[flang] Use box for components with non-default lower bounds (#138994)
When designating an array component that has non-default lower bounds the bridge was producing hlfir designates yielding reference types, which did not preserve the bounds information. Then, when creating components, unadjusted indices were used when initializing the structure. We could look at the declaration to get the shape parameter, but this would not be preserved if the component were passed as a block argument. These results must be boxed, but we also must not lose the contiguity information either. To address contiguity, annotate these boxes with the `contiguous` attribute during designation. Note that other designated entities are handled inside the HlfirDesignatorBuilder while component designators are built in HlfirBuilder. I am not sure if this handling should be moved into the designator builder or left in the general builder, so feedback is welcome. Also, I wouldn't mind finding a test that demonstrates a box-designated component with the contiguous attribute really is determined to be contiguous by any passes down the line checking for that. I don't have a test like that yet.
1 parent d06d43a commit 02f61ab

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

flang/lib/Lower/ConvertExprToHLFIR.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "flang/Optimizer/Builder/Runtime/Derived.h"
3131
#include "flang/Optimizer/Builder/Runtime/Pointer.h"
3232
#include "flang/Optimizer/Builder/Todo.h"
33+
#include "flang/Optimizer/Dialect/FIRAttr.h"
3334
#include "flang/Optimizer/HLFIR/HLFIROps.h"
3435
#include "mlir/IR/IRMapping.h"
3536
#include "llvm/ADT/TypeSwitch.h"
@@ -125,6 +126,19 @@ class HlfirDesignatorBuilder {
125126
hlfir::ElementalAddrOp convertVectorSubscriptedExprToElementalAddr(
126127
const Fortran::lower::SomeExpr &designatorExpr);
127128

129+
std::tuple<mlir::Type, fir::FortranVariableFlagsEnum>
130+
genComponentDesignatorTypeAndAttributes(
131+
const Fortran::semantics::Symbol &componentSym, mlir::Type fieldType,
132+
bool isVolatile) {
133+
if (mayHaveNonDefaultLowerBounds(componentSym)) {
134+
mlir::Type boxType = fir::BoxType::get(fieldType, isVolatile);
135+
return std::make_tuple(boxType,
136+
fir::FortranVariableFlagsEnum::contiguous);
137+
}
138+
auto refType = fir::ReferenceType::get(fieldType, isVolatile);
139+
return std::make_tuple(refType, fir::FortranVariableFlagsEnum{});
140+
}
141+
128142
mlir::Value genComponentShape(const Fortran::semantics::Symbol &componentSym,
129143
mlir::Type fieldType) {
130144
// For pointers and allocatable components, the
@@ -1863,8 +1877,9 @@ class HlfirBuilder {
18631877
designatorBuilder.genComponentShape(sym, compType);
18641878
const bool isDesignatorVolatile =
18651879
fir::isa_volatile_type(baseOp.getType());
1866-
mlir::Type designatorType =
1867-
builder.getRefType(compType, isDesignatorVolatile);
1880+
auto [designatorType, extraAttributeFlags] =
1881+
designatorBuilder.genComponentDesignatorTypeAndAttributes(
1882+
sym, compType, isDesignatorVolatile);
18681883

18691884
mlir::Type fieldElemType = hlfir::getFortranElementType(compType);
18701885
llvm::SmallVector<mlir::Value, 1> typeParams;
@@ -1884,7 +1899,8 @@ class HlfirBuilder {
18841899

18851900
// Convert component symbol attributes to variable attributes.
18861901
fir::FortranVariableFlagsAttr attrs =
1887-
Fortran::lower::translateSymbolAttributes(builder.getContext(), sym);
1902+
Fortran::lower::translateSymbolAttributes(builder.getContext(), sym,
1903+
extraAttributeFlags);
18881904

18891905
// Get the component designator.
18901906
auto lhs = builder.create<hlfir::DesignateOp>(

flang/test/Lower/HLFIR/designators-component-ref.f90

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ subroutine test_array_comp_non_contiguous_slice(a)
126126
! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_1]]#0{"array_comp"} <%[[VAL_9]]> (%[[VAL_10]]:%[[VAL_11]]:%[[VAL_12]], %[[VAL_14]]:%[[VAL_15]]:%[[VAL_16]]) shape %[[VAL_18]] : (!fir.ref<!fir.type<_QMcomp_refTt_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>, !fir.shape<2>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<6x17xf32>>
127127
end subroutine
128128

129+
subroutine test_array_lbs_array_ctor()
130+
use comp_ref
131+
type(t_array_lbs) :: a(-1:1)
132+
real :: array_comp(2:11,3:22)
133+
a = (/ (t_array_lbs(i, array_comp), i=-1,1) /)
134+
! CHECK: hlfir.designate %{{.+}}#0{"array_comp_lbs"} <%{{.+}}> shape %{{.+}} {fortran_attrs = #fir.var_attrs<contiguous>}
135+
! CHECK-SAME: (!fir.ref<!fir.type<_QMcomp_refTt_array_lbs{scalar_i:i32,array_comp_lbs:!fir.array<10x20xf32>}>>, !fir.shapeshift<2>, !fir.shapeshift<2>)
136+
! CHECK-SAME: -> !fir.box<!fir.array<10x20xf32>>
137+
end subroutine
138+
129139
subroutine test_array_lbs_comp_lbs_1(a)
130140
use comp_ref
131141
type(t_array_lbs) :: a

0 commit comments

Comments
 (0)