[flang] Fixed designator codegen for contiguous boxes. (#139003)
Contiguous variables represented with a box do not have explicit shape, but it looks like the base/shape computation was assuming that. This caused generation of raw address fir.array_coor without the shape. This patch is needed to fix failures hapenning with #138797.
This commit is contained in:
@@ -70,8 +70,9 @@ getExplicitExtents(fir::FortranVariableOpInterface var,
|
||||
return {};
|
||||
}
|
||||
|
||||
// Return explicit lower bounds. For pointers and allocatables, this will not
|
||||
// read the lower bounds and instead return an empty vector.
|
||||
// Return explicit lower bounds from a shape result.
|
||||
// Only fir.shape, fir.shift and fir.shape_shift are currently
|
||||
// supported as shape.
|
||||
static llvm::SmallVector<mlir::Value>
|
||||
getExplicitLboundsFromShape(mlir::Value shape) {
|
||||
llvm::SmallVector<mlir::Value> result;
|
||||
@@ -89,6 +90,9 @@ getExplicitLboundsFromShape(mlir::Value shape) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return explicit lower bounds. For pointers and allocatables, this will not
|
||||
// read the lower bounds and instead return an empty vector.
|
||||
static llvm::SmallVector<mlir::Value>
|
||||
getExplicitLbounds(fir::FortranVariableOpInterface var) {
|
||||
if (mlir::Value shape = var.getShape())
|
||||
@@ -753,9 +757,30 @@ std::pair<mlir::Value, mlir::Value> hlfir::genVariableFirBaseShapeAndParams(
|
||||
}
|
||||
if (entity.isScalar())
|
||||
return {fir::getBase(exv), mlir::Value{}};
|
||||
if (auto variableInterface = entity.getIfVariableInterface())
|
||||
return {fir::getBase(exv),
|
||||
asEmboxShape(loc, builder, exv, variableInterface.getShape())};
|
||||
|
||||
// Contiguous variables that are represented with a box
|
||||
// may require the shape to be extracted from the box (i.e. evx),
|
||||
// because they itself may not have shape specified.
|
||||
// This happens during late propagationg of contiguous
|
||||
// attribute, e.g.:
|
||||
// %9:2 = hlfir.declare %6
|
||||
// {fortran_attrs = #fir.var_attrs<contiguous>} :
|
||||
// (!fir.box<!fir.array<?x?x...>>) ->
|
||||
// (!fir.box<!fir.array<?x?x...>>, !fir.box<!fir.array<?x?x...>>)
|
||||
// The extended value is an ArrayBoxValue with base being
|
||||
// the raw address of the array.
|
||||
if (auto variableInterface = entity.getIfVariableInterface()) {
|
||||
mlir::Value shape = variableInterface.getShape();
|
||||
if (mlir::isa<fir::BaseBoxType>(fir::getBase(exv).getType()) ||
|
||||
!mlir::isa<fir::BaseBoxType>(entity.getType()) ||
|
||||
// Still use the variable's shape if it is present.
|
||||
// If it only specifies a shift, then we have to create
|
||||
// a shape from the exv.
|
||||
(shape && (shape.getDefiningOp<fir::ShapeShiftOp>() ||
|
||||
shape.getDefiningOp<fir::ShapeOp>())))
|
||||
return {fir::getBase(exv),
|
||||
asEmboxShape(loc, builder, exv, variableInterface.getShape())};
|
||||
}
|
||||
return {fir::getBase(exv), builder.createShape(loc, exv)};
|
||||
}
|
||||
|
||||
|
||||
@@ -414,10 +414,11 @@ class DesignateOpConversion
|
||||
auto attrs = designate.getIsTripletAttr();
|
||||
for (auto isTriplet : attrs.asArrayRef()) {
|
||||
// Coordinate of the first element are the index and triplets lower
|
||||
// bounds
|
||||
// bounds.
|
||||
firstElementIndices.push_back(indices[i]);
|
||||
i = i + (isTriplet ? 3 : 1);
|
||||
}
|
||||
|
||||
mlir::Type originalDesignateType = designate.getResult().getType();
|
||||
const bool isVolatile = fir::isa_volatile_type(originalDesignateType);
|
||||
mlir::Type arrayCoorType = fir::ReferenceType::get(baseEleTy, isVolatile);
|
||||
|
||||
@@ -213,3 +213,70 @@ func.func @test_polymorphic_array_elt(%arg0: !fir.class<!fir.array<?x!fir.type<_
|
||||
// CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_4]] source_box %[[VAL_2]] : (!fir.ref<!fir.type<_QMtypesTt1>>, !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>) -> !fir.class<!fir.type<_QMtypesTt1>>
|
||||
// CHECK: return
|
||||
// CHECK: }
|
||||
|
||||
// Test proper generation of fir.array_coor for contiguous box with default lbounds.
|
||||
func.func @_QPtest_contiguous_derived_default(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>> {fir.bindc_name = "d1", fir.contiguous, fir.optional}) {
|
||||
%c1 = arith.constant 1 : index
|
||||
%c16_i32 = arith.constant 16 : i32
|
||||
%0 = fir.dummy_scope : !fir.dscope
|
||||
%1:2 = hlfir.declare %arg0 dummy_scope %0 {fortran_attrs = #fir.var_attrs<contiguous, optional>, uniq_name = "_QFtest_contiguous_derived_defaultEd1"} : (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.dscope) -> (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>)
|
||||
fir.select_type %1#1 : !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>> [#fir.type_is<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>, ^bb1, unit, ^bb2]
|
||||
^bb1: // pred: ^bb0
|
||||
%2 = fir.convert %1#1 : (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
%3:2 = hlfir.declare %2 {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_defaultEd1"} : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>) -> (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>)
|
||||
%4 = hlfir.designate %3#0 (%c1, %c1) : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, index, index) -> !fir.ref<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>
|
||||
%5 = hlfir.designate %4{"i"} : (!fir.ref<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>) -> !fir.ref<i32>
|
||||
hlfir.assign %c16_i32 to %5 : i32, !fir.ref<i32>
|
||||
cf.br ^bb3
|
||||
^bb2: // pred: ^bb0
|
||||
%6:2 = hlfir.declare %1#1 {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_defaultEd1"} : (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>) -> (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>)
|
||||
cf.br ^bb3
|
||||
^bb3: // 2 preds: ^bb1, ^bb2
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @_QPtest_contiguous_derived_default(
|
||||
// CHECK: %[[VAL_0:.*]] = arith.constant 1 : index
|
||||
// CHECK: %[[VAL_9:.*]] = fir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_defaultEd1"} : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
// CHECK: %[[VAL_10:.*]] = fir.rebox %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_10]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
|
||||
// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_10]], %[[VAL_12]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, index) -> (index, index, index)
|
||||
// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index
|
||||
// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_10]], %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, index) -> (index, index, index)
|
||||
// CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_13]]#1, %[[VAL_15]]#1 : (index, index) -> !fir.shape<2>
|
||||
// CHECK: %[[VAL_17:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_16]]) %[[VAL_0]], %[[VAL_0]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.shape<2>, index, index) -> !fir.ref<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>
|
||||
|
||||
// Test proper generation of fir.array_coor for contiguous box with non-default lbounds.
|
||||
func.func @_QPtest_contiguous_derived_lbounds(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>> {fir.bindc_name = "d1", fir.contiguous}) {
|
||||
%c3 = arith.constant 3 : index
|
||||
%c1 = arith.constant 1 : index
|
||||
%c16_i32 = arith.constant 16 : i32
|
||||
%0 = fir.dummy_scope : !fir.dscope
|
||||
%1 = fir.shift %c1, %c3 : (index, index) -> !fir.shift<2>
|
||||
%2:2 = hlfir.declare %arg0(%1) dummy_scope %0 {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_lboundsEd1"} : (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.shift<2>, !fir.dscope) -> (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>)
|
||||
fir.select_type %2#1 : !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>> [#fir.type_is<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>, ^bb1, unit, ^bb2]
|
||||
^bb1: // pred: ^bb0
|
||||
%3 = fir.convert %2#1 : (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
%4:2 = hlfir.declare %3(%1) {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_lboundsEd1"} : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.shift<2>) -> (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>)
|
||||
%5 = hlfir.designate %4#0 (%c1, %c3) : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, index, index) -> !fir.ref<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>
|
||||
%6 = hlfir.designate %5{"i"} : (!fir.ref<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>) -> !fir.ref<i32>
|
||||
hlfir.assign %c16_i32 to %6 : i32, !fir.ref<i32>
|
||||
cf.br ^bb3
|
||||
^bb2: // pred: ^bb0
|
||||
%7:2 = hlfir.declare %2#1(%1) {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_lboundsEd1"} : (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.shift<2>) -> (!fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>, !fir.class<!fir.array<?x?x!fir.type<_QMtypesTt1>>>)
|
||||
cf.br ^bb3
|
||||
^bb3: // 2 preds: ^bb1, ^bb2
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @_QPtest_contiguous_derived_lbounds(
|
||||
// CHECK: %[[VAL_0:.*]] = arith.constant 3 : index
|
||||
// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
|
||||
// CHECK: %[[VAL_8:.*]] = fir.declare %{{.*}}(%[[VAL_4:.*]]) {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest_contiguous_derived_lboundsEd1"} : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
// CHECK: %[[VAL_9:.*]] = fir.rebox %[[VAL_8]](%[[VAL_4]]) : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
// CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>
|
||||
// CHECK: %[[VAL_11:.*]] = arith.constant 0 : index
|
||||
// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_9]], %[[VAL_11]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, index) -> (index, index, index)
|
||||
// CHECK: %[[VAL_13:.*]] = arith.constant 1 : index
|
||||
// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_9]], %[[VAL_13]] : (!fir.box<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, index) -> (index, index, index)
|
||||
// CHECK: %[[VAL_15:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_12]]#1, %[[VAL_0]], %[[VAL_14]]#1 : (index, index, index, index) -> !fir.shapeshift<2>
|
||||
// CHECK: %[[VAL_16:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_15]]) %[[VAL_1]], %[[VAL_0]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>>, !fir.shapeshift<2>, index, index) -> !fir.ref<!fir.type<_QMtypesTt2{t1:!fir.type<_QMtypesTt1>,i:i32}>>
|
||||
|
||||
Reference in New Issue
Block a user