From 2b60ed405b8110b20ab2e383839759ea34003127 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Tue, 20 Dec 2022 17:13:25 -0800 Subject: [PATCH] [flang] Use Assign() runtime for copy-in/copy-out. The loops generated under IsContiguous check for copy-in/copy-out result in LLVM backend spending too much time optimizing them. At the same time, the copy loops do not provide any optimization opportunities with the surrounding code (since they are executed under runtime IsContiguous check), so the copy code may be optimized on its own and this can be done in runtime. I thought I could implement and use new APIs for packing/unpacking non-contiguous data (interfaces added in D136378), but then I found that Assign() is already doing what is needed. If performance becomes an issue for these loops, we can optimize code in Assign() rather than creating new APIs. Thus, this change makes use of Assign() for copy-in/copy-out of boxed objects, and this is done only if the objects are non-contiguous during execution. Copies for non-boxed objects (e.g. for passing as VALUE dummy argument) are still done inline, because they can potentially be optimized with surrounding loops. I added internal -inline-copyinout-for-boxes option to revert to the old behavior just to make it easier to triage performance regressions, if any appear after the change. CPU2017/521.wrf compiles for 2179 seconds without the change and the module_dm.f90 compiled with -O0 (without -O0 this single module compiles for 5775 seconds). With the change total compilation time of the benchmark reduces to 722 seconds. Differential Revision: https://reviews.llvm.org/D140446 --- flang/lib/Lower/ConvertExpr.cpp | 64 ++++++++- flang/test/Lower/call-by-value-attr.f90 | 10 +- flang/test/Lower/call-copy-in-out.f90 | 156 +++++++++----------- .../dummy-argument-assumed-shape-optional.f90 | 48 ++----- flang/test/Lower/dummy-argument-optional-2.f90 | 47 ++---- flang/test/Lower/optional-value-caller.f90 | 157 ++++++++++++--------- flang/test/Lower/parent-component.f90 | 14 +- 7 files changed, 255 insertions(+), 241 deletions(-) diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp index 6194304..a5ff7dc 100644 --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -35,6 +35,7 @@ #include "flang/Optimizer/Builder/Character.h" #include "flang/Optimizer/Builder/Complex.h" #include "flang/Optimizer/Builder/Factory.h" +#include "flang/Optimizer/Builder/Runtime/Assign.h" #include "flang/Optimizer/Builder/Runtime/Character.h" #include "flang/Optimizer/Builder/Runtime/Derived.h" #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" @@ -105,6 +106,26 @@ static llvm::cl::opt optimizeTranspose( llvm::cl::desc("lower transpose without using a runtime call"), llvm::cl::init(true)); +// When copy-in/copy-out is generated for a boxed object we may +// either produce loops to copy the data or call the Fortran runtime's +// Assign function. Since the data copy happens under a runtime check +// (for IsContiguous) the copy loops can hardly provide any value +// to optimizations, instead, the optimizer just wastes compilation +// time on these loops. +// +// This internal option will force the loops generation, when set +// to true. It is false by default. +// +// Note that for copy-in/copy-out of non-boxed objects (e.g. for passing +// arguments by value) we always generate loops. Since the memory for +// such objects is contiguous, it may be better to expose them +// to the optimizer. +static llvm::cl::opt inlineCopyInOutForBoxes( + "inline-copyinout-for-boxes", + llvm::cl::desc( + "generate loops for copy-in/copy-out of objects with descriptors"), + llvm::cl::init(false)); + /// The various semantics of a program constituent (or a part thereof) as it may /// appear in an expression. /// @@ -2269,8 +2290,20 @@ public: auto doCopyIn = [&]() -> ExtValue { ExtValue temp = genArrayTempFromMold(actualArg, tempName); - if (arg.mayBeReadByCall()) + if (!arg.mayBeReadByCall()) { + return temp; + } + if (!isActualArgBox || inlineCopyInOutForBoxes) { genArrayCopy(temp, actualArg); + return temp; + } + + // Generate Assign() call to copy data from the actualArg + // to a temporary. + mlir::Value destBox = fir::getBase(builder.createBox(loc, temp)); + mlir::Value boxRef = builder.createTemporary(loc, destBox.getType()); + builder.create(loc, destBox, boxRef); + fir::runtime::genAssign(builder, loc, boxRef, fir::getBase(actualArg)); return temp; }; @@ -2366,17 +2399,38 @@ public: /// has been copied-in into a contiguous temp. void genCopyOut(const CopyOutPair ©OutPair) { mlir::Location loc = getLoc(); - if (!copyOutPair.restrictCopyAndFreeAtRuntime) { - if (copyOutPair.argMayBeModifiedByCall) + bool isActualArgBox = + fir::isa_box_type(fir::getBase(copyOutPair.var).getType()); + auto doCopyOut = [&]() { + if (!copyOutPair.argMayBeModifiedByCall) { + return; + } + if (!isActualArgBox || inlineCopyInOutForBoxes) { genArrayCopy(copyOutPair.var, copyOutPair.temp); + return; + } + // Generate Assign() call to copy data from the temporary + // to the actualArg. Note that in case the actual argument + // is ALLOCATABLE/POINTER the Assign() implementation + // should not engage its reallocation, because the temporary + // is rank, shape and type compatible with it. + mlir::Value srcBox = + fir::getBase(builder.createBox(loc, copyOutPair.temp)); + mlir::Value destBox = + fir::getBase(builder.createBox(loc, copyOutPair.var)); + mlir::Value destBoxRef = builder.createTemporary(loc, destBox.getType()); + builder.create(loc, destBox, destBoxRef); + fir::runtime::genAssign(builder, loc, destBoxRef, srcBox); + }; + if (!copyOutPair.restrictCopyAndFreeAtRuntime) { + doCopyOut(); builder.create(loc, fir::getBase(copyOutPair.temp)); return; } builder.genIfThen(loc, *copyOutPair.restrictCopyAndFreeAtRuntime) .genThen([&]() { - if (copyOutPair.argMayBeModifiedByCall) - genArrayCopy(copyOutPair.var, copyOutPair.temp); + doCopyOut(); builder.create(loc, fir::getBase(copyOutPair.temp)); }) .end(); diff --git a/flang/test/Lower/call-by-value-attr.f90 b/flang/test/Lower/call-by-value-attr.f90 index 5e00af8..1e4ca4c 100644 --- a/flang/test/Lower/call-by-value-attr.f90 +++ b/flang/test/Lower/call-by-value-attr.f90 @@ -74,11 +74,11 @@ program call_by_value_attr !CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[CONST_0]] : (!fir.box>, index) -> (index, index, index) !CHECK: %[[ARRAY_COPY_2:.*]] = fir.allocmem !fir.array<11xi32>, %[[DIMS]]#1 {uniq_name = ".copy"} !CHECK: %[[SHAPE_8:.*]] = fir.shape %[[DIMS]]#1 : (index) -> !fir.shape<1> - !CHECK: %[[ARRAY_LOAD_7:.*]] = fir.array_load %[[ARRAY_COPY_2]](%[[SHAPE_8]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array<11xi32> - !CHECK: %[[ARRAY_LOAD_8:.*]] = fir.array_load %[[BOX]] : (!fir.box>) -> !fir.array<11xi32> - !CHECK: %[[DO_4:.*]] = fir.do_loop {{.*}} { - !CHECK: } - !CHECK: fir.array_merge_store %[[ARRAY_LOAD_7]], %[[DO_4]] to %[[ARRAY_COPY_2]] : !fir.array<11xi32>, !fir.array<11xi32>, !fir.heap> + !CHECK: %[[TEMP_BOX:.*]] = fir.embox %[[ARRAY_COPY_2]](%[[SHAPE_8]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> + !CHECK: fir.store %[[TEMP_BOX]] to %[[TEMP_BOX_LOC:.*]] : !fir.ref>> + !CHECK: %[[TEMP_BOX_ADDR:.*]] = fir.convert %[[TEMP_BOX_LOC]] : (!fir.ref>>) -> !fir.ref> + !CHECK: %[[BOX_ADDR:.*]] = fir.convert %[[BOX]] : (!fir.box>) -> !fir.box + !CHECK: fir.call @_FortranAAssign(%[[TEMP_BOX_ADDR]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref>, !fir.box, !fir.ref, i32) -> none !CHECK: fir.result %[[ARRAY_COPY_2]] : !fir.heap> !CHECK: %[[CONVERT_B:.*]] = fir.convert %[[ADDR]] : (!fir.heap>) -> !fir.ref> !CHECK: fir.call @_QPsubra(%[[CONVERT_B]]) diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90 index d321006..fcf0abc 100644 --- a/flang/test/Lower/call-copy-in-out.f90 +++ b/flang/test/Lower/call-copy-in-out.f90 @@ -19,14 +19,11 @@ subroutine test_assumed_shape_to_array(x) ! Copy-in ! CHECK-DAG: %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1> -! CHECK-DAG: %[[temp_load:.*]] = fir.array_load %[[temp]](%[[shape]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array -! CHECK-DAG: %[[x_load:.*]] = fir.array_load %[[x]] : (!fir.box>) -> !fir.array -! CHECK: %[[copyin:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[res:.*]] = %[[temp_load]]) -> (!fir.array) { -! CHECK: %[[fetch:.*]] = fir.array_fetch %[[x_load]], %[[i]] : (!fir.array, index) -> f32 -! CHECK: %[[update:.*]] = fir.array_update %[[res]], %[[fetch]], %[[i]] : (!fir.array, f32, index) -> !fir.array -! CHECK: fir.result %[[update]] : !fir.array -! CHECK: } -! CHECK: fir.array_merge_store %[[temp_load]], %[[copyin:.*]] to %[[temp]] : !fir.array, !fir.array, !fir.heap> +! CHECK-DAG: %[[temp_box:.*]] = fir.embox %[[temp]](%[[shape]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK-DAG: fir.store %[[temp_box]] to %[[temp_box_loc:.*]] : !fir.ref>> +! CHECK-DAG: %[[temp_box_addr:.*]] = fir.convert %[[temp_box_loc]] : (!fir.ref>>) -> !fir.ref> +! CHECK-DAG: %[[arg_box:.*]] = fir.convert %[[x]] : (!fir.box>) -> !fir.box +! CHECK-DAG: fir.call @_FortranAAssign(%[[temp_box_addr]], %[[arg_box]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref>, !fir.box, !fir.ref, i32) -> none ! CHECK: fir.result %[[temp]] : !fir.heap> ! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) @@ -34,18 +31,12 @@ subroutine test_assumed_shape_to_array(x) ! CHECK: fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref>) -> () ! Copy-out -! CHECK-DAG: %[[x_load:.*]] = fir.array_load %[[x]] : (!fir.box>) -> !fir.array -! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1> -! CHECK-DAG: %[[temp_load:.*]] = fir.array_load %[[addr]](%[[shape]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array -! CHECK: %[[copyout:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[res:.*]] = %[[x_load]]) -> (!fir.array) { -! CHECK: %[[fetch:.*]] = fir.array_fetch %[[temp_load]], %[[i]] : (!fir.array, index) -> f32 -! CHECK: %[[update:.*]] = fir.array_update %[[res]], %[[fetch]], %[[i]] : (!fir.array, f32, index) -> !fir.array -! CHECK: fir.result %[[update]] : !fir.array -! CHECK: } -! CHECK: fir.array_merge_store %[[x_load]], %[[copyout:.*]] to %[[x]] : !fir.array, !fir.array, !fir.box> - +! CHECK-DAG: %[[temp_box:.*]] = fir.embox %[[addr]](%[[shape]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK-DAG: fir.store %[[x]] to %[[arg_box_loc:.*]] : !fir.ref>> +! CHECK-DAG: %[[arg_box_addr:.*]] = fir.convert %[[arg_box_loc]] : (!fir.ref>>) -> !fir.ref> +! CHECK-DAG: %[[temp_box_cast:.*]] = fir.convert %[[temp_box]] : (!fir.box>) -> !fir.box +! CHECK-DAG: fir.call @_FortranAAssign(%[[arg_box_addr]], %[[temp_box_cast]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref>, !fir.box, !fir.ref, i32) -> none ! CHECK: fir.freemem %[[addr]] : !fir.heap> call bar(x) @@ -66,7 +57,7 @@ subroutine eval_expr_only_once(x) ! CHECK: %[[temp:.*]] = fir.allocmem !fir.array ! CHECK-NOT: fir.call @_QPonly_once() -! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %[[temp]] +! CHECK: fir.call @_FortranAAssign ! CHECK-NOT: fir.call @_QPonly_once() ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> @@ -74,7 +65,7 @@ subroutine eval_expr_only_once(x) call bar(x(1:200:only_once())) ! CHECK-NOT: fir.call @_QPonly_once() -! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %[[x_section]] +! CHECK: fir.call @_FortranAAssign ! CHECK-NOT: fir.call @_QPonly_once() ! CHECK: fir.freemem %[[addr]] : !fir.heap> @@ -86,10 +77,10 @@ end subroutine subroutine test_contiguous(x) real, contiguous :: x(:) ! CHECK: %[[addr:.*]] = fir.box_addr %[[x]] : (!fir.box>) -> !fir.ref> -! CHECK-NOT: fir.array_merge_store +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: fir.call @_QPbar(%[[addr]]) {{.*}}: (!fir.ref>) -> () call bar(x) -! CHECK-NOT: fir.array_merge_store +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: return end subroutine @@ -104,7 +95,7 @@ subroutine test_parenthesis(x) ! CHECK: %[[cast:.*]] = fir.convert %[[temp]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref>) -> () call bar((x)) -! CHECK-NOT: fir.array_merge_store +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[temp]] : !fir.heap> ! CHECK: return end subroutine @@ -125,14 +116,14 @@ subroutine test_intent_out(x) ! CHECK: } else { ! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[temp:.*]] = fir.allocmem !fir.array, %[[dim]]#1 -! CHECK-NOT: fir.array_merge_store +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPbar_intent_out(%[[cast]]) {{.*}}: (!fir.ref>) -> () call bar_intent_out(x) ! CHECK: fir.if %[[not_contiguous]] -! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %[[x]] +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[addr]] : !fir.heap> ! CHECK: return end subroutine @@ -153,13 +144,17 @@ subroutine test_intent_in(x) ! CHECK: } else { ! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[temp:.*]] = fir.allocmem !fir.array, %[[dim]]#1 -! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %[[temp]] +! CHECK: %[[temp_shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[temp_box:.*]] = fir.embox %[[temp]](%[[temp_shape]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: fir.store %[[temp_box]] to %[[temp_box_loc:.*]] : !fir.ref>> +! CHECK: %[[temp_box_addr:.*]] = fir.convert %[[temp_box_loc]] : (!fir.ref>>) -> !fir.ref> +! CHECK: fir.call @_FortranAAssign(%[[temp_box_addr]], ! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPbar_intent_in(%[[cast]]) {{.*}}: (!fir.ref>) -> () call bar_intent_in(x) ! CHECK: fir.if %[[not_contiguous]] -! CHECK-NOT: fir.array_merge_store +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[addr]] : !fir.heap> ! CHECK: return end subroutine @@ -180,13 +175,13 @@ subroutine test_intent_inout(x) ! CHECK: } else { ! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[temp:.*]] = fir.allocmem !fir.array, %[[dim]]#1 -! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %[[temp]] +! CHECK: fir.call @_FortranAAssign ! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPbar_intent_inout(%[[cast]]) {{.*}}: (!fir.ref>) -> () call bar_intent_inout(x) ! CHECK: fir.if %[[not_contiguous]] -! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %[[x]] +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[addr]] : !fir.heap> ! CHECK: return end subroutine @@ -195,64 +190,49 @@ end subroutine ! CHECK-LABEL: func @_QPtest_char( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>>{{.*}}) { subroutine test_char(x) - ! CHECK: %[[VAL_1:.*]] = arith.constant 10 : index - ! CHECK: %[[box_none:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box) -> i1 - ! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]] - ! CHECK: } else { - ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_4:.*]] = fir.allocmem !fir.array>, %[[VAL_3]]#1 {uniq_name = ".copyinout"} - ! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_6:.*]] = fir.array_load %[[VAL_4]](%[[VAL_5]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.array> - ! CHECK: %[[VAL_7:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>>) -> !fir.array> - ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_10:.*]] = arith.subi %[[VAL_3]]#1, %[[VAL_8]] : index - ! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_9]] to %[[VAL_10]] step %[[VAL_8]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_6]]) -> (!fir.array>) { - ! CHECK: %[[VAL_14:.*]] = fir.array_access %[[VAL_7]], %[[VAL_12]] : (!fir.array>, index) -> !fir.ref> - ! CHECK: %[[VAL_15:.*]] = fir.array_access %[[VAL_13]], %[[VAL_12]] : (!fir.array>, index) -> !fir.ref> - ! CHECK: %[[VAL_16:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_17:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (index) -> i64 - ! CHECK: %[[VAL_19:.*]] = arith.muli %[[VAL_17]], %[[VAL_18]] : i64 - ! CHECK: %[[VAL_20:.*]] = arith.constant false - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_15]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_14]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_21]], %[[VAL_22]], %[[VAL_19]], %[[VAL_20]]) {{.*}}: (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_23:.*]] = fir.array_amend %[[VAL_13]], %[[VAL_15]] : (!fir.array>, !fir.ref>) -> !fir.array> - ! CHECK: fir.result %[[VAL_23]] : !fir.array> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_6]], %[[VAL_24:.*]] to %[[VAL_4]] : !fir.array>, !fir.array>, !fir.heap>> - ! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[VAL_0]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_25:.*]] = fir.convert %[[addr]] : (!fir.heap>>) -> !fir.ref> - ! CHECK: %[[VAL_26:.*]] = fir.emboxchar %[[VAL_25]], %[[VAL_1]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPbar_char(%[[VAL_26]]) {{.*}}: (!fir.boxchar<1>) -> () - ! CHECK: %[[VAL_27:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>>) -> !fir.array> - ! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_29:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_28]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_30:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_31:.*]] = fir.array_load %[[addr]](%[[VAL_30]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.array> - ! CHECK: %[[VAL_32:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_33:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_34:.*]] = arith.subi %[[VAL_29]]#1, %[[VAL_32]] : index - ! CHECK: %[[VAL_35:.*]] = fir.do_loop %[[VAL_36:.*]] = %[[VAL_33]] to %[[VAL_34]] step %[[VAL_32]] unordered iter_args(%[[VAL_37:.*]] = %[[VAL_27]]) -> (!fir.array>) { - ! CHECK: %[[VAL_38:.*]] = fir.array_access %[[VAL_31]], %[[VAL_36]] : (!fir.array>, index) -> !fir.ref> - ! CHECK: %[[VAL_39:.*]] = fir.array_access %[[VAL_37]], %[[VAL_36]] : (!fir.array>, index) -> !fir.ref> - ! CHECK: %[[VAL_40:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_41:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_40]] : (index) -> i64 - ! CHECK: %[[VAL_43:.*]] = arith.muli %[[VAL_41]], %[[VAL_42]] : i64 - ! CHECK: %[[VAL_44:.*]] = arith.constant false - ! CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_38]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_45]], %[[VAL_46]], %[[VAL_43]], %[[VAL_44]]) {{.*}}: (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_47:.*]] = fir.array_amend %[[VAL_37]], %[[VAL_39]] : (!fir.array>, !fir.ref>) -> !fir.array> - ! CHECK: fir.result %[[VAL_47]] : !fir.array> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_27]], %[[VAL_48:.*]] to %[[VAL_0]] : !fir.array>, !fir.array>, !fir.box>> - ! CHECK: fir.freemem %[[addr]] : !fir.heap>> - + ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box>> + ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box>> + ! CHECK: %[[VAL_3:.*]] = arith.constant 10 : index + ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_5:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_4]]) fastmath : (!fir.box) -> i1 + ! CHECK: %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.heap>>) { + ! CHECK: %[[VAL_7:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> + ! CHECK: fir.result %[[VAL_7]] : !fir.heap>> + ! CHECK: } else { + ! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array>, %[[VAL_9]]#1 {uniq_name = ".copyinout"} + ! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_9]]#1 : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_10]](%[[VAL_11]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: fir.store %[[VAL_12]] to %[[VAL_2]] : !fir.ref>>> + ! CHECK: %[[VAL_13:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref> + ! CHECK: %[[VAL_14:.*]] = arith.constant {{.*}} : i32 + ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>>>) -> !fir.ref> + ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_13]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAAssign(%[[VAL_15]], %[[VAL_16]], %[[VAL_17]], %[[VAL_14]]) fastmath : (!fir.ref>, !fir.box, !fir.ref, i32) -> none + ! CHECK: fir.result %[[VAL_10]] : !fir.heap>> + ! CHECK: } + ! CHECK: %[[VAL_19:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[VAL_21:.*]] = arith.constant false + ! CHECK: %[[VAL_22:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_21]] : i1 + ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_24:.*]] : (!fir.heap>>) -> !fir.ref> + ! CHECK: %[[VAL_25:.*]] = fir.emboxchar %[[VAL_23]], %[[VAL_3]] : (!fir.ref>, index) -> !fir.boxchar<1> + ! CHECK: fir.call @_QPbar_char(%[[VAL_25]]) fastmath : (!fir.boxchar<1>) -> () + ! CHECK: fir.if %[[VAL_22]] { + ! CHECK: %[[VAL_26:.*]] = fir.shape %[[VAL_20]]#1 : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_27:.*]] = fir.embox %[[VAL_24]](%[[VAL_26]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: fir.store %[[VAL_0]] to %[[VAL_1]] : !fir.ref>>> + ! CHECK: %[[VAL_28:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref> + ! CHECK: %[[VAL_29:.*]] = arith.constant {{.*}} : i32 + ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_1]] : (!fir.ref>>>) -> !fir.ref> + ! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_27]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_28]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_33:.*]] = fir.call @_FortranAAssign(%[[VAL_30]], %[[VAL_31]], %[[VAL_32]], %[[VAL_29]]) fastmath : (!fir.ref>, !fir.box, !fir.ref, i32) -> none + ! CHECK: fir.freemem %[[VAL_24]] : !fir.heap>> + ! CHECK: } + character(10) :: x(:) call bar_char(x) ! CHECK: return diff --git a/flang/test/Lower/dummy-argument-assumed-shape-optional.f90 b/flang/test/Lower/dummy-argument-assumed-shape-optional.f90 index d033e90..01f774f 100644 --- a/flang/test/Lower/dummy-argument-assumed-shape-optional.f90 +++ b/flang/test/Lower/dummy-argument-assumed-shape-optional.f90 @@ -29,9 +29,7 @@ end subroutine ! CHECK: fir.result %[[VAL_4]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_7:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { - ! ... copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_7]] : !fir.heap> ! CHECK: } ! CHECK: %[[VAL_20:.*]] = arith.constant 0 : index @@ -42,9 +40,7 @@ end subroutine ! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_3]](%[[VAL_24]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> ! CHECK: fir.call @_QPtakes_contiguous(%[[VAL_25]]) {{.*}}: (!fir.box>) -> () ! CHECK: fir.if %[[VAL_23]] { -! CHECK: fir.do_loop {{.*}} { - ! ... copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_3]] : !fir.heap> ! CHECK: } ! CHECK: return @@ -78,9 +74,7 @@ end subroutine ! CHECK: fir.result %[[VAL_4]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_7:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { - ! ... copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_7]] : !fir.heap> ! CHECK: } ! CHECK: %[[VAL_20:.*]] = arith.constant 0 : index @@ -91,9 +85,7 @@ end subroutine ! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_3]](%[[VAL_24]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> ! CHECK: fir.call @_QPtakes_contiguous(%[[VAL_25]]) {{.*}}: (!fir.box>) -> () ! CHECK: fir.if %[[VAL_23]] { -! CHECK: fir.do_loop {{.*}} { - ! ... copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_3]] : !fir.heap> ! CHECK: } ! CHECK: return @@ -128,9 +120,7 @@ end subroutine ! CHECK: fir.result %[[VAL_4]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_7:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { - ! ... copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_7]] : !fir.heap> ! CHECK: } ! CHECK: %[[VAL_20:.*]] = arith.constant 0 : index @@ -141,9 +131,7 @@ end subroutine ! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_3]](%[[VAL_24]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> ! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_25]]) {{.*}}: (!fir.box>) -> () ! CHECK: fir.if %[[VAL_23]] { -! CHECK: fir.do_loop {{.*}} { - ! ... copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_3]] : !fir.heap> ! CHECK: } ! CHECK: return @@ -184,9 +172,7 @@ end subroutine ! CHECK: fir.result %[[VAL_11]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_14:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { - ! copy ... -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_14]] : !fir.heap> ! CHECK: } ! CHECK: fir.result %[[VAL_10]] : !fir.heap> @@ -205,9 +191,7 @@ end subroutine ! CHECK: %[[VAL_38:.*]] = arith.select %[[VAL_1]], %[[VAL_35]], %[[VAL_37]] : !fir.box> ! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_38]]) {{.*}}: (!fir.box>) -> () ! CHECK: fir.if %[[VAL_33]] { -! CHECK: %[[VAL_47:.*]] = fir.do_loop {{.*}} { - ! copy ... -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_9]] : !fir.heap> ! CHECK: } ! CHECK: return @@ -251,9 +235,7 @@ end subroutine ! CHECK: fir.result %[[VAL_13]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_16:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { - ! copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_16]] : !fir.heap> ! CHECK: } ! CHECK: fir.result %[[VAL_12]] : !fir.heap> @@ -272,9 +254,7 @@ end subroutine ! CHECK: %[[VAL_41:.*]] = arith.select %[[VAL_5]], %[[VAL_38]], %[[VAL_40]] : !fir.box> ! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_41]]) {{.*}}: (!fir.box>) -> () ! CHECK: fir.if %[[VAL_36]] { -! CHECK: fir.do_loop {{.*}} { - ! copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_11]] : !fir.heap> ! CHECK: } ! CHECK: return @@ -324,9 +304,7 @@ end subroutine ! CHECK: fir.result %[[VAL_13]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_16:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { - ! copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_16]] : !fir.heap> ! CHECK: } ! CHECK: fir.result %[[VAL_12]] : !fir.heap> @@ -345,9 +323,7 @@ end subroutine ! CHECK: %[[VAL_41:.*]] = arith.select %[[VAL_5]], %[[VAL_38]], %[[VAL_40]] : !fir.box> ! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_41]]) {{.*}}: (!fir.box>) -> () ! CHECK: fir.if %[[VAL_36]] { -! CHECK: fir.do_loop {{.*}} { - ! copy -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_11]] : !fir.heap> ! CHECK: } ! CHECK: return diff --git a/flang/test/Lower/dummy-argument-optional-2.f90 b/flang/test/Lower/dummy-argument-optional-2.f90 index 9c0e9e3..ab43fd9 100644 --- a/flang/test/Lower/dummy-argument-optional-2.f90 +++ b/flang/test/Lower/dummy-argument-optional-2.f90 @@ -111,9 +111,7 @@ subroutine pass_pointer_array(i) ! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[box]], %[[VAL_10]] : (!fir.box>>, index) -> (index, index, index) ! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array, %[[VAL_11]]#1 {uniq_name = ".copyinout"} -! CHECK: %[[VAL_20:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_20]] to %[[VAL_12]] : !fir.array, !fir.array, !fir.heap> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_12]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_26:.*]] = fir.zero_bits !fir.heap> @@ -124,9 +122,7 @@ subroutine pass_pointer_array(i) ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_29]]) {{.*}}: (!fir.ref>) -> () ! CHECK: fir.if %[[and]] { -! CHECK: %[[VAL_40:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_40]] to %[[box]] : !fir.array, !fir.array, !fir.box>> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_9]] : !fir.heap> ! CHECK: } end subroutine @@ -149,9 +145,7 @@ subroutine pass_pointer_array_char(c) ! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_10]] : (!fir.box>>>, index) -> (index, index, index) ! CHECK: %[[VAL_12:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box>>>) -> index ! CHECK: %[[VAL_13:.*]] = fir.allocmem !fir.array>(%[[VAL_12]] : index), %[[VAL_11]]#1 {uniq_name = ".copyinout"} -! CHECK: %[[VAL_21:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_21]] to %[[VAL_13]] typeparams %[[VAL_12]] : !fir.array>, !fir.array>, !fir.heap>>, index +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_13]] : !fir.heap>> ! CHECK: } else { ! CHECK: %[[VAL_46:.*]] = fir.zero_bits !fir.heap>> @@ -164,9 +158,7 @@ subroutine pass_pointer_array_char(c) ! CHECK: %[[VAL_52:.*]] = fir.emboxchar %[[VAL_50]], %[[VAL_47]] : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_52]]) {{.*}}: (!fir.boxchar<1>) -> () ! CHECK: fir.if %[[and]] { -! CHECK: %[[VAL_62:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_62]] to %[[VAL_6]] : !fir.array>, !fir.array>, !fir.box>>> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_9]] : !fir.heap>> ! CHECK: } ! CHECK: return @@ -190,8 +182,7 @@ subroutine forward_pointer_array() ! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%{{.*}}) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.heap>) { ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_10]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> @@ -202,8 +193,7 @@ subroutine forward_pointer_array() ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_14]]) {{.*}}: (!fir.ref>) -> () ! CHECK: fir.if %[[and]] { -! CHECK: fir.do_loop {{.*}} { -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_7]] : !fir.heap> ! CHECK: } end subroutine @@ -231,9 +221,7 @@ subroutine pass_opt_assumed_shape(x) ! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array, %[[VAL_9]]#1 {uniq_name = ".copyinout"} -! CHECK: %[[VAL_17:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_17]] to %[[VAL_10]] : !fir.array, !fir.array, !fir.heap> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_10]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap> @@ -244,9 +232,7 @@ subroutine pass_opt_assumed_shape(x) ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_27:.*]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_26]]) {{.*}}: (!fir.ref>) -> () ! CHECK: fir.if %[[and]] { -! CHECK: %[[VAL_36:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_36]] to %[[VAL_6]] : !fir.array, !fir.array, !fir.box> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_27]] : !fir.heap> ! CHECK: } end subroutine @@ -272,9 +258,7 @@ subroutine pass_opt_assumed_shape_char(c) ! CHECK: } else { ! CHECK: %[[box_elesize:.*]] = fir.box_elesize %[[VAL_7]] : (!fir.box>>) -> index ! CHECK: %[[temp:.*]] = fir.allocmem !fir.array>(%[[box_elesize]] : index), %{{.*}}#1 {uniq_name = ".copyinout"} -! CHECK: %[[VAL_19:.*]] = fir.do_loop {{.*}} { -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_19]] to %[[temp]] typeparams %[[box_elesize]] : !fir.array>, !fir.array>, !fir.heap>>, index +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_12]] : !fir.heap>> ! CHECK: } else { ! CHECK: %[[VAL_44:.*]] = fir.zero_bits !fir.heap>> @@ -287,8 +271,7 @@ subroutine pass_opt_assumed_shape_char(c) ! CHECK: %[[VAL_50:.*]] = fir.emboxchar %[[VAL_48]], %[[VAL_45]] : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_50]]) {{.*}}: (!fir.boxchar<1>) -> () ! CHECK: fir.if %[[and]] { -! CHECK: %[[VAL_59:.*]] = fir.do_loop {{.*}} { -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_59]] to %[[VAL_7]] : !fir.array>, !fir.array>, !fir.box>> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_49]] : !fir.heap>> ! CHECK: } end subroutine @@ -411,8 +394,7 @@ subroutine pass_opt_assumed_shape_to_intentin(x) ! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array -! CHECK: fir.do_loop {{.*}} { -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_10]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap> @@ -423,7 +405,7 @@ subroutine pass_opt_assumed_shape_to_intentin(x) ! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentin(%[[VAL_24]]) {{.*}}: (!fir.ref>) -> () ! CHECK: fir.if %[[and]] { -! CHECK-NOT: fir.do_loop +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_7]] : !fir.heap> ! CHECK: } end subroutine @@ -443,7 +425,7 @@ subroutine pass_opt_assumed_shape_to_intentout(x) ! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array -! CHECK-NOT: fir.do_loop +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_10]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> @@ -454,8 +436,7 @@ subroutine pass_opt_assumed_shape_to_intentout(x) ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentout(%[[VAL_14]]) {{.*}}: (!fir.ref>) -> () ! CHECK: fir.if %[[and]] { -! CHECK: fir.do_loop {{.*}} { -! CHECK: } +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_7]] : !fir.heap> ! CHECK: } end subroutine diff --git a/flang/test/Lower/optional-value-caller.f90 b/flang/test/Lower/optional-value-caller.f90 index 089a85b..b4df341 100644 --- a/flang/test/Lower/optional-value-caller.f90 +++ b/flang/test/Lower/optional-value-caller.f90 @@ -287,9 +287,7 @@ subroutine test_dyn_array_from_assumed(i, n) ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_7]], %[[VAL_9]] : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[VAL_11:.*]] = fir.allocmem !fir.array, %[[VAL_10]]#1 {uniq_name = ".copy"} -! CHECK: %[[VAL_18:.*]] = fir.do_loop -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_18]] to %[[VAL_11]] : !fir.array, !fir.array, !fir.heap> +! CHECK: fir.call @_FortranAAssign ! CHECK: fir.result %[[VAL_11]] : !fir.heap> ! CHECK: } else { ! CHECK: %[[VAL_24:.*]] = fir.zero_bits !fir.heap> @@ -300,6 +298,7 @@ subroutine test_dyn_array_from_assumed(i, n) ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_8]] : (!fir.heap>) -> !fir.ref> ! CHECK: fir.call @_QPdyn_array(%[[VAL_25]], %[[VAL_1]]) {{.*}}: (!fir.ref>, !fir.ref) -> () ! CHECK: fir.if %[[and]] { +! CHECK-NOT: fir.call @_FortranAAssign ! CHECK: fir.freemem %[[VAL_8]] : !fir.heap> ! CHECK: } end subroutine @@ -309,34 +308,49 @@ end subroutine subroutine test_array_ptr(i) integer, pointer :: i(:) call array(i) -! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> -! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> -! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>) -> i64 -! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 -! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64 -! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> -! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index -! CHECK: %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_7]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[box_none:.*]] = fir.convert %[[VAL_6]] : (!fir.box>>) -> !fir.box -! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box) -> i1 -! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_5]] -> (!fir.heap>) { -! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index -! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_10]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array, %[[VAL_11]]#1 {uniq_name = ".copy"} -! CHECK: %[[VAL_20:.*]] = fir.do_loop -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_20]] to %[[VAL_12]] : !fir.array, !fir.array, !fir.heap> -! CHECK: fir.result %[[VAL_12]] : !fir.heap> -! CHECK: } else { -! CHECK: %[[VAL_26:.*]] = fir.zero_bits !fir.heap> -! CHECK: fir.result %[[VAL_26]] : !fir.heap> -! CHECK: } -! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1 -! CHECK: %[[and:.*]] = arith.andi %[[VAL_5]], %[[not_contiguous]] : i1 -! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>) -> !fir.ref> -! CHECK: fir.if %[[and]] { -! CHECK: fir.freemem %[[VAL_9]] : !fir.heap> -! CHECK: } +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box> +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>) -> i64 +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64 +! CHECK: %[[VAL_6:.*]] = arith.cmpi ne, %[[VAL_4]], %[[VAL_5]] : i64 +! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.box>>) -> !fir.box +! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_8]]) fastmath : (!fir.box) -> i1 +! CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_6]] -> (!fir.heap>) { +! CHECK: %[[VAL_11:.*]] = fir.if %[[VAL_9]] -> (!fir.heap>) { +! CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>>) -> !fir.heap> +! CHECK: fir.result %[[VAL_12]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_7]], %[[VAL_13]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array, %[[VAL_14]]#1 {uniq_name = ".copy"} +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_15]](%[[VAL_16]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: fir.store %[[VAL_17]] to %[[VAL_1]] : !fir.ref>> +! CHECK: %[[VAL_18:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref> +! CHECK: %[[VAL_19:.*]] = arith.constant {{.*}} : i32 +! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_1]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_7]] : (!fir.box>>) -> !fir.box +! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_23:.*]] = fir.call @_FortranAAssign(%[[VAL_20]], %[[VAL_21]], %[[VAL_22]], %[[VAL_19]]) fastmath : (!fir.ref>, !fir.box, !fir.ref, i32) -> none +! CHECK: fir.result %[[VAL_15]] : !fir.heap> +! CHECK: } +! CHECK: fir.result %[[VAL_24:.*]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_25:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.result %[[VAL_25]] : !fir.heap> +! CHECK: } +! CHECK: %[[VAL_26:.*]] = arith.constant false +! CHECK: %[[VAL_27:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_26]] : i1 +! CHECK: %[[VAL_28:.*]] = arith.andi %[[VAL_6]], %[[VAL_27]] : i1 +! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_30:.*]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QParray(%[[VAL_29]]) fastmath : (!fir.ref>) -> () +! CHECK: fir.if %[[VAL_28]] { +! CHECK: fir.freemem %[[VAL_30]] : !fir.heap> +! CHECK: } +! CHECK: return +! CHECK: } end subroutine ! CHECK-LABEL: func @_QMtestPtest_char( @@ -397,38 +411,53 @@ subroutine test_char_array(c) integer(8) :: n character(*), optional :: c(:) call dyn_char_array(c, n) -! CHECK: %[[VAL_1:.*]] = fir.alloca i64 {bindc_name = "n", uniq_name = "_QMtestFtest_char_arrayEn"} -! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -! CHECK: %[[VAL_3:.*]] = fir.zero_bits !fir.ref>> -! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index -! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> -! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index -! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_3]](%[[VAL_5]]) typeparams %[[VAL_6]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.box>> -! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_2]], %[[VAL_0]], %[[VAL_7]] : !fir.box>> -! CHECK: %[[box_none:.*]] = fir.convert %5 : (!fir.box>>) -> !fir.box -! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box) -> i1 -! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_2]] -> (!fir.heap>>) { -! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index -! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_10]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[VAL_12:.*]] = fir.box_elesize %[[VAL_8]] : (!fir.box>>) -> index -! CHECK: %[[VAL_13:.*]] = fir.allocmem !fir.array>(%[[VAL_12]] : index), %[[VAL_11]]#1 {uniq_name = ".copy"} -! CHECK: %[[VAL_20:.*]] = fir.do_loop {{.*}} -! CHECK: fir.call @llvm.memmove.p0.p0.i64 -! CHECK: } -! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_20]] to %[[VAL_13]] typeparams %[[VAL_12]] : !fir.array>, !fir.array>, !fir.heap>>, index -! CHECK: fir.result %[[VAL_13]] : !fir.heap>> -! CHECK: } else { -! CHECK: %[[VAL_45:.*]] = fir.zero_bits !fir.heap>> -! CHECK: fir.result %[[VAL_45]] : !fir.heap>> -! CHECK: } -! CHECK: %[[VAL_46:.*]] = fir.box_elesize %[[VAL_8]] : (!fir.box>>) -> index -! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1 -! CHECK: %[[and:.*]] = arith.andi %[[VAL_2]], %[[not_contiguous]] : i1 -! CHECK: %[[VAL_47:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>>) -> !fir.ref> -! CHECK: %[[VAL_49:.*]] = fir.emboxchar %[[VAL_47]], %[[VAL_46]] : (!fir.ref>, index) -> !fir.boxchar<1> -! CHECK: fir.call @_QPdyn_char_array(%[[VAL_49]], %[[VAL_1]]) {{.*}}: (!fir.boxchar<1>, !fir.ref) -> () -! CHECK: fir.if %[[and]] { -! CHECK: fir.freemem %[[VAL_9]] : !fir.heap>> -! CHECK: } +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box>> +! CHECK: %[[VAL_2:.*]] = fir.alloca i64 {bindc_name = "n", uniq_name = "_QMtestFtest_char_arrayEn"} +! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +! CHECK: %[[VAL_4:.*]] = fir.zero_bits !fir.ref>> +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]](%[[VAL_6]]) typeparams %[[VAL_7]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.box>> +! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_3]], %[[VAL_0]], %[[VAL_8]] : !fir.box>> +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.box>>) -> !fir.box +! CHECK: %[[VAL_11:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_10]]) fastmath : (!fir.box) -> i1 +! CHECK: %[[VAL_12:.*]] = fir.if %[[VAL_3]] -> (!fir.heap>>) { +! CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_11]] -> (!fir.heap>>) { +! CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box>>) -> !fir.heap>> +! CHECK: fir.result %[[VAL_14]] : !fir.heap>> +! CHECK: } else { +! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_9]], %[[VAL_15]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_9]] : (!fir.box>>) -> index +! CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array>(%[[VAL_17]] : index), %[[VAL_16]]#1 {uniq_name = ".copy"} +! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_16]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) typeparams %[[VAL_17]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.box>> +! CHECK: fir.store %[[VAL_20]] to %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[VAL_21:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref> +! CHECK: %[[VAL_22:.*]] = arith.constant {{.*}} : i32 +! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_1]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_9]] : (!fir.box>>) -> !fir.box +! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_26:.*]] = fir.call @_FortranAAssign(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_22]]) fastmath : (!fir.ref>, !fir.box, !fir.ref, i32) -> none +! CHECK: fir.result %[[VAL_18]] : !fir.heap>> +! CHECK: } +! CHECK: fir.result %[[VAL_27:.*]] : !fir.heap>> +! CHECK: } else { +! CHECK: %[[VAL_28:.*]] = fir.zero_bits !fir.heap>> +! CHECK: fir.result %[[VAL_28]] : !fir.heap>> +! CHECK: } +! CHECK: %[[VAL_29:.*]] = fir.box_elesize %[[VAL_9]] : (!fir.box>>) -> index +! CHECK: %[[VAL_30:.*]] = arith.constant false +! CHECK: %[[VAL_31:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_30]] : i1 +! CHECK: %[[VAL_32:.*]] = arith.andi %[[VAL_3]], %[[VAL_31]] : i1 +! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_34:.*]] : (!fir.heap>>) -> !fir.ref> +! CHECK: %[[VAL_35:.*]] = fir.emboxchar %[[VAL_33]], %[[VAL_29]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPdyn_char_array(%[[VAL_35]], %[[VAL_2]]) fastmath : (!fir.boxchar<1>, !fir.ref) -> () +! CHECK: fir.if %[[VAL_32]] { +! CHECK: fir.freemem %[[VAL_34]] : !fir.heap>> +! CHECK: } +! CHECK: return +! CHECK: } end subroutine end diff --git a/flang/test/Lower/parent-component.f90 b/flang/test/Lower/parent-component.f90 index ea7e774..88c7df0 100644 --- a/flang/test/Lower/parent-component.f90 +++ b/flang/test/Lower/parent-component.f90 @@ -58,9 +58,7 @@ contains ! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[TEMP:.*]] = fir.if %[[IS_CONTIGOUS]] -> (!fir.heap>>) { ! CHECK: } else { - ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%{{.*}} = %{{.*}}) -> (!fir.array<2x!fir.type<_QFTp{a:i32}>>) - ! CHECK: %{{.*}} = fir.field_index a, !fir.type<_QFTp{a:i32}> - ! CHECK-NOT: %{{.*}} = fir.field_index b, !fir.type<_QFTp{a:i32}> + ! CHECK: fir.call @_FortranAAssign ! CHECK: %[[TEMP_CAST:.*]] = fir.convert %[[TEMP]] : (!fir.heap>>) -> !fir.ref>> ! CHECK: fir.call @_QFPprint_p(%[[TEMP_CAST]]) {{.*}}: (!fir.ref>>) -> () @@ -96,9 +94,7 @@ contains ! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[TEMP:.*]] = fir.if %[[IS_CONTIGOUS]] -> (!fir.heap>>) { ! CHECK: } else { - ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%{{.*}} = %{{.*}}) -> (!fir.array<2x!fir.type<_QFTp{a:i32}>>) - ! CHECK: %{{.*}} = fir.field_index a, !fir.type<_QFTp{a:i32}> - ! CHECK-NOT: %{{.*}} = fir.field_index b, !fir.type<_QFTp{a:i32}> + ! CHECK: fir.call @_FortranAAssign ! CHECK: %[[TEMP_CAST:.*]] = fir.convert %[[TEMP]] : (!fir.heap>>) -> !fir.ref>> ! CHECK: fir.call @_QFPprint_p(%[[TEMP_CAST]]) {{.*}}: (!fir.ref>>) -> () @@ -143,9 +139,7 @@ contains ! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[TEMP:.*]] = fir.if %[[IS_CONTIGOUS]] -> (!fir.heap>>) { ! CHECK: } else { - ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%{{.*}} = %{{.*}}) -> (!fir.array>) - ! CHECK: %{{.*}} = fir.field_index a, !fir.type<_QFTp{a:i32}> - ! CHECK-NOT: %{{.*}} = fir.field_index b, !fir.type<_QFTp{a:i32}> + ! CHECK: fir.call @_FortranAAssign ! CHECK: %[[TEMP_CAST:.*]] = fir.convert %[[TEMP]] : (!fir.heap>>) -> !fir.ref>> ! CHECK: fir.call @_QFPprint_p(%[[TEMP_CAST]]) {{.*}}: (!fir.ref>>) -> () @@ -199,7 +193,7 @@ contains ! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]] : (!fir.box>>) -> !fir.box>> ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %13, %[[C0]] : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) ! CHECK: %[[C1:.*]] = arith.constant 1 : index ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> ! CHECK: %[[REBOX:.*]] = fir.rebox %arg0 [%[[SLICE]]] : (!fir.box>>, !fir.slice<1>) -> !fir.box>> -- 2.7.4