aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjeanPerier <jperier@nvidia.com>2024-06-20 09:01:07 +0200
committerGitHub <noreply@github.com>2024-06-20 09:01:07 +0200
commitfa08e97d03afd215caeb297a822895c4d0d93b7b (patch)
tree5a2c923908a365d8a7e2f74e56949f58bff54abd
parente7d63ebaa2928056fb837a575a36dc4447dc80b2 (diff)
downloadllvm-fa08e97d03afd215caeb297a822895c4d0d93b7b.zip
llvm-fa08e97d03afd215caeb297a822895c4d0d93b7b.tar.gz
llvm-fa08e97d03afd215caeb297a822895c4d0d93b7b.tar.bz2
[flang] lower assumed-rank TARGET to intent(in) POINTER (#96082)
The only special thing to do is to use fir.rebox_assumed_rank when reboxing the target to properly set the POINTER attribute inside the descriptor.
-rw-r--r--flang/lib/Lower/ConvertCall.cpp3
-rw-r--r--flang/lib/Optimizer/Builder/MutableBox.cpp9
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-calls.f9018
3 files changed, 26 insertions, 4 deletions
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 382419a1..5e20f9e 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1597,9 +1597,6 @@ void prepareUserCallArguments(
if (dataTy.isAssumedRank()) {
dataTy =
dataTy.getBoxTypeWithNewShape(fir::getBase(actualExv).getType());
- if (dataTy.isAssumedRank())
- TODO(loc, "associating assumed-rank target to pointer assumed-rank "
- "argument");
}
mlir::Value irBox = builder.createTemporary(loc, dataTy);
fir::MutableBoxValue ptrBox(irBox,
diff --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp
index 16e543f..52d149f 100644
--- a/flang/lib/Optimizer/Builder/MutableBox.cpp
+++ b/flang/lib/Optimizer/Builder/MutableBox.cpp
@@ -527,7 +527,14 @@ void fir::factory::associateMutableBox(fir::FirOpBuilder &builder,
mlir::ValueRange newLbounds = lbounds.empty()
? mlir::ValueRange{arr.getLBounds()}
: mlir::ValueRange{lbounds};
- if (box.isDescribedByVariables()) {
+ if (box.hasAssumedRank()) {
+ assert(arr.hasAssumedRank() &&
+ "expect both arr and box to be assumed-rank");
+ mlir::Value reboxed = builder.create<fir::ReboxAssumedRankOp>(
+ loc, box.getBoxTy(), arr.getAddr(),
+ fir::LowerBoundModifierAttribute::Preserve);
+ writer.updateWithIrBox(reboxed);
+ } else if (box.isDescribedByVariables()) {
// LHS is a contiguous pointer described by local variables. Open RHS
// fir.box to update the LHS.
auto rawAddr = builder.create<fir::BoxAddrOp>(loc, arr.getMemTy(),
diff --git a/flang/test/Lower/HLFIR/assumed-rank-calls.f90 b/flang/test/Lower/HLFIR/assumed-rank-calls.f90
index 071589b..9d4503f 100644
--- a/flang/test/Lower/HLFIR/assumed-rank-calls.f90
+++ b/flang/test/Lower/HLFIR/assumed-rank-calls.f90
@@ -40,6 +40,24 @@ end subroutine
! CHECK: return
! CHECK: }
+subroutine test_target_to_pointer(x)
+ real, target :: x(..)
+ interface
+ subroutine takes_target_as_pointer(x)
+ real, pointer, intent(in) :: x(..)
+ end subroutine
+ end interface
+ call takes_target_as_pointer(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_target_to_pointer(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x", fir.target}) {
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<*:f32>>>
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtest_target_to_pointerEx"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_4:.*]] = fir.rebox_assumed_rank %[[VAL_3]]#0 lbs preserve : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.ptr<!fir.array<*:f32>>>
+! CHECK: fir.store %[[VAL_4]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: fir.call @_QPtakes_target_as_pointer(%[[VAL_1]]) fastmath<contract> : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>) -> ()
+
subroutine test_poly_to_nonepoly(x)
type t
integer :: i