Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,13 +805,12 @@ llvm::LogicalResult BroadcastAssignBufferization::matchAndRewrite(
shape, /*slice=*/mlir::Value{});
} else {
// Array references must have fixed shape, when used in assignments.
auto refTy = mlir::cast<fir::ReferenceType>(lhs.getType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is slightly unsafe to assume this cannot be a fir.heap/fir.ptr. Nothing prevents these types from describing constant shaped compiler generated objects. Please use fir::unwrapRefType() instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review.

On line 786 there is a call to hlfir::derefPointersAndAllocatables:
lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
Shouldn't it handle fir.heap/fir.ptr already?

Also, after getting the flat array reference type, lhs is converted to it. Would this convert be valid for fir.heap/fir.ptr?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to submit this PR soon and do a follow-up with any additional changes? This issue blocks internal testing of some apps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it is already approved and blocking testing, I believe it's OK to merge it now.
As mentioned, I can make any necessary changes in a follow-up PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I understand @jeanPerier's comment.
Even after calling hlfir::derefPointersAndAllocatables the resulting type may still be a fir.heap/fir.ptr.
They can be converted to a fir.ref.

It seems hlfir::derefPointersAndAllocatables dereferences other pointer types, such as !fir.ref<!fir.box<!fir.ptr<!fir.array...>>>, generated from Fortran pointers, but not pointers directly to arrays, such as !fir.ptr<!fir.array...>, that may appear when equivalence is used.

I'll prepare a follow-up PR with this change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, lesson learned: "always listen to Jean" :)

auto seqTy = mlir::cast<fir::SequenceType>(refTy.getElementType());
llvm::ArrayRef<int64_t> fixedShape = seqTy.getShape();
int64_t flatExtent = 1;
for (const mlir::Value &extent : extents) {
mlir::Operation *op = extent.getDefiningOp();
assert(op && "no defining operation for constant array extent");
flatExtent *= fir::toInt(mlir::cast<mlir::arith::ConstantOp>(*op));
}

for (int64_t extent : fixedShape)
flatExtent *= extent;
flatArrayType =
fir::ReferenceType::get(fir::SequenceType::get({flatExtent}, eleTy));
flatArray = builder.createConvert(loc, flatArrayType, flatArray);
Expand Down
29 changes: 29 additions & 0 deletions flang/test/HLFIR/opt-scalar-assign.fir
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,32 @@ func.func @_QPtest6(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>> {f
// CHECK: }
// CHECK: return
// CHECK: }

func.func @_QQmain() {
return
}

func.func private @_QFPtest7(%arg0: !fir.ref<tuple<!fir.box<!fir.array<2x2xi32>>>> {fir.host_assoc}) attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>} {
%0 = fir.dummy_scope : !fir.dscope
%c0_i32 = arith.constant 0 : i32
%1 = fir.coordinate_of %arg0, %c0_i32 : (!fir.ref<tuple<!fir.box<!fir.array<2x2xi32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<2x2xi32>>>
%2 = fir.load %1 : !fir.ref<!fir.box<!fir.array<2x2xi32>>>
%3 = fir.box_addr %2 : (!fir.box<!fir.array<2x2xi32>>) -> !fir.ref<!fir.array<2x2xi32>>
%c0 = arith.constant 0 : index
%4:3 = fir.box_dims %2, %c0 : (!fir.box<!fir.array<2x2xi32>>, index) -> (index, index, index)
%c1 = arith.constant 1 : index
%5:3 = fir.box_dims %2, %c1 : (!fir.box<!fir.array<2x2xi32>>, index) -> (index, index, index)
%6 = fir.shape %4#1, %5#1 : (index, index) -> !fir.shape<2>
%7:2 = hlfir.declare %3(%6) {fortran_attrs = #fir.var_attrs<host_assoc>, uniq_name = "_QFEa"} : (!fir.ref<!fir.array<2x2xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<2x2xi32>>, !fir.ref<!fir.array<2x2xi32>>)
%c0_i32_0 = arith.constant 0 : i32
hlfir.assign %c0_i32_0 to %7#0 : i32, !fir.ref<!fir.array<2x2xi32>>
return
}

// CHECK-LABEL: func.func private @_QFPtest7({{.*}}) {{.*}} {
// CHECK: %[[VAL_0:.*]] = arith.constant 0 : i32
// CHECK: fir.do_loop %[[VAL_1:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered {
// CHECK: %[[VAL_2:.*]] = hlfir.designate %{{.*}} (%[[VAL_1]]) : (!fir.ref<!fir.array<4xi32>>, index) -> !fir.ref<i32>
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_2]] : i32, !fir.ref<i32>
// CHECK: }
// CHECK: }
Loading