[flang-commits] [flang] [flang] Added LoopInvariantCodeMotion pass for [HL]FIR. (PR #173438)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Tue Dec 23 17:12:53 PST 2025
https://github.com/vzakhari updated https://github.com/llvm/llvm-project/pull/173438
>From df125f74452fc14f1404824c7d3dae575ee87767 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 23 Dec 2025 16:35:58 -0800
Subject: [PATCH 1/3] [flang] Improve FIR mod-ref analysis.
We may recurse into `HasRecursiveMemoryEffects` operations and
use `getModRef` recursively to get more precise results for
regions with `fir.call` operations.
This patch also modifies `AliasAnalysis` to set the instantiation
point for cases where the tracked data is accessed through a load
from `!fir.ref<!fir.box<>>`: without this change the mod-ref
analysis was not able to recognize user pointer/allocatable variables.
---
.../lib/Optimizer/Analysis/AliasAnalysis.cpp | 58 ++++++++++-------
.../AliasAnalysis/gen_mod_ref_test.py | 10 +++
.../AliasAnalysis/modref-call-dummies.f90 | 61 +++++++++++++++++-
.../AliasAnalysis/modref-call-globals.f90 | 22 +++++++
.../AliasAnalysis/modref-call-recursive.fir | 62 +++++++++++++++++++
5 files changed, 187 insertions(+), 26 deletions(-)
create mode 100644 flang/test/Analysis/AliasAnalysis/modref-call-recursive.fir
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index d2656fa7b8ea8..0dc9dda3aa0f5 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -468,7 +468,8 @@ static ModRefResult getCallModRef(fir::CallOp call, mlir::Value var) {
// TODO: limit to Fortran functions??
// 1. Detect variables that can be accessed indirectly.
fir::AliasAnalysis aliasAnalysis;
- fir::AliasAnalysis::Source varSrc = aliasAnalysis.getSource(var);
+ fir::AliasAnalysis::Source varSrc =
+ aliasAnalysis.getSource(var, /*getLastInstantiationPoint=*/true);
// If the variable is not a user variable, we cannot safely assume that
// Fortran semantics apply (e.g., a bare alloca/allocmem result may very well
// be placed in an allocatable/pointer descriptor and escape).
@@ -498,6 +499,7 @@ static ModRefResult getCallModRef(fir::CallOp call, mlir::Value var) {
// At that stage, it has been ruled out that local (including the saved ones)
// and dummy cannot be indirectly accessed in the call.
if (varSrc.kind != fir::AliasAnalysis::SourceKind::Allocate &&
+ varSrc.kind != fir::AliasAnalysis::SourceKind::Argument &&
!varSrc.isDummyArgument()) {
if (varSrc.kind != fir::AliasAnalysis::SourceKind::Global ||
!isSavedLocal(varSrc))
@@ -523,19 +525,36 @@ static ModRefResult getCallModRef(fir::CallOp call, mlir::Value var) {
/// flow analysis to come 2) Allocate and Free effects are considered
/// modifying
ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) {
- MemoryEffectOpInterface interface = dyn_cast<MemoryEffectOpInterface>(op);
- if (!interface) {
- if (auto call = llvm::dyn_cast<fir::CallOp>(op))
- return getCallModRef(call, location);
- return ModRefResult::getModAndRef();
- }
+ if (auto call = llvm::dyn_cast<fir::CallOp>(op))
+ return getCallModRef(call, location);
// Build a ModRefResult by merging the behavior of the effects of this
// operation.
+ ModRefResult result = ModRefResult::getNoModRef();
+ MemoryEffectOpInterface interface = dyn_cast<MemoryEffectOpInterface>(op);
+ if (op->hasTrait<mlir::OpTrait::HasRecursiveMemoryEffects>()) {
+ for (mlir::Region ®ion : op->getRegions()) {
+ result = result.merge(getModRef(region, location));
+ if (result.isModAndRef())
+ break;
+ }
+
+ // In MLIR, RecursiveMemoryEffects can be combined with
+ // MemoryEffectOpInterface to describe extra effects on top of the
+ // effects of the nested operations. However, the presence of
+ // RecursiveMemoryEffects and the absence of MemoryEffectOpInterface
+ // implies the operation has no other memory effects than the one of its
+ // nested operations.
+ if (!interface)
+ return result;
+ }
+
+ if (!interface || result.isModAndRef())
+ return ModRefResult::getModAndRef();
+
SmallVector<MemoryEffects::EffectInstance> effects;
interface.getEffects(effects);
- ModRefResult result = ModRefResult::getNoModRef();
for (const MemoryEffects::EffectInstance &effect : effects) {
// Check for an alias between the effect and our memory location.
@@ -563,22 +582,6 @@ ModRefResult AliasAnalysis::getModRef(mlir::Region ®ion,
mlir::Value location) {
ModRefResult result = ModRefResult::getNoModRef();
for (mlir::Operation &op : region.getOps()) {
- if (op.hasTrait<mlir::OpTrait::HasRecursiveMemoryEffects>()) {
- for (mlir::Region &subRegion : op.getRegions()) {
- result = result.merge(getModRef(subRegion, location));
- // Fast return is already mod and ref.
- if (result.isModAndRef())
- return result;
- }
- // In MLIR, RecursiveMemoryEffects can be combined with
- // MemoryEffectOpInterface to describe extra effects on top of the
- // effects of the nested operations. However, the presence of
- // RecursiveMemoryEffects and the absence of MemoryEffectOpInterface
- // implies the operation has no other memory effects than the one of its
- // nested operations.
- if (!mlir::isa<mlir::MemoryEffectOpInterface>(op))
- continue;
- }
result = result.merge(getModRef(&op, location));
if (result.isModAndRef())
return result;
@@ -674,6 +677,13 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
isCapturedInInternalProcedure |=
boxSrc.isCapturedInInternalProcedure;
+ if (getLastInstantiationPoint) {
+ if (!instantiationPoint)
+ instantiationPoint = boxSrc.origin.instantiationPoint;
+ } else {
+ instantiationPoint = boxSrc.origin.instantiationPoint;
+ }
+
global = llvm::dyn_cast<mlir::SymbolRefAttr>(boxSrc.origin.u);
if (global) {
type = SourceKind::Global;
diff --git a/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py b/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py
index ce7d9b1700bf7..953f1a2545781 100755
--- a/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py
+++ b/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py
@@ -7,11 +7,14 @@
This will insert mod ref test hook:
- to any fir.call to a function which name starts with "test_effect_"
- to any hlfir.declare for variable which name starts with "test_var_"
+ - to any fir.box_addr - they are assigned box_addr_# hooks
"""
import sys
import re
+box_addr_counter=0
+
for line in sys.stdin:
line = re.sub(
r"(fir.call @_\w*P)(test_effect_\w*)(\(.*) : ",
@@ -23,4 +26,11 @@
r'\1\2", test.ptr ="\2"',
line,
)
+ line, count = re.subn(
+ r'(fir.box_addr.*) :',
+ rf'\1 {{test.ptr ="box_addr_{box_addr_counter}"}} :',
+ line,
+ )
+ if count > 0:
+ box_addr_counter += 1
sys.stdout.write(line)
diff --git a/flang/test/Analysis/AliasAnalysis/modref-call-dummies.f90 b/flang/test/Analysis/AliasAnalysis/modref-call-dummies.f90
index a4c57cff70927..a81f266b87979 100644
--- a/flang/test/Analysis/AliasAnalysis/modref-call-dummies.f90
+++ b/flang/test/Analysis/AliasAnalysis/modref-call-dummies.f90
@@ -20,7 +20,7 @@ subroutine test_dummy(test_var_x)
use somemod, only : may_capture
implicit none
real :: test_var_x
- ! Capture is invalid after the call because test_var_xsaved does not have the
+ ! Capture is invalid after the call because test_var_x does not have the
! target attribute.
call may_capture(test_var_x)
call test_effect_external()
@@ -50,4 +50,61 @@ subroutine test_dummy_pointer(p)
end associate
end subroutine
! CHECK-LABEL: Testing : "_QPtest_dummy_pointer"
-! CHECK: test_effect_external -> test_var_p_target#0: ModRef
+! CHECK-DAG: test_effect_external -> test_var_p_target#0: ModRef
+! CHECK-DAG: test_effect_external -> box_addr_0#0: ModRef
+
+subroutine test_dummy_allocatable(test_var_x)
+ use somemod, only : may_capture
+ implicit none
+ real, allocatable :: test_var_x
+ ! Capture is invalid after the call because test_var_x does not have the
+ ! target attribute.
+ call may_capture(test_var_x)
+ call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_dummy_allocatable"
+! CHECK-DAG: test_effect_external -> test_var_x#0: NoModRef
+! We used to report the next one as ModRef:
+! CHECK-DAG: test_effect_external -> box_addr_1#0: NoModRef
+
+subroutine test_target_dummy_allocatable(test_var_x)
+ use somemod, only : may_capture
+ implicit none
+ real, allocatable, target :: test_var_x
+ call may_capture(test_var_x)
+ call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_target_dummy_allocatable"
+! CHECK-DAG: test_effect_external -> test_var_x#0: ModRef
+! We used to report the next one as ModRef:
+! CHECK-DAG: test_effect_external -> box_addr_2#0: ModRef
+
+subroutine test_dummy_derived_with_allocatable(test_var_x)
+ use somemod, only : may_capture
+ implicit none
+ type t
+ real, allocatable :: member
+ end type t
+ type(t) test_var_x
+ call may_capture(test_var_x%member)
+ call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_dummy_derived_with_allocatable"
+! CHECK-DAG: test_effect_external -> test_var_x#0: NoModRef
+! We used to report the next one as ModRef:
+! CHECK-DAG: test_effect_external -> box_addr_3#0: NoModRef
+
+subroutine test_target_dummy_derived_with_allocatable(test_var_x)
+ use somemod, only : may_capture
+ implicit none
+ type t
+ real, allocatable :: member
+ end type t
+ type(t), target :: test_var_x
+ call may_capture(test_var_x%member)
+ call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_target_dummy_derived_with_allocatable"
+! CHECK-DAG: test_effect_external -> test_var_x#0: ModRef
+! We used to report the next one as ModRef:
+! CHECK-DAG: test_effect_external -> box_addr_4#0: ModRef
diff --git a/flang/test/Analysis/AliasAnalysis/modref-call-globals.f90 b/flang/test/Analysis/AliasAnalysis/modref-call-globals.f90
index fd1d37d18ae15..a9b0b67b1ee11 100644
--- a/flang/test/Analysis/AliasAnalysis/modref-call-globals.f90
+++ b/flang/test/Analysis/AliasAnalysis/modref-call-globals.f90
@@ -8,6 +8,8 @@
module somemod
implicit none
real :: test_var_xmod
+ real, pointer :: test_var_ptr
+ real, allocatable :: test_var_alloc
interface
subroutine may_capture(x)
real, target :: x
@@ -80,3 +82,23 @@ subroutine test_common
end subroutine
! CHECK-LABEL: Testing : "_QPtest_common"
! CHECK: test_effect_external -> test_var_x_common#0: ModRef
+
+subroutine test_module_pointer
+ use somemod, only : may_capture, test_var_ptr
+ implicit none
+ call may_capture(test_var_ptr)
+ call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_module_pointer"
+! CHECK-DAG: test_effect_external -> test_var_ptr#0: ModRef
+! CHECK-DAG: test_effect_external -> box_addr_0#0: ModRef
+
+subroutine test_module_allocatable
+ use somemod, only : may_capture, test_var_alloc
+ implicit none
+ call may_capture(test_var_alloc)
+ call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_module_allocatable"
+! CHECK-DAG: test_effect_external -> test_var_alloc#0: ModRef
+! CHECK-DAG: test_effect_external -> box_addr_1#0: ModRef
diff --git a/flang/test/Analysis/AliasAnalysis/modref-call-recursive.fir b/flang/test/Analysis/AliasAnalysis/modref-call-recursive.fir
new file mode 100644
index 0000000000000..eec8e744ebcfe
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/modref-call-recursive.fir
@@ -0,0 +1,62 @@
+// RUN: fir-opt -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis-modref))' \
+// RUN: --mlir-disable-threading %s -o /dev/null 2>&1 | FileCheck %s
+
+// Test modref for fir.call's nested in regions.
+
+// CHECK-LABEL: Testing : "_QPtest_if_then"
+// CHECK: test_if -> test_var_if#0: NoModRef
+// CHECK: test_if -> test_var_if#1: NoModRef
+func.func @_QPtest_if_then(%arg0: !fir.ref<f32> {fir.bindc_name = "test_var_if"}, %arg1: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1:2 = hlfir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_if_thenEcond"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+ %2:2 = hlfir.declare %arg0 dummy_scope %0 arg 1 {uniq_name = "_QFtest_if_thenEtest_var_if", test.ptr ="test_var_if"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %3 = fir.load %1#0 : !fir.ref<!fir.logical<4>>
+ %4 = fir.convert %3 : (!fir.logical<4>) -> i1
+ fir.if %4 {
+ fir.call @_QPtest_effect_external() fastmath<contract> : () -> ()
+ } {test.ptr ="test_if"}
+ return
+}
+
+// CHECK-LABEL: Testing : "_QPtest_if_then_else"
+// CHECK: test_if_then_else -> test_var_if_then_else#0: NoModRef
+// CHECK: test_if_then_else -> test_var_if_then_else#1: NoModRef
+func.func @_QPtest_if_then_else(%arg0: !fir.ref<f32> {fir.bindc_name = "test_var_if_then_else"}, %arg1: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1:2 = hlfir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_if_then_elseEcond"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+ %2:2 = hlfir.declare %arg0 dummy_scope %0 arg 1 {uniq_name = "_QFtest_if_then_elseEtest_var_if_then_else", test.ptr ="test_var_if_then_else"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %3 = fir.load %1#0 : !fir.ref<!fir.logical<4>>
+ %4 = fir.convert %3 : (!fir.logical<4>) -> i1
+ fir.if %4 {
+ } else {
+ fir.call @_QPtest_effect_external() fastmath<contract> : () -> ()
+ } {test.ptr ="test_if_then_else"}
+ return
+}
+
+// CHECK-LABEL: Testing : "_QPtest_do_loop"
+// CHECK: test_do_loop -> test_var_do_loop#0: NoModRef
+// CHECK: test_do_loop -> test_var_do_loop#1: NoModRef
+func.func @_QPtest_do_loop(%arg0: !fir.ref<f32> {fir.bindc_name = "test_var_do_loop"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_do_loopEi"}
+ %2:2 = hlfir.declare %1 {uniq_name = "_QFtest_do_loopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %3:2 = hlfir.declare %arg0 dummy_scope %0 arg 1 {uniq_name = "_QFtest_do_loopEtest_var_do_loop", test.ptr ="test_var_do_loop"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %c1_i32 = arith.constant 1 : i32
+ %4 = fir.convert %c1_i32 : (i32) -> index
+ %c10_i32 = arith.constant 10 : i32
+ %5 = fir.convert %c10_i32 : (i32) -> index
+ %c1 = arith.constant 1 : index
+ %6 = fir.convert %4 : (index) -> i32
+ %7 = fir.do_loop %arg1 = %4 to %5 step %c1 iter_args(%arg2 = %6) -> (i32) attributes {test.ptr ="test_do_loop"} {
+ fir.store %arg2 to %2#0 : !fir.ref<i32>
+ fir.call @_QPtest_effect_external() fastmath<contract> : () -> ()
+ %8 = fir.convert %c1 : (index) -> i32
+ %9 = fir.load %2#0 : !fir.ref<i32>
+ %10 = arith.addi %9, %8 overflow<nsw> : i32
+ fir.result %10 : i32
+ }
+ fir.store %7 to %2#0 : !fir.ref<i32>
+ return
+}
+func.func private @_QPtest_effect_external()
>From 9dc62b6b2a0a8b64ab733d564bd26dd1af65eef8 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 23 Dec 2025 16:36:07 -0800
Subject: [PATCH 2/3] [flang] Added LoopInvariantCodeMotion pass for [HL]FIR.
The new pass allows hoisting some `fir.load` operations early
in MLIR. For example, many descriptor load might be hoisted
out of the loops, though it does not make much difference
in performance, because LLVM is able to optimize such loads
(which are lowered as `llvm.memcpy` into temporary descriptors),
given that proper TBAA information is generated by Flang.
Further hoisting improvements are possible in [HL]FIR LICM,
e.g. getting proper mod-ref results for Fortran runtime calls
may allow hoisting loads from global variables, which LLVM
cannot do due to lack of alias information.
---
.../flang/Optimizer/Transforms/Passes.td | 11 +
flang/lib/Optimizer/Passes/Pipelines.cpp | 4 +
flang/lib/Optimizer/Transforms/CMakeLists.txt | 53 +-
.../Transforms/LoopInvariantCodeMotion.cpp | 233 +++
flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 3 +
flang/test/Driver/mlir-pass-pipeline.f90 | 3 +
flang/test/Fir/basic-program.fir | 3 +
.../Lower/array-expression-assumed-size.f90 | 323 ++--
flang/test/Lower/array-temp.f90 | 512 +++----
flang/test/Lower/vector-subscript-io.f90 | 10 +-
flang/test/Transforms/licm.fir | 1326 +++++++++++++++++
11 files changed, 2042 insertions(+), 439 deletions(-)
create mode 100644 flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp
create mode 100644 flang/test/Transforms/licm.fir
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index f50202784e2dc..b6b78ec7b21b0 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -596,4 +596,15 @@ def MIFOpConversion : Pass<"mif-convert", "mlir::ModuleOp"> {
let dependentDialects = ["fir::FIROpsDialect", "mlir::LLVM::LLVMDialect"];
}
+def LoopInvariantCodeMotion : Pass<"flang-licm", "::mlir::func::FuncOp"> {
+ let summary = "Hoist invariants from loops";
+ let description = [{
+ Hoist invariants from loops. This is a FIR-specific version of loop
+ invariant code motion, which relies on FIR types, operations (such as
+ fir.declare) and interfaces such as FortranObjectViewOpInterface.
+ The pass only moves existing operations, so there are no dependent
+ dialects.
+ }];
+}
+
#endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 103e736accca0..038ceb1d4bd75 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -206,6 +206,10 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm,
pm.addPass(fir::createSimplifyRegionLite());
pm.addPass(mlir::createCSEPass());
+ // Run LICM after CSE, which may reduce the number of operations to hoist.
+ if (pc.OptLevel.isOptimizingForSpeed())
+ pm.addPass(fir::createLoopInvariantCodeMotion());
+
// Polymorphic types
pm.addPass(fir::createPolymorphicOpConversion());
pm.addPass(fir::createAssumedRankOpConversion());
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 619f3adc67c85..fad6f34f478ba 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -1,43 +1,44 @@
add_flang_library(FIRTransforms
AbstractResult.cpp
AddAliasTags.cpp
- AffinePromotion.cpp
+ AddDebugInfo.cpp
AffineDemotion.cpp
+ AffinePromotion.cpp
+ AlgebraicSimplification.cpp
AnnotateConstant.cpp
+ ArrayValueCopy.cpp
AssumedRankOpConversion.cpp
- CharacterConversion.cpp
- CompilerGeneratedNames.cpp
- ConstantArgumentGlobalisation.cpp
- ControlFlowConverter.cpp
CUDA/CUFAllocationConversion.cpp
CUFAddConstructor.cpp
+ CUFComputeSharedMemoryOffsetsAndSize.cpp
CUFDeviceGlobal.cpp
- CUFOpConversion.cpp
CUFGPUToLLVMConversion.cpp
- CUFComputeSharedMemoryOffsetsAndSize.cpp
- ArrayValueCopy.cpp
+ CUFOpConversion.cpp
+ CharacterConversion.cpp
+ CompilerGeneratedNames.cpp
+ ConstantArgumentGlobalisation.cpp
+ ControlFlowConverter.cpp
+ ConvertComplexPow.cpp
+ DebugTypeGenerator.cpp
ExternalNameConversion.cpp
FIRToSCF.cpp
- MemoryUtils.cpp
- MemoryAllocation.cpp
- StackArrays.cpp
+ FunctionAttr.cpp
+ GenRuntimeCallsForTest.cpp
+ LoopInvariantCodeMotion.cpp
+ LoopVersioning.cpp
+ MIFOpConversion.cpp
MemRefDataFlowOpt.cpp
- SimplifyRegionLite.cpp
- AlgebraicSimplification.cpp
- SimplifyIntrinsics.cpp
- AddDebugInfo.cpp
+ MemoryAllocation.cpp
+ MemoryUtils.cpp
+ OptimizeArrayRepacking.cpp
PolymorphicOpConversion.cpp
- LoopVersioning.cpp
- StackReclaim.cpp
- VScaleAttr.cpp
- FunctionAttr.cpp
- DebugTypeGenerator.cpp
SetRuntimeCallAttributes.cpp
- GenRuntimeCallsForTest.cpp
SimplifyFIROperations.cpp
- OptimizeArrayRepacking.cpp
- ConvertComplexPow.cpp
- MIFOpConversion.cpp
+ SimplifyIntrinsics.cpp
+ SimplifyRegionLite.cpp
+ StackArrays.cpp
+ StackReclaim.cpp
+ VScaleAttr.cpp
DEPENDS
CUFAttrs
@@ -63,12 +64,14 @@ add_flang_library(FIRTransforms
MLIR_LIBS
MLIRAffineUtils
+ MLIRAnalysis
MLIRFuncDialect
MLIRGPUDialect
- MLIRLLVMDialect
MLIRLLVMCommonConversion
+ MLIRLLVMDialect
MLIRMathTransforms
MLIROpenACCDialect
MLIROpenACCToLLVMIRTranslation
MLIROpenMPDialect
+ MLIRTransformUtils
)
diff --git a/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp b/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp
new file mode 100644
index 0000000000000..c033d5e278c8d
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp
@@ -0,0 +1,233 @@
+//===- LoopInvariantCodeMotion.cpp ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// FIR-specific Loop Invariant Code Motion pass.
+/// The pass relies on FIR types and interfaces to prove the safety
+/// of hoisting invariant operations out of loop-like operations.
+/// It may be run on both HLFIR and FIR representations.
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Analysis/AliasAnalysis.h"
+#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/LoopInvariantCodeMotionUtils.h"
+#include "llvm/Support/DebugLog.h"
+
+namespace fir {
+#define GEN_PASS_DEF_LOOPINVARIANTCODEMOTION
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+#define DEBUG_TYPE "flang-licm"
+
+// Temporary engineering option for triaging LICM.
+static llvm::cl::opt<bool> disableFlangLICM(
+ "disable-flang-licm", llvm::cl::init(false), llvm::cl::Hidden,
+ llvm::cl::desc("Disable Flang's loop invariant code motion"));
+
+namespace {
+
+using namespace mlir;
+
+/// The pass tries to hoist loop invariant operations with only
+/// MemoryEffects::Read effects (MemoryEffects::Write support
+/// may be added later).
+/// The safety of hoisting is proven by:
+/// * Proving that the loop runs at least one iteration.
+/// * Proving that is is always safe to load from this location
+/// (see isSafeToHoistLoad() comments below).
+struct LoopInvariantCodeMotion
+ : fir::impl::LoopInvariantCodeMotionBase<LoopInvariantCodeMotion> {
+ void runOnOperation() override;
+};
+
+} // namespace
+
+/// 'location' is a memory reference used by a memory access.
+/// The type of 'location' defines the data type of the access
+/// (e.g. it is considered to be invalid to access 'i64'
+/// data using '!fir.ref<i32>`).
+/// For the given location, this function returns true iff
+/// the Fortran object being accessed is a scalar that
+/// may not be OPTIONAL.
+///
+/// Note that the '!fir.ref<!fir.box<>>' accesses are considered
+/// to be scalar, even if the underlying data is an array.
+///
+/// Note that an access of '!fir.ref<scalar>' may access
+/// an array object. For example:
+/// real :: x(:)
+/// do i=...
+/// = x(10)
+/// 'x(10)' accesses array 'x', and it may be unsafe to hoist
+/// it without proving that '10' is a valid index for the array.
+/// The fact that 'x' is not OPTIONAL does not allow hoisting
+/// on its own.
+static bool isNonOptionalScalar(Value location) {
+ while (true) {
+ LDBG() << "Checking location:\n" << location;
+ Type dataType = fir::unwrapRefType(location.getType());
+ if (!isa<fir::BaseBoxType>(location.getType()) &&
+ (!dataType ||
+ (!isa<fir::BaseBoxType>(dataType) && !fir::isa_trivial(dataType) &&
+ !fir::isa_derived(dataType)))) {
+ LDBG() << "Failure: data access is not scalar";
+ return false;
+ }
+ Operation *defOp = location.getDefiningOp();
+ if (!defOp) {
+ LDBG() << "Failure: no defining operation";
+ return false;
+ }
+ if (auto varIface = dyn_cast<fir::FortranVariableOpInterface>(defOp)) {
+ bool result = !varIface.isOptional();
+ if (result)
+ LDBG() << "Success: is non optional scalar";
+ else
+ LDBG() << "Failure: is not non optional scalar";
+ return result;
+ }
+ if (auto viewIface = dyn_cast<fir::FortranObjectViewOpInterface>(defOp)) {
+ location = viewIface.getViewSource(cast<OpResult>(location));
+ } else {
+ LDBG() << "Failure: unknown operation:\n" << *defOp;
+ return false;
+ }
+ }
+}
+
+/// Returns true iff it is safe to hoist the given load-like operation 'op',
+/// which access given memory 'locations', out of the operation 'loopLike'.
+/// The current safety conditions are:
+/// * The loop runs at least one iteration, OR
+/// * all the accessed locations are inside scalar non-OPTIONAL
+/// Fortran objects (Fortran descriptors are considered to be scalars).
+static bool isSafeToHoistLoad(Operation *op, ArrayRef<Value> locations,
+ LoopLikeOpInterface loopLike,
+ AliasAnalysis &aliasAnalysis) {
+ for (Value location : locations)
+ if (aliasAnalysis.getModRef(loopLike.getOperation(), location)
+ .isModAndRef()) {
+ LDBG() << "Failure: reads location:\n"
+ << location << "\nwhich is modified inside the loop";
+ return false;
+ }
+
+ // Check that it is safe to read from all the locations before the loop.
+ std::optional<llvm::APInt> tripCount = loopLike.getStaticTripCount();
+ if (tripCount && !tripCount->isZero()) {
+ // Loop executes at least one iteration, so it is safe to hoist.
+ LDBG() << "Success: loop has non-zero iterations";
+ return true;
+ }
+
+ // Check whether the access must always be valid.
+ return llvm::all_of(
+ locations, [&](Value location) { return isNonOptionalScalar(location); });
+ // TODO: consider hoisting under condition of the loop's trip count
+ // being non-zero.
+}
+
+/// Returns true iff the given 'op' is a load-like operation,
+/// and it can be hoisted out of 'loopLike' operation.
+static bool canHoistLoad(Operation *op, LoopLikeOpInterface loopLike,
+ AliasAnalysis &aliasAnalysis) {
+ LDBG() << "Checking operation:\n" << *op;
+ if (auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
+ SmallVector<MemoryEffects::EffectInstance> effects;
+ effectInterface.getEffects(effects);
+ if (effects.empty()) {
+ LDBG() << "Failure: not a load";
+ return false;
+ }
+ llvm::SetVector<Value> locations;
+ for (const MemoryEffects::EffectInstance &effect : effects) {
+ Value location = effect.getValue();
+ if (!isa<MemoryEffects::Read>(effect.getEffect())) {
+ LDBG() << "Failure: has unsupported effects";
+ return false;
+ } else if (!location) {
+ LDBG() << "Failure: reads from unknown location";
+ return false;
+ }
+ locations.insert(location);
+ }
+ return isSafeToHoistLoad(op, locations.getArrayRef(), loopLike,
+ aliasAnalysis);
+ }
+ LDBG() << "Failure: has unknown effects";
+ return false;
+}
+
+void LoopInvariantCodeMotion::runOnOperation() {
+ if (disableFlangLICM) {
+ LDBG() << "Skipping [HL]FIR LoopInvariantCodeMotion()";
+ return;
+ }
+
+ LDBG() << "Enter [HL]FIR LoopInvariantCodeMotion()";
+
+ auto &aliasAnalysis = getAnalysis<AliasAnalysis>();
+ aliasAnalysis.addAnalysisImplementation(fir::AliasAnalysis{});
+
+ std::function<bool(Operation *, LoopLikeOpInterface loopLike)>
+ shouldMoveOutOfLoop = [&](Operation *op, LoopLikeOpInterface loopLike) {
+ if (isPure(op)) {
+ LDBG() << "Pure operation: " << *op;
+ return true;
+ }
+
+ // Handle RecursivelySpeculatable operations that have
+ // RecursiveMemoryEffects by checking if all their
+ // nested operations can be hoisted.
+ auto iface = dyn_cast<ConditionallySpeculatable>(op);
+ if (iface && iface.getSpeculatability() ==
+ Speculation::RecursivelySpeculatable) {
+ if (op->hasTrait<OpTrait::HasRecursiveMemoryEffects>()) {
+ LDBG() << "Checking recursive operation:\n" << *op;
+ llvm::SmallVector<Operation *> nestedOps;
+ for (Region ®ion : op->getRegions())
+ for (Block &block : region)
+ for (Operation &nestedOp : block)
+ nestedOps.push_back(&nestedOp);
+
+ bool result = llvm::all_of(nestedOps, [&](Operation *nestedOp) {
+ return shouldMoveOutOfLoop(nestedOp, loopLike);
+ });
+ LDBG() << "Recursive operation can" << (result ? "" : "not")
+ << " be hoisted";
+
+ // If nested operations cannot be hoisted, there is nothing
+ // else to check. Also if the operation itself does not have
+ // any memory effects, we can return the result now.
+ // Otherwise, we have to check the operation itself below.
+ if (!result || !isa<MemoryEffectOpInterface>(op))
+ return result;
+ }
+ }
+ return canHoistLoad(op, loopLike, aliasAnalysis);
+ };
+
+ getOperation()->walk([&](LoopLikeOpInterface loopLike) {
+ moveLoopInvariantCode(
+ loopLike.getLoopRegions(),
+ /*isDefinedOutsideRegion=*/
+ [&](Value value, Region *) {
+ return loopLike.isDefinedOutsideOfLoop(value);
+ },
+ /*shouldMoveOutOfRegion=*/
+ [&](Operation *op, Region *) {
+ return shouldMoveOutOfLoop(op, loopLike);
+ },
+ /*moveOutOfRegion=*/
+ [&](Operation *op, Region *) { loopLike.moveOutOfLoop(op); });
+ });
+
+ LDBG() << "Exit [HL]FIR LoopInvariantCodeMotion()";
+}
diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
index bf2712d547a82..54588a711a023 100644
--- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90
+++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
@@ -45,6 +45,9 @@
! CHECK-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
! CHECK-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! CHECK-NEXT: 'func.func' Pipeline
+! CHECK-NEXT: LoopInvariantCodeMotion
+
! CHECK-NEXT: PolymorphicOpConversion
! CHECK-NEXT: AssumedRankOpConversion
! CHECK-NEXT: 'func.func' Pipeline
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index 0d68191fedc1e..94c364ee3b983 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -112,6 +112,9 @@
! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! O2-NEXT: 'func.func' Pipeline
+! O2-NEXT: LoopInvariantCodeMotion
+
! ALL-NEXT: PolymorphicOpConversion
! ALL-NEXT: AssumedRankOpConversion
! O2-NEXT: 'func.func' Pipeline
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index 6d2beae4da1c8..1b34237447230 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -102,6 +102,9 @@ func.func @_QQmain() {
// PASSES-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
// PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT: LoopInvariantCodeMotion
+
// PASSES-NEXT: PolymorphicOpConversion
// PASSES-NEXT: AssumedRankOpConversion
// PASSES-NEXT: 'func.func' Pipeline
diff --git a/flang/test/Lower/array-expression-assumed-size.f90 b/flang/test/Lower/array-expression-assumed-size.f90
index b51dc00c20e28..62f23b34cee4f 100644
--- a/flang/test/Lower/array-expression-assumed-size.f90
+++ b/flang/test/Lower/array-expression-assumed-size.f90
@@ -141,163 +141,168 @@ end subroutine assumed_size_forall_test
! CHECK: return
! CHECK: }
-! PostOpt-LABEL: func @_QPassumed_size_test(
-! PostOpt-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x?xi32>>{{.*}}) {
-! PostOpt-DAG: %[[VAL_1:.*]] = arith.constant 10 : index
-! PostOpt-DAG: %[[VAL_2:.*]] = arith.constant 1 : index
-! PostOpt-DAG: %[[VAL_3:.*]] = arith.constant 2 : index
-! PostOpt-DAG: %[[VAL_4:.*]] = arith.constant 0 : index
-! PostOpt-DAG: %[[VAL_5:.*]] = arith.constant 3 : index
-! PostOpt-DAG: %[[VAL_6:.*]] = arith.constant 4 : index
-! PostOpt-DAG: %[[VAL_7:.*]] = fir.assumed_size_extent : index
-! PostOpt: %[[VAL_8:.*]] = fir.shape %[[VAL_1]], %[[VAL_7]] : (index, index) -> !fir.shape<2>
-! PostOpt: %[[VAL_9:.*]] = fir.slice %[[VAL_2]], %[[VAL_1]], %[[VAL_2]], %[[VAL_2]], %[[VAL_3]], %[[VAL_2]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! PostOpt: %[[VAL_10:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[VAL_3]]
-! PostOpt: br ^bb1(%[[VAL_4]], %[[VAL_3]] : index, index)
-! PostOpt: ^bb1(%[[VAL_11:.*]]: index, %[[VAL_12:.*]]: index):
-! PostOpt: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_12]], %[[VAL_4]] : index
-! PostOpt: cond_br %[[VAL_13]], ^bb2(%[[VAL_4]], %[[VAL_1]] : index, index), ^bb5
-! PostOpt: ^bb2(%[[VAL_14:.*]]: index, %[[VAL_15:.*]]: index):
-! PostOpt: %[[VAL_16:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_4]] : index
-! PostOpt: cond_br %[[VAL_16]], ^bb3, ^bb4
-! PostOpt: ^bb3:
-! PostOpt: %[[VAL_17:.*]] = arith.addi %[[VAL_14]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_18:.*]] = arith.addi %[[VAL_11]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_19:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_8]]) {{\[}}%[[VAL_9]]] %[[VAL_17]], %[[VAL_18]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_20:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_8]]) %[[VAL_17]], %[[VAL_18]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_21:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
-! PostOpt: fir.store %[[VAL_21]] to %[[VAL_20]] : !fir.ref<i32>
-! PostOpt: %[[VAL_22:.*]] = arith.subi %[[VAL_15]], %[[VAL_2]] : index
-! PostOpt: br ^bb2(%[[VAL_17]], %[[VAL_22]] : index, index)
-! PostOpt: ^bb4:
-! PostOpt: %[[VAL_23:.*]] = arith.addi %[[VAL_11]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_24:.*]] = arith.subi %[[VAL_12]], %[[VAL_2]] : index
-! PostOpt: br ^bb1(%[[VAL_23]], %[[VAL_24]] : index, index)
-! PostOpt: ^bb5:
-! PostOpt: %[[VAL_25:.*]] = fir.slice %[[VAL_2]], %[[VAL_1]], %[[VAL_2]], %[[VAL_5]], %[[VAL_6]], %[[VAL_2]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! PostOpt: br ^bb6(%[[VAL_4]], %[[VAL_3]] : index, index)
-! PostOpt: ^bb6(%[[VAL_26:.*]]: index, %[[VAL_27:.*]]: index):
-! PostOpt: %[[VAL_28:.*]] = arith.cmpi sgt, %[[VAL_27]], %[[VAL_4]] : index
-! PostOpt: cond_br %[[VAL_28]], ^bb7(%[[VAL_4]], %[[VAL_1]] : index, index), ^bb10(%[[VAL_4]], %[[VAL_3]] : index, index)
-! PostOpt: ^bb7(%[[VAL_29:.*]]: index, %[[VAL_30:.*]]: index):
-! PostOpt: %[[VAL_31:.*]] = arith.cmpi sgt, %[[VAL_30]], %[[VAL_4]] : index
-! PostOpt: cond_br %[[VAL_31]], ^bb8, ^bb9
-! PostOpt: ^bb8:
-! PostOpt: %[[VAL_32:.*]] = arith.addi %[[VAL_29]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_33:.*]] = arith.addi %[[VAL_26]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_34:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_8]]) {{\[}}%[[VAL_25]]] %[[VAL_32]], %[[VAL_33]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_35:.*]] = fir.load %[[VAL_34]] : !fir.ref<i32>
-! PostOpt: %[[VAL_36:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_8]]) %[[VAL_32]], %[[VAL_33]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: fir.store %[[VAL_35]] to %[[VAL_36]] : !fir.ref<i32>
-! PostOpt: %[[VAL_37:.*]] = arith.subi %[[VAL_30]], %[[VAL_2]] : index
-! PostOpt: br ^bb7(%[[VAL_32]], %[[VAL_37]] : index, index)
-! PostOpt: ^bb9:
-! PostOpt: %[[VAL_38:.*]] = arith.addi %[[VAL_26]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_39:.*]] = arith.subi %[[VAL_27]], %[[VAL_2]] : index
-! PostOpt: br ^bb6(%[[VAL_38]], %[[VAL_39]] : index, index)
-! PostOpt: ^bb10(%[[VAL_40:.*]]: index, %[[VAL_41:.*]]: index):
-! PostOpt: %[[VAL_42:.*]] = arith.cmpi sgt, %[[VAL_41]], %[[VAL_4]] : index
-! PostOpt: cond_br %[[VAL_42]], ^bb11(%[[VAL_4]], %[[VAL_1]] : index, index), ^bb14
-! PostOpt: ^bb11(%[[VAL_43:.*]]: index, %[[VAL_44:.*]]: index):
-! PostOpt: %[[VAL_45:.*]] = arith.cmpi sgt, %[[VAL_44]], %[[VAL_4]] : index
-! PostOpt: cond_br %[[VAL_45]], ^bb12, ^bb13
-! PostOpt: ^bb12:
-! PostOpt: %[[VAL_46:.*]] = arith.addi %[[VAL_43]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_47:.*]] = arith.addi %[[VAL_40]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_48:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_8]]) %[[VAL_46]], %[[VAL_47]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_49:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_8]]) {{\[}}%[[VAL_9]]] %[[VAL_46]], %[[VAL_47]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_50:.*]] = fir.load %[[VAL_48]] : !fir.ref<i32>
-! PostOpt: fir.store %[[VAL_50]] to %[[VAL_49]] : !fir.ref<i32>
-! PostOpt: %[[VAL_51:.*]] = arith.subi %[[VAL_44]], %[[VAL_2]] : index
-! PostOpt: br ^bb11(%[[VAL_46]], %[[VAL_51]] : index, index)
-! PostOpt: ^bb13:
-! PostOpt: %[[VAL_52:.*]] = arith.addi %[[VAL_40]], %[[VAL_2]] : index
-! PostOpt: %[[VAL_53:.*]] = arith.subi %[[VAL_41]], %[[VAL_2]] : index
-! PostOpt: br ^bb10(%[[VAL_52]], %[[VAL_53]] : index, index)
-! PostOpt: ^bb14:
-! PostOpt: fir.freemem %[[VAL_10]] : !fir.heap<!fir.array<10x?xi32>>
-! PostOpt: return
-! PostOpt: }
+! PostOpt-LABEL: func.func @_QPassumed_size_test(
+! PostOpt-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<10x?xi32>> {fir.bindc_name = "a"}) {
+! PostOpt: %[[CONSTANT_0:.*]] = arith.constant 4 : index
+! PostOpt: %[[CONSTANT_1:.*]] = arith.constant 3 : index
+! PostOpt: %[[CONSTANT_2:.*]] = arith.constant 2 : index
+! PostOpt: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! PostOpt: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! PostOpt: %[[CONSTANT_5:.*]] = arith.constant 10 : index
+! PostOpt: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+! PostOpt: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]], %[[ASSUMED_SIZE_EXTENT_0]] : (index, index) -> !fir.shape<2>
+! PostOpt: %[[SLICE_0:.*]] = fir.slice %[[CONSTANT_3]], %[[CONSTANT_5]], %[[CONSTANT_3]], %[[CONSTANT_3]], %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! PostOpt: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[CONSTANT_2]]
+! PostOpt: cf.br ^bb1(%[[CONSTANT_4]], %[[CONSTANT_2]] : index, index)
+! PostOpt: ^bb1(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index):
+! PostOpt: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[VAL_1]], %[[CONSTANT_4]] : index
+! PostOpt: cf.cond_br %[[CMPI_0]], ^bb2, ^bb6
+! PostOpt: ^bb2:
+! PostOpt: %[[ADDI_0:.*]] = arith.addi %[[VAL_0]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb3(%[[CONSTANT_4]], %[[CONSTANT_5]] : index, index)
+! PostOpt: ^bb3(%[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index):
+! PostOpt: %[[CMPI_1:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[CONSTANT_4]] : index
+! PostOpt: cf.cond_br %[[CMPI_1]], ^bb4, ^bb5
+! PostOpt: ^bb4:
+! PostOpt: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[CONSTANT_3]] : index
+! PostOpt: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_0]]] %[[ADDI_1]], %[[ADDI_0]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_1]], %[[ADDI_0]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[LOAD_0:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<i32>
+! PostOpt: fir.store %[[LOAD_0]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+! PostOpt: %[[SUBI_0:.*]] = arith.subi %[[VAL_3]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb3(%[[ADDI_1]], %[[SUBI_0]] : index, index)
+! PostOpt: ^bb5:
+! PostOpt: %[[SUBI_1:.*]] = arith.subi %[[VAL_1]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb1(%[[ADDI_0]], %[[SUBI_1]] : index, index)
+! PostOpt: ^bb6:
+! PostOpt: %[[SLICE_1:.*]] = fir.slice %[[CONSTANT_3]], %[[CONSTANT_5]], %[[CONSTANT_3]], %[[CONSTANT_1]], %[[CONSTANT_0]], %[[CONSTANT_3]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! PostOpt: cf.br ^bb7(%[[CONSTANT_4]], %[[CONSTANT_2]] : index, index)
+! PostOpt: ^bb7(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: index):
+! PostOpt: %[[CMPI_2:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[CONSTANT_4]] : index
+! PostOpt: cf.cond_br %[[CMPI_2]], ^bb8, ^bb12(%[[CONSTANT_4]], %[[CONSTANT_2]] : index, index)
+! PostOpt: ^bb8:
+! PostOpt: %[[ADDI_2:.*]] = arith.addi %[[VAL_4]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb9(%[[CONSTANT_4]], %[[CONSTANT_5]] : index, index)
+! PostOpt: ^bb9(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):
+! PostOpt: %[[CMPI_3:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[CONSTANT_4]] : index
+! PostOpt: cf.cond_br %[[CMPI_3]], ^bb10, ^bb11
+! PostOpt: ^bb10:
+! PostOpt: %[[ADDI_3:.*]] = arith.addi %[[VAL_6]], %[[CONSTANT_3]] : index
+! PostOpt: %[[ARRAY_COOR_2:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_1]]] %[[ADDI_3]], %[[ADDI_2]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[LOAD_1:.*]] = fir.load %[[ARRAY_COOR_2]] : !fir.ref<i32>
+! PostOpt: %[[ARRAY_COOR_3:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_3]], %[[ADDI_2]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: fir.store %[[LOAD_1]] to %[[ARRAY_COOR_3]] : !fir.ref<i32>
+! PostOpt: %[[SUBI_2:.*]] = arith.subi %[[VAL_7]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb9(%[[ADDI_3]], %[[SUBI_2]] : index, index)
+! PostOpt: ^bb11:
+! PostOpt: %[[SUBI_3:.*]] = arith.subi %[[VAL_5]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb7(%[[ADDI_2]], %[[SUBI_3]] : index, index)
+! PostOpt: ^bb12(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index):
+! PostOpt: %[[CMPI_4:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[CONSTANT_4]] : index
+! PostOpt: cf.cond_br %[[CMPI_4]], ^bb13, ^bb17
+! PostOpt: ^bb13:
+! PostOpt: %[[ADDI_4:.*]] = arith.addi %[[VAL_8]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb14(%[[CONSTANT_4]], %[[CONSTANT_5]] : index, index)
+! PostOpt: ^bb14(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index):
+! PostOpt: %[[CMPI_5:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[CONSTANT_4]] : index
+! PostOpt: cf.cond_br %[[CMPI_5]], ^bb15, ^bb16
+! PostOpt: ^bb15:
+! PostOpt: %[[ADDI_5:.*]] = arith.addi %[[VAL_10]], %[[CONSTANT_3]] : index
+! PostOpt: %[[ARRAY_COOR_4:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_5]], %[[ADDI_4]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[ARRAY_COOR_5:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_0]]] %[[ADDI_5]], %[[ADDI_4]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_4]] : !fir.ref<i32>
+! PostOpt: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_5]] : !fir.ref<i32>
+! PostOpt: %[[SUBI_4:.*]] = arith.subi %[[VAL_11]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb14(%[[ADDI_5]], %[[SUBI_4]] : index, index)
+! PostOpt: ^bb16:
+! PostOpt: %[[SUBI_5:.*]] = arith.subi %[[VAL_9]], %[[CONSTANT_3]] : index
+! PostOpt: cf.br ^bb12(%[[ADDI_4]], %[[SUBI_5]] : index, index)
+! PostOpt: ^bb17:
+! PostOpt: fir.freemem %[[ALLOCMEM_0]] : !fir.heap<!fir.array<10x?xi32>>
+! PostOpt: return
+! PostOpt: }
-! PostOpt-LABEL: func @_QPassumed_size_forall_test(
-! PostOpt-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x?xi32>>{{.*}}) {
-! PostOpt-DAG: %[[VAL_1:.*]] = arith.constant 3 : index
-! PostOpt-DAG: %[[VAL_2:.*]] = arith.constant 10 : index
-! PostOpt-DAG: %[[VAL_3:.*]] = arith.constant 2 : index
-! PostOpt-DAG: %[[VAL_4:.*]] = arith.constant 1 : index
-! PostOpt-DAG: %[[VAL_5:.*]] = arith.constant 0 : index
-! PostOpt-DAG: %[[VAL_6:.*]] = arith.constant 5 : index
-! PostOpt: %[[VAL_7:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
-! PostOpt: %[[VAL_8:.*]] = fir.assumed_size_extent : index
-! PostOpt: %[[VAL_9:.*]] = fir.shape %[[VAL_2]], %[[VAL_8]] : (index, index) -> !fir.shape<2>
-! PostOpt: %[[VAL_10:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[VAL_4]]
-! PostOpt: br ^bb1(%[[VAL_5]], %[[VAL_4]] : index, index)
-! PostOpt: ^bb1(%[[VAL_11:.*]]: index, %[[VAL_12:.*]]: index):
-! PostOpt: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_12]], %[[VAL_5]] : index
-! PostOpt: cond_br %[[VAL_13]], ^bb2(%[[VAL_5]], %[[VAL_2]] : index, index), ^bb5
-! PostOpt: ^bb2(%[[VAL_14:.*]]: index, %[[VAL_15:.*]]: index):
-! PostOpt: %[[VAL_16:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_5]] : index
-! PostOpt: cond_br %[[VAL_16]], ^bb3, ^bb4
-! PostOpt: ^bb3:
-! PostOpt: %[[VAL_17:.*]] = arith.addi %[[VAL_14]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_18:.*]] = arith.addi %[[VAL_11]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_19:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_9]]) %[[VAL_17]], %[[VAL_18]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_20:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_9]]) %[[VAL_17]], %[[VAL_18]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_21:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
-! PostOpt: fir.store %[[VAL_21]] to %[[VAL_20]] : !fir.ref<i32>
-! PostOpt: %[[VAL_22:.*]] = arith.subi %[[VAL_15]], %[[VAL_4]] : index
-! PostOpt: br ^bb2(%[[VAL_17]], %[[VAL_22]] : index, index)
-! PostOpt: ^bb4:
-! PostOpt: %[[VAL_23:.*]] = arith.addi %[[VAL_11]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_24:.*]] = arith.subi %[[VAL_12]], %[[VAL_4]] : index
-! PostOpt: br ^bb1(%[[VAL_23]], %[[VAL_24]] : index, index)
-! PostOpt: ^bb5:
-! PostOpt: br ^bb6(%[[VAL_3]], %[[VAL_6]] : index, index)
-! PostOpt: ^bb6(%[[VAL_25:.*]]: index, %[[VAL_26:.*]]: index):
-! PostOpt: %[[VAL_27:.*]] = arith.cmpi sgt, %[[VAL_26]], %[[VAL_5]] : index
-! PostOpt: cond_br %[[VAL_27]], ^bb7, ^bb11(%[[VAL_5]], %[[VAL_4]] : index, index)
-! PostOpt: ^bb7:
-! PostOpt: %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (index) -> i32
-! PostOpt: fir.store %[[VAL_28]] to %[[VAL_7]] : !fir.ref<i32>
-! PostOpt: %[[VAL_29:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32>
-! PostOpt: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i32) -> index
-! PostOpt: br ^bb8(%[[VAL_5]], %[[VAL_3]] : index, index)
-! PostOpt: ^bb8(%[[VAL_31:.*]]: index, %[[VAL_32:.*]]: index):
-! PostOpt: %[[VAL_33:.*]] = arith.cmpi sgt, %[[VAL_32]], %[[VAL_5]] : index
-! PostOpt: cond_br %[[VAL_33]], ^bb9, ^bb10
-! PostOpt: ^bb9:
-! PostOpt: %[[VAL_34:.*]] = arith.addi %[[VAL_31]], %[[VAL_1]] : index
-! PostOpt: %[[VAL_35:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_9]]) %[[VAL_30]], %[[VAL_34]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_36:.*]] = fir.load %[[VAL_35]] : !fir.ref<i32>
-! PostOpt: %[[VAL_37:.*]] = arith.addi %[[VAL_31]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_38:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_9]]) %[[VAL_30]], %[[VAL_37]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: fir.store %[[VAL_36]] to %[[VAL_38]] : !fir.ref<i32>
-! PostOpt: %[[VAL_39:.*]] = arith.subi %[[VAL_32]], %[[VAL_4]] : index
-! PostOpt: br ^bb8(%[[VAL_37]], %[[VAL_39]] : index, index)
-! PostOpt: ^bb10:
-! PostOpt: %[[VAL_40:.*]] = arith.addi %[[VAL_25]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_41:.*]] = arith.subi %[[VAL_26]], %[[VAL_4]] : index
-! PostOpt: br ^bb6(%[[VAL_40]], %[[VAL_41]] : index, index)
-! PostOpt: ^bb11(%[[VAL_42:.*]]: index, %[[VAL_43:.*]]: index):
-! PostOpt: %[[VAL_44:.*]] = arith.cmpi sgt, %[[VAL_43]], %[[VAL_5]] : index
-! PostOpt: cond_br %[[VAL_44]], ^bb12(%[[VAL_5]], %[[VAL_2]] : index, index), ^bb15
-! PostOpt: ^bb12(%[[VAL_45:.*]]: index, %[[VAL_46:.*]]: index):
-! PostOpt: %[[VAL_47:.*]] = arith.cmpi sgt, %[[VAL_46]], %[[VAL_5]] : index
-! PostOpt: cond_br %[[VAL_47]], ^bb13, ^bb14
-! PostOpt: ^bb13:
-! PostOpt: %[[VAL_48:.*]] = arith.addi %[[VAL_45]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_49:.*]] = arith.addi %[[VAL_42]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_50:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_9]]) %[[VAL_48]], %[[VAL_49]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_51:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_9]]) %[[VAL_48]], %[[VAL_49]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
-! PostOpt: %[[VAL_52:.*]] = fir.load %[[VAL_50]] : !fir.ref<i32>
-! PostOpt: fir.store %[[VAL_52]] to %[[VAL_51]] : !fir.ref<i32>
-! PostOpt: %[[VAL_53:.*]] = arith.subi %[[VAL_46]], %[[VAL_4]] : index
-! PostOpt: br ^bb12(%[[VAL_48]], %[[VAL_53]] : index, index)
-! PostOpt: ^bb14:
-! PostOpt: %[[VAL_54:.*]] = arith.addi %[[VAL_42]], %[[VAL_4]] : index
-! PostOpt: %[[VAL_55:.*]] = arith.subi %[[VAL_43]], %[[VAL_4]] : index
-! PostOpt: br ^bb11(%[[VAL_54]], %[[VAL_55]] : index, index)
-! PostOpt: ^bb15:
-! PostOpt: fir.freemem %[[VAL_10]] : !fir.heap<!fir.array<10x?xi32>>
-! PostOpt: return
-! PostOpt: }
+! PostOpt-LABEL: func.func @_QPassumed_size_forall_test(
+! PostOpt-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<10x?xi32>> {fir.bindc_name = "b"}) {
+! PostOpt: %[[CONSTANT_0:.*]] = arith.constant 5 : index
+! PostOpt: %[[CONSTANT_1:.*]] = arith.constant 3 : index
+! PostOpt: %[[CONSTANT_2:.*]] = arith.constant 2 : index
+! PostOpt: %[[CONSTANT_3:.*]] = arith.constant 10 : index
+! PostOpt: %[[CONSTANT_4:.*]] = arith.constant 1 : index
+! PostOpt: %[[CONSTANT_5:.*]] = arith.constant 0 : index
+! PostOpt: %[[ALLOCA_0:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! PostOpt: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+! PostOpt: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_3]], %[[ASSUMED_SIZE_EXTENT_0]] : (index, index) -> !fir.shape<2>
+! PostOpt: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[CONSTANT_4]]
+! PostOpt: cf.br ^bb1(%[[CONSTANT_5]], %[[CONSTANT_4]] : index, index)
+! PostOpt: ^bb1(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index):
+! PostOpt: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[VAL_1]], %[[CONSTANT_5]] : index
+! PostOpt: cf.cond_br %[[CMPI_0]], ^bb2, ^bb6
+! PostOpt: ^bb2:
+! PostOpt: %[[ADDI_0:.*]] = arith.addi %[[VAL_0]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb3(%[[CONSTANT_5]], %[[CONSTANT_3]] : index, index)
+! PostOpt: ^bb3(%[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index):
+! PostOpt: %[[CMPI_1:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[CONSTANT_5]] : index
+! PostOpt: cf.cond_br %[[CMPI_1]], ^bb4, ^bb5
+! PostOpt: ^bb4:
+! PostOpt: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[CONSTANT_4]] : index
+! PostOpt: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) %[[ADDI_1]], %[[ADDI_0]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_1]], %[[ADDI_0]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[LOAD_0:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<i32>
+! PostOpt: fir.store %[[LOAD_0]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+! PostOpt: %[[SUBI_0:.*]] = arith.subi %[[VAL_3]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb3(%[[ADDI_1]], %[[SUBI_0]] : index, index)
+! PostOpt: ^bb5:
+! PostOpt: %[[SUBI_1:.*]] = arith.subi %[[VAL_1]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb1(%[[ADDI_0]], %[[SUBI_1]] : index, index)
+! PostOpt: ^bb6:
+! PostOpt: cf.br ^bb7(%[[CONSTANT_2]], %[[CONSTANT_0]] : index, index)
+! PostOpt: ^bb7(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: index):
+! PostOpt: %[[CMPI_2:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[CONSTANT_5]] : index
+! PostOpt: cf.cond_br %[[CMPI_2]], ^bb8, ^bb12(%[[CONSTANT_5]], %[[CONSTANT_4]] : index, index)
+! PostOpt: ^bb8:
+! PostOpt: %[[CONVERT_0:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+! PostOpt: fir.store %[[CONVERT_0]] to %[[ALLOCA_0]] : !fir.ref<i32>
+! PostOpt: %[[LOAD_1:.*]] = fir.load %[[ALLOCA_0]] : !fir.ref<i32>
+! PostOpt: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_1]] : (i32) -> index
+! PostOpt: cf.br ^bb9(%[[CONSTANT_5]], %[[CONSTANT_2]] : index, index)
+! PostOpt: ^bb9(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):
+! PostOpt: %[[CMPI_3:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[CONSTANT_5]] : index
+! PostOpt: cf.cond_br %[[CMPI_3]], ^bb10, ^bb11
+! PostOpt: ^bb10:
+! PostOpt: %[[ADDI_2:.*]] = arith.addi %[[VAL_6]], %[[CONSTANT_1]] : index
+! PostOpt: %[[ARRAY_COOR_2:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) %[[CONVERT_1]], %[[ADDI_2]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_2]] : !fir.ref<i32>
+! PostOpt: %[[ADDI_3:.*]] = arith.addi %[[VAL_6]], %[[CONSTANT_4]] : index
+! PostOpt: %[[ARRAY_COOR_3:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[CONVERT_1]], %[[ADDI_3]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_3]] : !fir.ref<i32>
+! PostOpt: %[[SUBI_2:.*]] = arith.subi %[[VAL_7]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb9(%[[ADDI_3]], %[[SUBI_2]] : index, index)
+! PostOpt: ^bb11:
+! PostOpt: %[[ADDI_4:.*]] = arith.addi %[[VAL_4]], %[[CONSTANT_4]] : index
+! PostOpt: %[[SUBI_3:.*]] = arith.subi %[[VAL_5]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb7(%[[ADDI_4]], %[[SUBI_3]] : index, index)
+! PostOpt: ^bb12(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index):
+! PostOpt: %[[CMPI_4:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[CONSTANT_5]] : index
+! PostOpt: cf.cond_br %[[CMPI_4]], ^bb13, ^bb17
+! PostOpt: ^bb13:
+! PostOpt: %[[ADDI_5:.*]] = arith.addi %[[VAL_8]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb14(%[[CONSTANT_5]], %[[CONSTANT_3]] : index, index)
+! PostOpt: ^bb14(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index):
+! PostOpt: %[[CMPI_5:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[CONSTANT_5]] : index
+! PostOpt: cf.cond_br %[[CMPI_5]], ^bb15, ^bb16
+! PostOpt: ^bb15:
+! PostOpt: %[[ADDI_6:.*]] = arith.addi %[[VAL_10]], %[[CONSTANT_4]] : index
+! PostOpt: %[[ARRAY_COOR_4:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_6]], %[[ADDI_5]] : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[ARRAY_COOR_5:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) %[[ADDI_6]], %[[ADDI_5]] : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, index, index) -> !fir.ref<i32>
+! PostOpt: %[[LOAD_3:.*]] = fir.load %[[ARRAY_COOR_4]] : !fir.ref<i32>
+! PostOpt: fir.store %[[LOAD_3]] to %[[ARRAY_COOR_5]] : !fir.ref<i32>
+! PostOpt: %[[SUBI_4:.*]] = arith.subi %[[VAL_11]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb14(%[[ADDI_6]], %[[SUBI_4]] : index, index)
+! PostOpt: ^bb16:
+! PostOpt: %[[SUBI_5:.*]] = arith.subi %[[VAL_9]], %[[CONSTANT_4]] : index
+! PostOpt: cf.br ^bb12(%[[ADDI_5]], %[[SUBI_5]] : index, index)
+! PostOpt: ^bb17:
+! PostOpt: fir.freemem %[[ALLOCMEM_0]] : !fir.heap<!fir.array<10x?xi32>>
+! PostOpt: return
+! PostOpt: }
diff --git a/flang/test/Lower/array-temp.f90 b/flang/test/Lower/array-temp.f90
index 6a67fb55be2a9..4da40f1eeb9d7 100644
--- a/flang/test/Lower/array-temp.f90
+++ b/flang/test/Lower/array-temp.f90
@@ -135,257 +135,269 @@ subroutine ss4(N)
! CHECK: return
! CHECK: }
-! CHECK-LABEL: func @_QPss3(
-! CHECK-SAME: %arg0: !fir.ref<i32> {fir.bindc_name = "n"}) {
-! CHECK-DAG: %[[C_m1:[-0-9a-z_]+]] = arith.constant -1 : index
-! CHECK-DAG: %[[C_2:[-0-9a-z_]+]] = arith.constant 2 : index
-! CHECK-DAG: %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
-! CHECK-DAG: %[[C_34_i32:[-0-9a-z_]+]] = arith.constant 34 : i32
-! CHECK-DAG: %[[C_6_i32:[-0-9a-z_]+]] = arith.constant 6 : i32
-! CHECK-DAG: %[[C_st:[-0-9a-z_]+]] = arith.constant 7.000000e+00 : f32
-! CHECK-DAG: %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
-! CHECK-DAG: %[[C_st_0:[-0-9a-z_]+]] = arith.constant -2.000000e+00 : f32
-! CHECK-DAG: %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
-! CHECK: %[[V_0:[0-9]+]] = fir.load %arg0 : !fir.ref<i32>
-! CHECK: %[[V_1:[0-9]+]] = fir.convert %[[V_0:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_2:[0-9]+]] = arith.cmpi sgt, %[[V_1]], %[[C_0]] : index
-! CHECK: %[[V_3:[0-9]+]] = arith.select %[[V_2]], %[[V_1]], %[[C_0]] : index
-! CHECK: %[[V_4:[0-9]+]] = fir.alloca !fir.array<2x?xf32>, %[[V_3]] {bindc_name = "aa", uniq_name = "_QFss3Eaa"}
-! CHECK: %[[V_5:[0-9]+]] = fir.shape %[[C_2]], %[[V_3:[0-9]+]] : (index, index) -> !fir.shape<2>
-! CHECK: cf.br ^bb1(%[[C_0]], %[[V_3:[0-9]+]] : index, index)
-! CHECK: ^bb1(%[[V_6:[0-9]+]]: index, %[[V_7:[0-9]+]]: index): // 2 preds: ^bb0, ^bb4
-! CHECK: %[[V_8:[0-9]+]] = arith.cmpi sgt, %[[V_7]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_8]], ^bb2(%[[C_0]], %[[C_2]] : index, index), ^bb5
-! CHECK: ^bb2(%[[V_9:[0-9]+]]: index, %[[V_10:[0-9]+]]: index): // 2 preds: ^bb1, ^bb3
-! CHECK: %[[V_11:[0-9]+]] = arith.cmpi sgt, %[[V_10]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_11]], ^bb3, ^bb4
-! CHECK: ^bb3: // pred: ^bb2
-! CHECK: %[[V_12:[0-9]+]] = arith.addi %[[V_9]], %[[C_1]] : index
-! CHECK: %[[V_13:[0-9]+]] = arith.addi %[[V_6]], %[[C_1]] : index
-! CHECK: %[[V_14:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) %[[V_12]], %[[V_13:[0-9]+]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[C_st_0]] to %[[V_14:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_15:[0-9]+]] = arith.subi %[[V_10]], %[[C_1]] : index
-! CHECK: cf.br ^bb2(%[[V_12]], %[[V_15:[0-9]+]] : index, index)
-! CHECK: ^bb4: // pred: ^bb2
-! CHECK: %[[V_16:[0-9]+]] = arith.addi %[[V_6]], %[[C_1]] : index
-! CHECK: %[[V_17:[0-9]+]] = arith.subi %[[V_7]], %[[C_1]] : index
-! CHECK: cf.br ^bb1(%[[V_16]], %[[V_17:[0-9]+]] : index, index)
-! CHECK: ^bb5: // pred: ^bb1
-! CHECK: %[[V_18:[0-9]+]] = fir.load %arg0 : !fir.ref<i32>
-! CHECK: %[[V_19:[0-9]+]] = fir.convert %[[V_18:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_20:[0-9]+]] = arith.addi %[[V_19]], %[[C_m1]] : index
-! CHECK: %[[V_21:[0-9]+]] = arith.cmpi sgt, %[[V_20]], %[[C_0]] : index
-! CHECK: %[[V_22:[0-9]+]] = arith.select %[[V_21]], %[[V_20]], %[[C_0]] : index
-! CHECK: %[[V_23:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[C_2]], %[[V_19]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: %[[V_24:[0-9]+]] = fir.allocmem !fir.array<2x?xf32>, %[[V_3]]
-! CHECK: cf.br ^bb6(%[[C_0]], %[[V_3:[0-9]+]] : index, index)
-! CHECK: ^bb6(%[[V_25:[0-9]+]]: index, %[[V_26:[0-9]+]]: index): // 2 preds: ^bb5, ^bb9
-! CHECK: %[[V_27:[0-9]+]] = arith.cmpi sgt, %[[V_26]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_27]], ^bb7(%[[C_0]], %[[C_2]] : index, index), ^bb10
-! CHECK: ^bb7(%[[V_28:[0-9]+]]: index, %[[V_29:[0-9]+]]: index): // 2 preds: ^bb6, ^bb8
-! CHECK: %[[V_30:[0-9]+]] = arith.cmpi sgt, %[[V_29]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_30]], ^bb8, ^bb9
-! CHECK: ^bb8: // pred: ^bb7
-! CHECK: %[[V_31:[0-9]+]] = arith.addi %[[V_28]], %[[C_1]] : index
-! CHECK: %[[V_32:[0-9]+]] = arith.addi %[[V_25]], %[[C_1]] : index
-! CHECK: %[[V_33:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) %[[V_31]], %[[V_32:[0-9]+]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_34:[0-9]+]] = fir.array_coor %[[V_24]](%[[V_5]]) %[[V_31]], %[[V_32:[0-9]+]] : (!fir.heap<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_35:[0-9]+]] = fir.load %[[V_33:[0-9]+]] : !fir.ref<f32>
-! CHECK: fir.store %[[V_35]] to %[[V_34:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_36:[0-9]+]] = arith.subi %[[V_29]], %[[C_1]] : index
-! CHECK: cf.br ^bb7(%[[V_31]], %[[V_36:[0-9]+]] : index, index)
-! CHECK: ^bb9: // pred: ^bb7
-! CHECK: %[[V_37:[0-9]+]] = arith.addi %[[V_25]], %[[C_1]] : index
-! CHECK: %[[V_38:[0-9]+]] = arith.subi %[[V_26]], %[[C_1]] : index
-! CHECK: cf.br ^bb6(%[[V_37]], %[[V_38:[0-9]+]] : index, index)
-! CHECK: ^bb10: // pred: ^bb6
-! CHECK: %[[V_39:[0-9]+]] = arith.subi %[[V_18]], %[[C_1_i32]] : i32
-! CHECK: %[[V_40:[0-9]+]] = fir.convert %[[V_39:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_41:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[C_1]], %[[V_40]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: cf.br ^bb11(%[[C_0]], %[[V_22:[0-9]+]] : index, index)
-! CHECK: ^bb11(%[[V_42:[0-9]+]]: index, %[[V_43:[0-9]+]]: index): // 2 preds: ^bb10, ^bb14
-! CHECK: %[[V_44:[0-9]+]] = arith.cmpi sgt, %[[V_43]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_44]], ^bb12(%[[C_0]], %[[C_2]] : index, index), ^bb15(%[[C_0]], %[[V_3:[0-9]+]] : index, index)
-! CHECK: ^bb12(%[[V_45:[0-9]+]]: index, %[[V_46:[0-9]+]]: index): // 2 preds: ^bb11, ^bb13
-! CHECK: %[[V_47:[0-9]+]] = arith.cmpi sgt, %[[V_46]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_47]], ^bb13, ^bb14
-! CHECK: ^bb13: // pred: ^bb12
-! CHECK: %[[V_48:[0-9]+]] = arith.addi %[[V_45]], %[[C_1]] : index
-! CHECK: %[[V_49:[0-9]+]] = arith.addi %[[V_42]], %[[C_1]] : index
-! CHECK: %[[V_50:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) [%[[V_41]]] %[[V_48]], %[[V_49:[0-9]+]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_51:[0-9]+]] = fir.load %[[V_50:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_52:[0-9]+]] = arith.addf %[[V_51]], %[[C_st]] fastmath<contract> : f32
-! CHECK: %[[V_53:[0-9]+]] = fir.array_coor %[[V_24]](%[[V_5]]) [%[[V_23]]] %[[V_48]], %[[V_49:[0-9]+]] : (!fir.heap<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[V_52]] to %[[V_53:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_54:[0-9]+]] = arith.subi %[[V_46]], %[[C_1]] : index
-! CHECK: cf.br ^bb12(%[[V_48]], %[[V_54:[0-9]+]] : index, index)
-! CHECK: ^bb14: // pred: ^bb12
-! CHECK: %[[V_55:[0-9]+]] = arith.addi %[[V_42]], %[[C_1]] : index
-! CHECK: %[[V_56:[0-9]+]] = arith.subi %[[V_43]], %[[C_1]] : index
-! CHECK: cf.br ^bb11(%[[V_55]], %[[V_56:[0-9]+]] : index, index)
-! CHECK: ^bb15(%[[V_57:[0-9]+]]: index, %[[V_58:[0-9]+]]: index): // 2 preds: ^bb11, ^bb18
-! CHECK: %[[V_59:[0-9]+]] = arith.cmpi sgt, %[[V_58]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_59]], ^bb16(%[[C_0]], %[[C_2]] : index, index), ^bb19
-! CHECK: ^bb16(%[[V_60:[0-9]+]]: index, %[[V_61:[0-9]+]]: index): // 2 preds: ^bb15, ^bb17
-! CHECK: %[[V_62:[0-9]+]] = arith.cmpi sgt, %[[V_61]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_62]], ^bb17, ^bb18
-! CHECK: ^bb17: // pred: ^bb16
-! CHECK: %[[V_63:[0-9]+]] = arith.addi %[[V_60]], %[[C_1]] : index
-! CHECK: %[[V_64:[0-9]+]] = arith.addi %[[V_57]], %[[C_1]] : index
-! CHECK: %[[V_65:[0-9]+]] = fir.array_coor %[[V_24]](%[[V_5]]) %[[V_63]], %[[V_64:[0-9]+]] : (!fir.heap<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_66:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) %[[V_63]], %[[V_64:[0-9]+]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_67:[0-9]+]] = fir.load %[[V_65:[0-9]+]] : !fir.ref<f32>
-! CHECK: fir.store %[[V_67]] to %[[V_66:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_68:[0-9]+]] = arith.subi %[[V_61]], %[[C_1]] : index
-! CHECK: cf.br ^bb16(%[[V_63]], %[[V_68:[0-9]+]] : index, index)
-! CHECK: ^bb18: // pred: ^bb16
-! CHECK: %[[V_69:[0-9]+]] = arith.addi %[[V_57]], %[[C_1]] : index
-! CHECK: %[[V_70:[0-9]+]] = arith.subi %[[V_58]], %[[C_1]] : index
-! CHECK: cf.br ^bb15(%[[V_69]], %[[V_70:[0-9]+]] : index, index)
-! CHECK: ^bb19: // pred: ^bb15
-! CHECK: fir.freemem %[[V_24:[0-9]+]] : !fir.heap<!fir.array<2x?xf32>>
-! CHECK: %[[V_73:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput(%[[C_6_i32]], %{{.*}}, %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK: %[[V_74:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: %[[V_75:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_74]]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x2xf32>>
-! CHECK: %[[V_76:[0-9]+]] = fir.convert %[[V_75:[0-9]+]] : (!fir.box<!fir.array<?x2xf32>>) -> !fir.box<none>
-! CHECK: %[[V_77:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_76]]) fastmath<contract> {{.*}}: (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: %[[V_78:[0-9]+]] = fir.load %arg0 : !fir.ref<i32>
-! CHECK: %[[V_79:[0-9]+]] = arith.subi %[[V_78]], %[[C_1_i32]] : i32
-! CHECK: %[[V_80:[0-9]+]] = fir.convert %[[V_79:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_81:[0-9]+]] = fir.convert %[[V_78:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_82:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[V_80]], %[[V_81]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: %[[V_83:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_82]]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?xf32>>
-! CHECK: %[[V_84:[0-9]+]] = fir.convert %[[V_83:[0-9]+]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-! CHECK: %[[V_85:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_84]]) fastmath<contract> {{.*}}: (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: %[[V_86:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_73]]) fastmath<contract> {{.*}}: (!fir.ref<i8>) -> i32
-! CHECK: return
-! CHECK: }
+! CHECK-LABEL: func.func @_QPss3(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant {{.*}} : i32
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 6 : i32
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 7.000000e+00 : f32
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : i32
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant -2.000000e+00 : f32
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 2 : index
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[CONVERT_0]], %[[CONSTANT_7]] : index
+! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[CONVERT_0]], %[[CONSTANT_7]] : index
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<2x?xf32>, %[[SELECT_0]] {bindc_name = "aa", uniq_name = "_QFss3Eaa"}
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_8]], %[[SELECT_0]] : (index, index) -> !fir.shape<2>
+! CHECK: cf.br ^bb1(%[[CONSTANT_7]], %[[SELECT_0]] : index, index)
+! CHECK: ^bb1(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index):
+! CHECK: %[[CMPI_1:.*]] = arith.cmpi sgt, %[[VAL_1]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_1]], ^bb2, ^bb6
+! CHECK: ^bb2:
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_0]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb3(%[[CONSTANT_7]], %[[CONSTANT_8]] : index, index)
+! CHECK: ^bb3(%[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index):
+! CHECK: %[[CMPI_2:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_2]], ^bb4, ^bb5
+! CHECK: ^bb4:
+! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[CONSTANT_5]] : index
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) %[[ADDI_1]], %[[ADDI_0]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: fir.store %[[CONSTANT_6]] to %[[ARRAY_COOR_0]] : !fir.ref<f32>
+! CHECK: %[[SUBI_0:.*]] = arith.subi %[[VAL_3]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb3(%[[ADDI_1]], %[[SUBI_0]] : index, index)
+! CHECK: ^bb5:
+! CHECK: %[[SUBI_1:.*]] = arith.subi %[[VAL_1]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb1(%[[ADDI_0]], %[[SUBI_1]] : index, index)
+! CHECK: ^bb6:
+! CHECK: %[[LOAD_1:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_1]] : (i32) -> index
+! CHECK: %[[ADDI_2:.*]] = arith.addi %[[CONVERT_1]], %[[CONSTANT_0]] : index
+! CHECK: %[[CMPI_3:.*]] = arith.cmpi sgt, %[[ADDI_2]], %[[CONSTANT_7]] : index
+! CHECK: %[[SELECT_1:.*]] = arith.select %[[CMPI_3]], %[[ADDI_2]], %[[CONSTANT_7]] : index
+! CHECK: %[[SLICE_0:.*]] = fir.slice %[[CONSTANT_5]], %[[CONSTANT_8]], %[[CONSTANT_5]], %[[CONSTANT_8]], %[[CONVERT_1]], %[[CONSTANT_5]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<2x?xf32>, %[[SELECT_0]]
+! CHECK: cf.br ^bb7(%[[CONSTANT_7]], %[[SELECT_0]] : index, index)
+! CHECK: ^bb7(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: index):
+! CHECK: %[[CMPI_4:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_4]], ^bb8, ^bb12
+! CHECK: ^bb8:
+! CHECK: %[[ADDI_3:.*]] = arith.addi %[[VAL_4]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb9(%[[CONSTANT_7]], %[[CONSTANT_8]] : index, index)
+! CHECK: ^bb9(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):
+! CHECK: %[[CMPI_5:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_5]], ^bb10, ^bb11
+! CHECK: ^bb10:
+! CHECK: %[[ADDI_4:.*]] = arith.addi %[[VAL_6]], %[[CONSTANT_5]] : index
+! CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) %[[ADDI_4]], %[[ADDI_3]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[ARRAY_COOR_2:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_4]], %[[ADDI_3]] : (!fir.heap<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_1]] : !fir.ref<f32>
+! CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_2]] : !fir.ref<f32>
+! CHECK: %[[SUBI_2:.*]] = arith.subi %[[VAL_7]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb9(%[[ADDI_4]], %[[SUBI_2]] : index, index)
+! CHECK: ^bb11:
+! CHECK: %[[SUBI_3:.*]] = arith.subi %[[VAL_5]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb7(%[[ADDI_3]], %[[SUBI_3]] : index, index)
+! CHECK: ^bb12:
+! CHECK: %[[SUBI_4:.*]] = arith.subi %[[LOAD_1]], %[[CONSTANT_4]] : i32
+! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[SUBI_4]] : (i32) -> index
+! CHECK: %[[SLICE_1:.*]] = fir.slice %[[CONSTANT_5]], %[[CONSTANT_8]], %[[CONSTANT_5]], %[[CONSTANT_5]], %[[CONVERT_2]], %[[CONSTANT_5]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: cf.br ^bb13(%[[CONSTANT_7]], %[[SELECT_1]] : index, index)
+! CHECK: ^bb13(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index):
+! CHECK: %[[CMPI_6:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_6]], ^bb14, ^bb18(%[[CONSTANT_7]], %[[SELECT_0]] : index, index)
+! CHECK: ^bb14:
+! CHECK: %[[ADDI_5:.*]] = arith.addi %[[VAL_8]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb15(%[[CONSTANT_7]], %[[CONSTANT_8]] : index, index)
+! CHECK: ^bb15(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index):
+! CHECK: %[[CMPI_7:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_7]], ^bb16, ^bb17
+! CHECK: ^bb16:
+! CHECK: %[[ADDI_6:.*]] = arith.addi %[[VAL_10]], %[[CONSTANT_5]] : index
+! CHECK: %[[ARRAY_COOR_3:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_1]]] %[[ADDI_6]], %[[ADDI_5]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_3:.*]] = fir.load %[[ARRAY_COOR_3]] : !fir.ref<f32>
+! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_3]], %[[CONSTANT_3]] fastmath<contract> : f32
+! CHECK: %[[ARRAY_COOR_4:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_0]]] %[[ADDI_6]], %[[ADDI_5]] : (!fir.heap<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+! CHECK: fir.store %[[ADDF_0]] to %[[ARRAY_COOR_4]] : !fir.ref<f32>
+! CHECK: %[[SUBI_5:.*]] = arith.subi %[[VAL_11]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb15(%[[ADDI_6]], %[[SUBI_5]] : index, index)
+! CHECK: ^bb17:
+! CHECK: %[[SUBI_6:.*]] = arith.subi %[[VAL_9]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb13(%[[ADDI_5]], %[[SUBI_6]] : index, index)
+! CHECK: ^bb18(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index):
+! CHECK: %[[CMPI_8:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_8]], ^bb19, ^bb23
+! CHECK: ^bb19:
+! CHECK: %[[ADDI_7:.*]] = arith.addi %[[VAL_12]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb20(%[[CONSTANT_7]], %[[CONSTANT_8]] : index, index)
+! CHECK: ^bb20(%[[VAL_14:.*]]: index, %[[VAL_15:.*]]: index):
+! CHECK: %[[CMPI_9:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[CONSTANT_7]] : index
+! CHECK: cf.cond_br %[[CMPI_9]], ^bb21, ^bb22
+! CHECK: ^bb21:
+! CHECK: %[[ADDI_8:.*]] = arith.addi %[[VAL_14]], %[[CONSTANT_5]] : index
+! CHECK: %[[ARRAY_COOR_5:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_8]], %[[ADDI_7]] : (!fir.heap<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[ARRAY_COOR_6:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) %[[ADDI_8]], %[[ADDI_7]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_4:.*]] = fir.load %[[ARRAY_COOR_5]] : !fir.ref<f32>
+! CHECK: fir.store %[[LOAD_4]] to %[[ARRAY_COOR_6]] : !fir.ref<f32>
+! CHECK: %[[SUBI_7:.*]] = arith.subi %[[VAL_15]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb20(%[[ADDI_8]], %[[SUBI_7]] : index, index)
+! CHECK: ^bb22:
+! CHECK: %[[SUBI_8:.*]] = arith.subi %[[VAL_13]], %[[CONSTANT_5]] : index
+! CHECK: cf.br ^bb18(%[[ADDI_7]], %[[SUBI_8]] : index, index)
+! CHECK: ^bb23:
+! CHECK: fir.freemem %[[ALLOCMEM_0]] : !fir.heap<!fir.array<2x?xf32>>
+! CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+! CHECK: %[[CONVERT_3:.*]] = fir.convert %[[ADDRESS_OF_0]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+! CHECK: %[[CALL_0:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[CONSTANT_2]], %[[CONVERT_3]], %[[CONSTANT_1]]) fastmath<contract> {fir.llvm_memory = #llvm.memory_effects<other = none, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>, llvm.nocallback, llvm.nosync} : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK: %[[SLICE_2:.*]] = fir.slice %[[CONSTANT_5]], %[[CONSTANT_8]], %[[CONSTANT_5]], %[[CONSTANT_5]], %[[CONSTANT_8]], %[[CONSTANT_5]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCA_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_2]]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x2xf32>>
+! CHECK: %[[CONVERT_4:.*]] = fir.convert %[[EMBOX_0]] : (!fir.box<!fir.array<?x2xf32>>) -> !fir.box<none>
+! CHECK: %[[CALL_1:.*]] = fir.call @_FortranAioOutputDescriptor(%[[CALL_0]], %[[CONVERT_4]]) fastmath<contract> {llvm.nocallback, llvm.nosync} : (!fir.ref<i8>, !fir.box<none>) -> i1
+! CHECK: %[[LOAD_5:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
+! CHECK: %[[SUBI_9:.*]] = arith.subi %[[LOAD_5]], %[[CONSTANT_4]] : i32
+! CHECK: %[[CONVERT_5:.*]] = fir.convert %[[SUBI_9]] : (i32) -> index
+! CHECK: %[[CONVERT_6:.*]] = fir.convert %[[LOAD_5]] : (i32) -> index
+! CHECK: %[[SLICE_3:.*]] = fir.slice %[[CONSTANT_5]], %[[CONSTANT_8]], %[[CONSTANT_5]], %[[CONVERT_5]], %[[CONVERT_6]], %[[CONSTANT_5]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCA_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_3]]] : (!fir.ref<!fir.array<2x?xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[CONVERT_7:.*]] = fir.convert %[[EMBOX_1]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+! CHECK: %[[CALL_2:.*]] = fir.call @_FortranAioOutputDescriptor(%[[CALL_0]], %[[CONVERT_7]]) fastmath<contract> {llvm.nocallback, llvm.nosync} : (!fir.ref<i8>, !fir.box<none>) -> i1
+! CHECK: %[[CALL_3:.*]] = fir.call @_FortranAioEndIoStatement(%[[CALL_0]]) fastmath<contract> {fir.llvm_memory = #llvm.memory_effects<other = none, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>, llvm.nocallback, llvm.nosync} : (!fir.ref<i8>) -> i32
+! CHECK: return
+! CHECK: }
-! CHECK-LABEL: func @_QPss4(
-! CHECK-SAME: %arg0: !fir.ref<i32> {fir.bindc_name = "n"}) {
-! CHECK-DAG: %[[C_2:[-0-9a-z_]+]] = arith.constant 2 : index
-! CHECK-DAG: %[[C_m1:[-0-9a-z_]+]] = arith.constant -1 : index
-! CHECK-DAG: %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
-! CHECK-DAG: %[[C_41_i32:[-0-9a-z_]+]] = arith.constant 41 : i32
-! CHECK-DAG: %[[C_6_i32:[-0-9a-z_]+]] = arith.constant 6 : i32
-! CHECK-DAG: %[[C_st:[-0-9a-z_]+]] = arith.constant 7.000000e+00 : f32
-! CHECK-DAG: %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
-! CHECK-DAG: %[[C_st_0:[-0-9a-z_]+]] = arith.constant -2.000000e+00 : f32
-! CHECK-DAG: %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
-! CHECK: %[[V_0:[0-9]+]] = fir.load %arg0 : !fir.ref<i32>
-! CHECK: %[[V_1:[0-9]+]] = fir.convert %[[V_0:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_2:[0-9]+]] = arith.cmpi sgt, %[[V_1]], %[[C_0]] : index
-! CHECK: %[[V_3:[0-9]+]] = arith.select %[[V_2]], %[[V_1]], %[[C_0]] : index
-! CHECK: %[[V_4:[0-9]+]] = fir.alloca !fir.array<?x2xf32>, %[[V_3]] {bindc_name = "aa", uniq_name = "_QFss4Eaa"}
-! CHECK: %[[V_5:[0-9]+]] = fir.shape %[[V_3]], %[[C_2]] : (index, index) -> !fir.shape<2>
-! CHECK: cf.br ^bb1(%[[C_0]], %[[C_2]] : index, index)
-! CHECK: ^bb1(%[[V_6:[0-9]+]]: index, %[[V_7:[0-9]+]]: index): // 2 preds: ^bb0, ^bb4
-! CHECK: %[[V_8:[0-9]+]] = arith.cmpi sgt, %[[V_7]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_8]], ^bb2(%[[C_0]], %[[V_3:[0-9]+]] : index, index), ^bb5
-! CHECK: ^bb2(%[[V_9:[0-9]+]]: index, %[[V_10:[0-9]+]]: index): // 2 preds: ^bb1, ^bb3
-! CHECK: %[[V_11:[0-9]+]] = arith.cmpi sgt, %[[V_10]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_11]], ^bb3, ^bb4
-! CHECK: ^bb3: // pred: ^bb2
-! CHECK: %[[V_12:[0-9]+]] = arith.addi %[[V_9]], %[[C_1]] : index
-! CHECK: %[[V_13:[0-9]+]] = arith.addi %[[V_6]], %[[C_1]] : index
-! CHECK: %[[V_14:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) %[[V_12]], %[[V_13:[0-9]+]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[C_st_0]] to %[[V_14:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_15:[0-9]+]] = arith.subi %[[V_10]], %[[C_1]] : index
-! CHECK: cf.br ^bb2(%[[V_12]], %[[V_15:[0-9]+]] : index, index)
-! CHECK: ^bb4: // pred: ^bb2
-! CHECK: %[[V_16:[0-9]+]] = arith.addi %[[V_6]], %[[C_1]] : index
-! CHECK: %[[V_17:[0-9]+]] = arith.subi %[[V_7]], %[[C_1]] : index
-! CHECK: cf.br ^bb1(%[[V_16]], %[[V_17:[0-9]+]] : index, index)
-! CHECK: ^bb5: // pred: ^bb1
-! CHECK: %[[V_18:[0-9]+]] = fir.load %arg0 : !fir.ref<i32>
-! CHECK: %[[V_19:[0-9]+]] = fir.convert %[[V_18:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_20:[0-9]+]] = arith.addi %[[V_19]], %[[C_m1]] : index
-! CHECK: %[[V_21:[0-9]+]] = arith.cmpi sgt, %[[V_20]], %[[C_0]] : index
-! CHECK: %[[V_22:[0-9]+]] = arith.select %[[V_21]], %[[V_20]], %[[C_0]] : index
-! CHECK: %[[V_23:[0-9]+]] = fir.slice %[[C_2]], %[[V_19]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: %[[V_24:[0-9]+]] = fir.allocmem !fir.array<?x2xf32>, %[[V_3]]
-! CHECK: cf.br ^bb6(%[[C_0]], %[[C_2]] : index, index)
-! CHECK: ^bb6(%[[V_25:[0-9]+]]: index, %[[V_26:[0-9]+]]: index): // 2 preds: ^bb5, ^bb9
-! CHECK: %[[V_27:[0-9]+]] = arith.cmpi sgt, %[[V_26]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_27]], ^bb7(%[[C_0]], %[[V_3:[0-9]+]] : index, index), ^bb10
-! CHECK: ^bb7(%[[V_28:[0-9]+]]: index, %[[V_29:[0-9]+]]: index): // 2 preds: ^bb6, ^bb8
-! CHECK: %[[V_30:[0-9]+]] = arith.cmpi sgt, %[[V_29]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_30]], ^bb8, ^bb9
-! CHECK: ^bb8: // pred: ^bb7
-! CHECK: %[[V_31:[0-9]+]] = arith.addi %[[V_28]], %[[C_1]] : index
-! CHECK: %[[V_32:[0-9]+]] = arith.addi %[[V_25]], %[[C_1]] : index
-! CHECK: %[[V_33:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) %[[V_31]], %[[V_32:[0-9]+]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_34:[0-9]+]] = fir.array_coor %[[V_24]](%[[V_5]]) %[[V_31]], %[[V_32:[0-9]+]] : (!fir.heap<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_35:[0-9]+]] = fir.load %[[V_33:[0-9]+]] : !fir.ref<f32>
-! CHECK: fir.store %[[V_35]] to %[[V_34:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_36:[0-9]+]] = arith.subi %[[V_29]], %[[C_1]] : index
-! CHECK: cf.br ^bb7(%[[V_31]], %[[V_36:[0-9]+]] : index, index)
-! CHECK: ^bb9: // pred: ^bb7
-! CHECK: %[[V_37:[0-9]+]] = arith.addi %[[V_25]], %[[C_1]] : index
-! CHECK: %[[V_38:[0-9]+]] = arith.subi %[[V_26]], %[[C_1]] : index
-! CHECK: cf.br ^bb6(%[[V_37]], %[[V_38:[0-9]+]] : index, index)
-! CHECK: ^bb10: // pred: ^bb6
-! CHECK: %[[V_39:[0-9]+]] = arith.subi %[[V_18]], %[[C_1_i32]] : i32
-! CHECK: %[[V_40:[0-9]+]] = fir.convert %[[V_39:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_41:[0-9]+]] = fir.slice %[[C_1]], %[[V_40]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: cf.br ^bb11(%[[C_0]], %[[C_2]] : index, index)
-! CHECK: ^bb11(%[[V_42:[0-9]+]]: index, %[[V_43:[0-9]+]]: index): // 2 preds: ^bb10, ^bb14
-! CHECK: %[[V_44:[0-9]+]] = arith.cmpi sgt, %[[V_43]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_44]], ^bb12(%[[C_0]], %[[V_22:[0-9]+]] : index, index), ^bb15(%[[C_0]], %[[C_2]] : index, index)
-! CHECK: ^bb12(%[[V_45:[0-9]+]]: index, %[[V_46:[0-9]+]]: index): // 2 preds: ^bb11, ^bb13
-! CHECK: %[[V_47:[0-9]+]] = arith.cmpi sgt, %[[V_46]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_47]], ^bb13, ^bb14
-! CHECK: ^bb13: // pred: ^bb12
-! CHECK: %[[V_48:[0-9]+]] = arith.addi %[[V_45]], %[[C_1]] : index
-! CHECK: %[[V_49:[0-9]+]] = arith.addi %[[V_42]], %[[C_1]] : index
-! CHECK: %[[V_50:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) [%[[V_41]]] %[[V_48]], %[[V_49:[0-9]+]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_51:[0-9]+]] = fir.load %[[V_50:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_52:[0-9]+]] = arith.addf %[[V_51]], %[[C_st]] fastmath<contract> : f32
-! CHECK: %[[V_53:[0-9]+]] = fir.array_coor %[[V_24]](%[[V_5]]) [%[[V_23]]] %[[V_48]], %[[V_49:[0-9]+]] : (!fir.heap<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[V_52]] to %[[V_53:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_54:[0-9]+]] = arith.subi %[[V_46]], %[[C_1]] : index
-! CHECK: cf.br ^bb12(%[[V_48]], %[[V_54:[0-9]+]] : index, index)
-! CHECK: ^bb14: // pred: ^bb12
-! CHECK: %[[V_55:[0-9]+]] = arith.addi %[[V_42]], %[[C_1]] : index
-! CHECK: %[[V_56:[0-9]+]] = arith.subi %[[V_43]], %[[C_1]] : index
-! CHECK: cf.br ^bb11(%[[V_55]], %[[V_56:[0-9]+]] : index, index)
-! CHECK: ^bb15(%[[V_57:[0-9]+]]: index, %[[V_58:[0-9]+]]: index): // 2 preds: ^bb11, ^bb18
-! CHECK: %[[V_59:[0-9]+]] = arith.cmpi sgt, %[[V_58]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_59]], ^bb16(%[[C_0]], %[[V_3:[0-9]+]] : index, index), ^bb19
-! CHECK: ^bb16(%[[V_60:[0-9]+]]: index, %[[V_61:[0-9]+]]: index): // 2 preds: ^bb15, ^bb17
-! CHECK: %[[V_62:[0-9]+]] = arith.cmpi sgt, %[[V_61]], %[[C_0]] : index
-! CHECK: cf.cond_br %[[V_62]], ^bb17, ^bb18
-! CHECK: ^bb17: // pred: ^bb16
-! CHECK: %[[V_63:[0-9]+]] = arith.addi %[[V_60]], %[[C_1]] : index
-! CHECK: %[[V_64:[0-9]+]] = arith.addi %[[V_57]], %[[C_1]] : index
-! CHECK: %[[V_65:[0-9]+]] = fir.array_coor %[[V_24]](%[[V_5]]) %[[V_63]], %[[V_64:[0-9]+]] : (!fir.heap<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_66:[0-9]+]] = fir.array_coor %[[V_4]](%[[V_5]]) %[[V_63]], %[[V_64:[0-9]+]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
-! CHECK: %[[V_67:[0-9]+]] = fir.load %[[V_65:[0-9]+]] : !fir.ref<f32>
-! CHECK: fir.store %[[V_67]] to %[[V_66:[0-9]+]] : !fir.ref<f32>
-! CHECK: %[[V_68:[0-9]+]] = arith.subi %[[V_61]], %[[C_1]] : index
-! CHECK: cf.br ^bb16(%[[V_63]], %[[V_68:[0-9]+]] : index, index)
-! CHECK: ^bb18: // pred: ^bb16
-! CHECK: %[[V_69:[0-9]+]] = arith.addi %[[V_57]], %[[C_1]] : index
-! CHECK: %[[V_70:[0-9]+]] = arith.subi %[[V_58]], %[[C_1]] : index
-! CHECK: cf.br ^bb15(%[[V_69]], %[[V_70:[0-9]+]] : index, index)
-! CHECK: ^bb19: // pred: ^bb15
-! CHECK: fir.freemem %[[V_24:[0-9]+]] : !fir.heap<!fir.array<?x2xf32>>
-! CHECK: %[[V_73:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput(%[[C_6_i32]], %{{.*}}, %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK: %[[V_74:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: %[[V_75:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_74]]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<2x?xf32>>
-! CHECK: %[[V_76:[0-9]+]] = fir.convert %[[V_75:[0-9]+]] : (!fir.box<!fir.array<2x?xf32>>) -> !fir.box<none>
-! CHECK: %[[V_77:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_76]]) fastmath<contract> {{.*}}: (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: %[[V_78:[0-9]+]] = fir.load %arg0 : !fir.ref<i32>
-! CHECK: %[[V_79:[0-9]+]] = arith.subi %[[V_78]], %[[C_1_i32]] : i32
-! CHECK: %[[V_80:[0-9]+]] = fir.convert %[[V_79:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_81:[0-9]+]] = fir.convert %[[V_78:[0-9]+]] : (i32) -> index
-! CHECK: %[[V_82:[0-9]+]] = fir.slice %[[V_80]], %[[V_81]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK: %[[V_83:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_82]]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?xf32>>
-! CHECK: %[[V_84:[0-9]+]] = fir.convert %[[V_83:[0-9]+]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-! CHECK: %[[V_85:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_84]]) fastmath<contract> {{.*}}: (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: %[[V_86:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_73]]) fastmath<contract> {{.*}}: (!fir.ref<i8>) -> i32
-! CHECK: return
-! CHECK: }
+! CHECK-LABEL: func.func @_QPss4(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 2 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant {{.*}} : i32
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 6 : i32
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 7.000000e+00 : f32
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : i32
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant -2.000000e+00 : f32
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[CONVERT_0]], %[[CONSTANT_8]] : index
+! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[CONVERT_0]], %[[CONSTANT_8]] : index
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<?x2xf32>, %[[SELECT_0]] {bindc_name = "aa", uniq_name = "_QFss4Eaa"}
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]], %[[CONSTANT_1]] : (index, index) -> !fir.shape<2>
+! CHECK: cf.br ^bb1(%[[CONSTANT_8]], %[[CONSTANT_1]] : index, index)
+! CHECK: ^bb1(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index):
+! CHECK: %[[CMPI_1:.*]] = arith.cmpi sgt, %[[VAL_1]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_1]], ^bb2, ^bb6
+! CHECK: ^bb2:
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_0]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb3(%[[CONSTANT_8]], %[[SELECT_0]] : index, index)
+! CHECK: ^bb3(%[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index):
+! CHECK: %[[CMPI_2:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_2]], ^bb4, ^bb5
+! CHECK: ^bb4:
+! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[CONSTANT_6]] : index
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) %[[ADDI_1]], %[[ADDI_0]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: fir.store %[[CONSTANT_7]] to %[[ARRAY_COOR_0]] : !fir.ref<f32>
+! CHECK: %[[SUBI_0:.*]] = arith.subi %[[VAL_3]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb3(%[[ADDI_1]], %[[SUBI_0]] : index, index)
+! CHECK: ^bb5:
+! CHECK: %[[SUBI_1:.*]] = arith.subi %[[VAL_1]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb1(%[[ADDI_0]], %[[SUBI_1]] : index, index)
+! CHECK: ^bb6:
+! CHECK: %[[LOAD_1:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_1]] : (i32) -> index
+! CHECK: %[[ADDI_2:.*]] = arith.addi %[[CONVERT_1]], %[[CONSTANT_0]] : index
+! CHECK: %[[CMPI_3:.*]] = arith.cmpi sgt, %[[ADDI_2]], %[[CONSTANT_8]] : index
+! CHECK: %[[SELECT_1:.*]] = arith.select %[[CMPI_3]], %[[ADDI_2]], %[[CONSTANT_8]] : index
+! CHECK: %[[SLICE_0:.*]] = fir.slice %[[CONSTANT_1]], %[[CONVERT_1]], %[[CONSTANT_6]], %[[CONSTANT_6]], %[[CONSTANT_1]], %[[CONSTANT_6]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?x2xf32>, %[[SELECT_0]]
+! CHECK: cf.br ^bb7(%[[CONSTANT_8]], %[[CONSTANT_1]] : index, index)
+! CHECK: ^bb7(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: index):
+! CHECK: %[[CMPI_4:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_4]], ^bb8, ^bb12
+! CHECK: ^bb8:
+! CHECK: %[[ADDI_3:.*]] = arith.addi %[[VAL_4]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb9(%[[CONSTANT_8]], %[[SELECT_0]] : index, index)
+! CHECK: ^bb9(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):
+! CHECK: %[[CMPI_5:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_5]], ^bb10, ^bb11
+! CHECK: ^bb10:
+! CHECK: %[[ADDI_4:.*]] = arith.addi %[[VAL_6]], %[[CONSTANT_6]] : index
+! CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) %[[ADDI_4]], %[[ADDI_3]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[ARRAY_COOR_2:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_4]], %[[ADDI_3]] : (!fir.heap<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_1]] : !fir.ref<f32>
+! CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_2]] : !fir.ref<f32>
+! CHECK: %[[SUBI_2:.*]] = arith.subi %[[VAL_7]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb9(%[[ADDI_4]], %[[SUBI_2]] : index, index)
+! CHECK: ^bb11:
+! CHECK: %[[SUBI_3:.*]] = arith.subi %[[VAL_5]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb7(%[[ADDI_3]], %[[SUBI_3]] : index, index)
+! CHECK: ^bb12:
+! CHECK: %[[SUBI_4:.*]] = arith.subi %[[LOAD_1]], %[[CONSTANT_5]] : i32
+! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[SUBI_4]] : (i32) -> index
+! CHECK: %[[SLICE_1:.*]] = fir.slice %[[CONSTANT_6]], %[[CONVERT_2]], %[[CONSTANT_6]], %[[CONSTANT_6]], %[[CONSTANT_1]], %[[CONSTANT_6]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: cf.br ^bb13(%[[CONSTANT_8]], %[[CONSTANT_1]] : index, index)
+! CHECK: ^bb13(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index):
+! CHECK: %[[CMPI_6:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_6]], ^bb14, ^bb18(%[[CONSTANT_8]], %[[CONSTANT_1]] : index, index)
+! CHECK: ^bb14:
+! CHECK: %[[ADDI_5:.*]] = arith.addi %[[VAL_8]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb15(%[[CONSTANT_8]], %[[SELECT_1]] : index, index)
+! CHECK: ^bb15(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index):
+! CHECK: %[[CMPI_7:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_7]], ^bb16, ^bb17
+! CHECK: ^bb16:
+! CHECK: %[[ADDI_6:.*]] = arith.addi %[[VAL_10]], %[[CONSTANT_6]] : index
+! CHECK: %[[ARRAY_COOR_3:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_1]]] %[[ADDI_6]], %[[ADDI_5]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_3:.*]] = fir.load %[[ARRAY_COOR_3]] : !fir.ref<f32>
+! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_3]], %[[CONSTANT_4]] fastmath<contract> : f32
+! CHECK: %[[ARRAY_COOR_4:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_0]]] %[[ADDI_6]], %[[ADDI_5]] : (!fir.heap<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+! CHECK: fir.store %[[ADDF_0]] to %[[ARRAY_COOR_4]] : !fir.ref<f32>
+! CHECK: %[[SUBI_5:.*]] = arith.subi %[[VAL_11]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb15(%[[ADDI_6]], %[[SUBI_5]] : index, index)
+! CHECK: ^bb17:
+! CHECK: %[[SUBI_6:.*]] = arith.subi %[[VAL_9]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb13(%[[ADDI_5]], %[[SUBI_6]] : index, index)
+! CHECK: ^bb18(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index):
+! CHECK: %[[CMPI_8:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_8]], ^bb19, ^bb23
+! CHECK: ^bb19:
+! CHECK: %[[ADDI_7:.*]] = arith.addi %[[VAL_12]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb20(%[[CONSTANT_8]], %[[SELECT_0]] : index, index)
+! CHECK: ^bb20(%[[VAL_14:.*]]: index, %[[VAL_15:.*]]: index):
+! CHECK: %[[CMPI_9:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[CONSTANT_8]] : index
+! CHECK: cf.cond_br %[[CMPI_9]], ^bb21, ^bb22
+! CHECK: ^bb21:
+! CHECK: %[[ADDI_8:.*]] = arith.addi %[[VAL_14]], %[[CONSTANT_6]] : index
+! CHECK: %[[ARRAY_COOR_5:.*]] = fir.array_coor %[[ALLOCMEM_0]](%[[SHAPE_0]]) %[[ADDI_8]], %[[ADDI_7]] : (!fir.heap<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[ARRAY_COOR_6:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_0]]) %[[ADDI_8]], %[[ADDI_7]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_4:.*]] = fir.load %[[ARRAY_COOR_5]] : !fir.ref<f32>
+! CHECK: fir.store %[[LOAD_4]] to %[[ARRAY_COOR_6]] : !fir.ref<f32>
+! CHECK: %[[SUBI_7:.*]] = arith.subi %[[VAL_15]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb20(%[[ADDI_8]], %[[SUBI_7]] : index, index)
+! CHECK: ^bb22:
+! CHECK: %[[SUBI_8:.*]] = arith.subi %[[VAL_13]], %[[CONSTANT_6]] : index
+! CHECK: cf.br ^bb18(%[[ADDI_7]], %[[SUBI_8]] : index, index)
+! CHECK: ^bb23:
+! CHECK: fir.freemem %[[ALLOCMEM_0]] : !fir.heap<!fir.array<?x2xf32>>
+! CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+! CHECK: %[[CONVERT_3:.*]] = fir.convert %[[ADDRESS_OF_0]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+! CHECK: %[[CALL_0:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[CONSTANT_3]], %[[CONVERT_3]], %[[CONSTANT_2]]) fastmath<contract> {fir.llvm_memory = #llvm.memory_effects<other = none, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>, llvm.nocallback, llvm.nosync} : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK: %[[SLICE_2:.*]] = fir.slice %[[CONSTANT_6]], %[[CONSTANT_1]], %[[CONSTANT_6]], %[[CONSTANT_6]], %[[CONSTANT_1]], %[[CONSTANT_6]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCA_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_2]]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<2x?xf32>>
+! CHECK: %[[CONVERT_4:.*]] = fir.convert %[[EMBOX_0]] : (!fir.box<!fir.array<2x?xf32>>) -> !fir.box<none>
+! CHECK: %[[CALL_1:.*]] = fir.call @_FortranAioOutputDescriptor(%[[CALL_0]], %[[CONVERT_4]]) fastmath<contract> {llvm.nocallback, llvm.nosync} : (!fir.ref<i8>, !fir.box<none>) -> i1
+! CHECK: %[[LOAD_5:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
+! CHECK: %[[SUBI_9:.*]] = arith.subi %[[LOAD_5]], %[[CONSTANT_5]] : i32
+! CHECK: %[[CONVERT_5:.*]] = fir.convert %[[SUBI_9]] : (i32) -> index
+! CHECK: %[[CONVERT_6:.*]] = fir.convert %[[LOAD_5]] : (i32) -> index
+! CHECK: %[[SLICE_3:.*]] = fir.slice %[[CONVERT_5]], %[[CONVERT_6]], %[[CONSTANT_6]], %[[CONSTANT_6]], %[[CONSTANT_1]], %[[CONSTANT_6]] : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCA_0]](%[[SHAPE_0]]) {{\[}}%[[SLICE_3]]] : (!fir.ref<!fir.array<?x2xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[CONVERT_7:.*]] = fir.convert %[[EMBOX_1]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+! CHECK: %[[CALL_2:.*]] = fir.call @_FortranAioOutputDescriptor(%[[CALL_0]], %[[CONVERT_7]]) fastmath<contract> {llvm.nocallback, llvm.nosync} : (!fir.ref<i8>, !fir.box<none>) -> i1
+! CHECK: %[[CALL_3:.*]] = fir.call @_FortranAioEndIoStatement(%[[CALL_0]]) fastmath<contract> {fir.llvm_memory = #llvm.memory_effects<other = none, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>, llvm.nocallback, llvm.nosync} : (!fir.ref<i8>) -> i32
+! CHECK: return
+! CHECK: }
! CHECK-LABEL: func @_QPtt1
subroutine tt1
diff --git a/flang/test/Lower/vector-subscript-io.f90 b/flang/test/Lower/vector-subscript-io.f90
index 0f64e99e03a20..e47314d8ef63b 100644
--- a/flang/test/Lower/vector-subscript-io.f90
+++ b/flang/test/Lower/vector-subscript-io.f90
@@ -313,6 +313,11 @@ subroutine substring(x, y, i, j)
! CHECK: %[[VAL_217:.*]] = fir.load %[[VAL_218]] : !fir.ref<i32>
! CHECK: %[[VAL_219:.*]] = fir.convert %[[VAL_217]] : (i32) -> index
! CHECK: %[[VAL_220:.*]] = fir.slice %[[VAL_210]], %[[VAL_208]], %[[VAL_210]] : (index, index, index) -> !fir.slice<1>
+! CHECK: %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index
+! CHECK: %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index
+! CHECK: %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index
+! CHECK: %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index
+! CHECK: %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index
! CHECK: cf.br ^bb1(%[[VAL_209]], %[[VAL_208]] : index, index)
! CHECK: ^bb1(%[[VAL_221:.*]]: index, %[[VAL_222:.*]]: index):
! CHECK: %[[VAL_223:.*]] = arith.cmpi sgt, %[[VAL_222]], %[[VAL_209]] : index
@@ -322,13 +327,8 @@ subroutine substring(x, y, i, j)
! CHECK: %[[VAL_226:.*]] = fir.load %[[VAL_224]] : !fir.ref<i32>
! CHECK: %[[VAL_227:.*]] = fir.convert %[[VAL_226]] : (i32) -> index
! CHECK: %[[VAL_228:.*]] = fir.array_coor %[[VAL_229]] {{\[}}%[[VAL_220]]] %[[VAL_227]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.slice<1>, index) -> !fir.ref<!fir.char<1,?>>
-! CHECK: %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index
! CHECK: %[[VAL_231:.*]] = fir.convert %[[VAL_228]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
! CHECK: %[[VAL_232:.*]] = fir.coordinate_of %[[VAL_231]], %[[VAL_230]] : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
-! CHECK: %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index
-! CHECK: %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index
-! CHECK: %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index
-! CHECK: %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index
! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_232]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64
! CHECK: %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
diff --git a/flang/test/Transforms/licm.fir b/flang/test/Transforms/licm.fir
new file mode 100644
index 0000000000000..e6fdced9db134
--- /dev/null
+++ b/flang/test/Transforms/licm.fir
@@ -0,0 +1,1326 @@
+// RUN: fir-opt -flang-licm --split-input-file %s | FileCheck %s
+
+// Tests checking that Flang's LICM works correctly:
+// * Descriptor loads may be hoisted unless they can be modified inside
+// the loop (e.g. global descriptors may be modifed by calls).
+// * Reads of scalar non-optional variables may be hoisted unless
+// they are ALLOCATABLE or POINTER (which means they can be unallocated
+// or disassociated in loops that have zero iterations).
+// * TODO: any invariant loads may be hoisted in loops having non-zero
+// iterations.
+
+// subroutine test_dummy_scalar(r,x,n)
+// integer :: r(*), x, n
+// do i=1,n
+// r(i) = x
+// call external_sub
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_scalar(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalarEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_scalarEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_scalarEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_scalarEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_dummy_scalarEx"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<i32>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_1]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: fir.call @_QPexternal_sub() : () -> ()
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_scalar(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalarEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_scalarEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_scalarEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_scalarEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_dummy_scalarEx"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<i32>
+ %14 = fir.convert %13 : (i32) -> i64
+ %15 = fir.array_coor %6(%5) %14 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %12 to %15 : !fir.ref<i32>
+ fir.call @_QPexternal_sub() : () -> ()
+ %16 = fir.load %2 : !fir.ref<i32>
+ %17 = arith.addi %16, %10 overflow<nsw> : i32
+ fir.result %17 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_scalar_allocatable(r,x,n)
+// integer :: r(*), n
+// ! x may be unallocated:
+// integer, allocatable :: x
+// do i=1,n
+// r(i) = x
+// call external_sub
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_scalar_allocatable(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_allocatableEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_scalar_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_scalar_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_scalar_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_dummy_scalar_allocatableEx"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: fir.call @_QPexternal_sub() : () -> ()
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_scalar_allocatable(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_allocatableEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_scalar_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_scalar_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_scalar_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_dummy_scalar_allocatableEx"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %13 = fir.box_addr %12 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ %14 = fir.load %13 : !fir.heap<i32>
+ %15 = fir.load %2 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> i64
+ %17 = fir.array_coor %6(%5) %16 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %14 to %17 : !fir.ref<i32>
+ fir.call @_QPexternal_sub() : () -> ()
+ %18 = fir.load %2 : !fir.ref<i32>
+ %19 = arith.addi %18, %10 overflow<nsw> : i32
+ fir.result %19 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_scalar_pointer(r,x,n)
+// integer :: r(*), n
+// ! x may be disassociated:
+// integer, pointer :: x
+// do i=1,n
+// r(i) = x
+// call external_sub
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_scalar_pointer(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_pointerEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_scalar_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_scalar_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_scalar_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_dummy_scalar_pointerEx"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: fir.call @_QPexternal_sub() : () -> ()
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_scalar_pointer(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_pointerEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_scalar_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_scalar_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_scalar_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_dummy_scalar_pointerEx"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+ %13 = fir.box_addr %12 : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+ %14 = fir.load %13 : !fir.ptr<i32>
+ %15 = fir.load %2 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> i64
+ %17 = fir.array_coor %6(%5) %16 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %14 to %17 : !fir.ref<i32>
+ fir.call @_QPexternal_sub() : () -> ()
+ %18 = fir.load %2 : !fir.ref<i32>
+ %19 = arith.addi %18, %10 overflow<nsw> : i32
+ fir.result %19 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_scalar(r,n)
+// use data, only : glob_var
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_var
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_scalar(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_var) : !fir.ref<f32>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {uniq_name = "_QMdataEglob_var"} : (!fir.ref<f32>) -> !fir.ref<f32>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalarEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_scalarEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_scalarEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_scalarEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<f32>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_1]] : (f32) -> i32
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_scalar(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_var) : !fir.ref<f32>
+ %2 = fir.declare %1 {uniq_name = "_QMdataEglob_var"} : (!fir.ref<f32>) -> !fir.ref<f32>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalarEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_scalarEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_scalarEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_scalarEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<f32>
+ %14 = fir.convert %13 : (f32) -> i32
+ %15 = fir.load %4 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> i64
+ %17 = fir.array_coor %8(%7) %16 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %14 to %17 : !fir.ref<i32>
+ %18 = fir.load %4 : !fir.ref<i32>
+ %19 = arith.addi %18, %11 overflow<nsw> : i32
+ fir.result %19 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_scalar_allocatable(r,n)
+// use data, only : glob_alloc
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_alloc
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_scalar_allocatable(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_alloc) : !fir.ref<!fir.box<!fir.heap<f32>>>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMdataEglob_alloc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_allocatableEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_scalar_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_scalar_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_scalar_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.heap<f32>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (f32) -> i32
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_scalar_allocatable(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_alloc) : !fir.ref<!fir.box<!fir.heap<f32>>>
+ %2 = fir.declare %1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMdataEglob_alloc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_allocatableEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_scalar_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_scalar_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_scalar_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<!fir.box<!fir.heap<f32>>>
+ %14 = fir.box_addr %13 : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
+ %15 = fir.load %14 : !fir.heap<f32>
+ %16 = fir.convert %15 : (f32) -> i32
+ %17 = fir.load %4 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> i64
+ %19 = fir.array_coor %8(%7) %18 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %16 to %19 : !fir.ref<i32>
+ %20 = fir.load %4 : !fir.ref<i32>
+ %21 = arith.addi %20, %11 overflow<nsw> : i32
+ fir.result %21 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_scalar_pointer(r,n)
+// use data, only : glob_ptr
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_ptr
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_scalar_pointer(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_ptr) : !fir.ref<!fir.box<!fir.ptr<f32>>>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMdataEglob_ptr"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_pointerEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_scalar_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_scalar_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_scalar_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.ptr<f32>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (f32) -> i32
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_scalar_pointer(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_ptr) : !fir.ref<!fir.box<!fir.ptr<f32>>>
+ %2 = fir.declare %1 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMdataEglob_ptr"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_pointerEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_scalar_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_scalar_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_scalar_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<!fir.box<!fir.ptr<f32>>>
+ %14 = fir.box_addr %13 : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
+ %15 = fir.load %14 : !fir.ptr<f32>
+ %16 = fir.convert %15 : (f32) -> i32
+ %17 = fir.load %4 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> i64
+ %19 = fir.array_coor %8(%7) %18 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %16 to %19 : !fir.ref<i32>
+ %20 = fir.load %4 : !fir.ref<i32>
+ %21 = arith.addi %20, %11 overflow<nsw> : i32
+ fir.result %21 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_scalar_negative(r,n)
+// use data, only : glob_var
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_var
+// call external_sub
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_scalar_negative(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_var) : !fir.ref<f32>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {uniq_name = "_QMdataEglob_var"} : (!fir.ref<f32>) -> !fir.ref<f32>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_negativeEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_scalar_negativeEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_scalar_negativeEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_scalar_negativeEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_1]] : (f32) -> i32
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: fir.call @_QPexternal_sub() : () -> ()
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_scalar_negative(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_var) : !fir.ref<f32>
+ %2 = fir.declare %1 {uniq_name = "_QMdataEglob_var"} : (!fir.ref<f32>) -> !fir.ref<f32>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_negativeEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_scalar_negativeEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_scalar_negativeEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_scalar_negativeEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<f32>
+ %14 = fir.convert %13 : (f32) -> i32
+ %15 = fir.load %4 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> i64
+ %17 = fir.array_coor %8(%7) %16 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %14 to %17 : !fir.ref<i32>
+ fir.call @_QPexternal_sub() : () -> ()
+ %18 = fir.load %4 : !fir.ref<i32>
+ %19 = arith.addi %18, %11 overflow<nsw> : i32
+ fir.result %19 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_scalar_allocatable_negative(r,n)
+// use data, only : glob_alloc
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_alloc
+// call external_sub
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_scalar_allocatable_negative(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_alloc) : !fir.ref<!fir.box<!fir.heap<f32>>>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMdataEglob_alloc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_allocatable_negativeEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_scalar_allocatable_negativeEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_scalar_allocatable_negativeEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_scalar_allocatable_negativeEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.heap<f32>>>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (f32) -> i32
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: fir.call @_QPexternal_sub() : () -> ()
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_scalar_allocatable_negative(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_alloc) : !fir.ref<!fir.box<!fir.heap<f32>>>
+ %2 = fir.declare %1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMdataEglob_alloc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_allocatable_negativeEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_scalar_allocatable_negativeEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_scalar_allocatable_negativeEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_scalar_allocatable_negativeEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<!fir.box<!fir.heap<f32>>>
+ %14 = fir.box_addr %13 : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
+ %15 = fir.load %14 : !fir.heap<f32>
+ %16 = fir.convert %15 : (f32) -> i32
+ %17 = fir.load %4 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> i64
+ %19 = fir.array_coor %8(%7) %18 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %16 to %19 : !fir.ref<i32>
+ fir.call @_QPexternal_sub() : () -> ()
+ %20 = fir.load %4 : !fir.ref<i32>
+ %21 = arith.addi %20, %11 overflow<nsw> : i32
+ fir.result %21 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_scalar_pointer_negative(r,n)
+// use data, only : glob_ptr
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_ptr
+// call external_sub
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_scalar_pointer_negative(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_ptr) : !fir.ref<!fir.box<!fir.ptr<f32>>>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMdataEglob_ptr"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_pointer_negativeEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_scalar_pointer_negativeEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_scalar_pointer_negativeEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_scalar_pointer_negativeEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.ptr<f32>>>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (f32) -> i32
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: fir.call @_QPexternal_sub() : () -> ()
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_scalar_pointer_negative(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_ptr) : !fir.ref<!fir.box<!fir.ptr<f32>>>
+ %2 = fir.declare %1 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMdataEglob_ptr"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_scalar_pointer_negativeEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_scalar_pointer_negativeEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_scalar_pointer_negativeEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_scalar_pointer_negativeEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<!fir.box<!fir.ptr<f32>>>
+ %14 = fir.box_addr %13 : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
+ %15 = fir.load %14 : !fir.ptr<f32>
+ %16 = fir.convert %15 : (f32) -> i32
+ %17 = fir.load %4 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> i64
+ %19 = fir.array_coor %8(%7) %18 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %16 to %19 : !fir.ref<i32>
+ fir.call @_QPexternal_sub() : () -> ()
+ %20 = fir.load %4 : !fir.ref<i32>
+ %21 = arith.addi %20, %11 overflow<nsw> : i32
+ fir.result %21 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_array(r,x,n)
+// integer :: r(*), x(*), n
+// do i=1,n
+// r(i) = x(1)
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_array(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_arrayEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_arrayEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_arrayEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_arrayEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_dummy_arrayEx"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONSTANT_0]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_1]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_array(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_arrayEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_arrayEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_arrayEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_arrayEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1(%5) dummy_scope %0 arg 2 {uniq_name = "_QFtest_dummy_arrayEx"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.array_coor %7(%5) %c1 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
+ %13 = fir.load %12 : !fir.ref<i32>
+ %14 = fir.load %2 : !fir.ref<i32>
+ %15 = fir.convert %14 : (i32) -> i64
+ %16 = fir.array_coor %6(%5) %15 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %13 to %16 : !fir.ref<i32>
+ %17 = fir.load %2 : !fir.ref<i32>
+ %18 = arith.addi %17, %10 overflow<nsw> : i32
+ fir.result %18 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_array_allocatable(r,x,n)
+// integer :: r(*), n
+// integer, allocatable :: x(:)
+// do i=1,n
+// r(i) = x(1)
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_array_allocatable(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+// CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_array_allocatableEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_array_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_array_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_array_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_dummy_array_allocatableEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_1]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_1]] to %[[CONVERT_0]] step %[[CONSTANT_1]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+// CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_0]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+// CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_0]]#0, %[[BOX_DIMS_0]]#1 : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[BOX_ADDR_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_1]] : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_array_allocatable(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_array_allocatableEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_array_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_array_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_array_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_dummy_array_allocatableEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+ %13 = fir.box_addr %12 : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+ %14:3 = fir.box_dims %12, %c0 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+ %15 = fir.shape_shift %14#0, %14#1 : (index, index) -> !fir.shapeshift<1>
+ %16 = fir.array_coor %13(%15) %c1 : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ %17 = fir.load %16 : !fir.ref<i32>
+ %18 = fir.load %2 : !fir.ref<i32>
+ %19 = fir.convert %18 : (i32) -> i64
+ %20 = fir.array_coor %6(%5) %19 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %17 to %20 : !fir.ref<i32>
+ %21 = fir.load %2 : !fir.ref<i32>
+ %22 = arith.addi %21, %10 overflow<nsw> : i32
+ fir.result %22 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_array_pointer(r,x,n)
+// integer :: r(*), n
+// integer, pointer :: x(:)
+// do i=1,n
+// r(i) = x(1)
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_array_pointer(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+// CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_array_pointerEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_array_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_array_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_array_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_dummy_array_pointerEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_1]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_1]] to %[[CONVERT_0]] step %[[CONSTANT_1]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_0]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+// CHECK: %[[SHIFT_0:.*]] = fir.shift %[[BOX_DIMS_0]]#0 : (index) -> !fir.shift<1>
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[LOAD_1]](%[[SHIFT_0]]) %[[CONSTANT_1]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>, index) -> !fir.ref<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_array_pointer(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_array_pointerEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_array_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_array_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_array_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_dummy_array_pointerEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+ %13:3 = fir.box_dims %12, %c0 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+ %14 = fir.shift %13#0 : (index) -> !fir.shift<1>
+ %15 = fir.array_coor %12(%14) %c1 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>, index) -> !fir.ref<i32>
+ %16 = fir.load %15 : !fir.ref<i32>
+ %17 = fir.load %2 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> i64
+ %19 = fir.array_coor %6(%5) %18 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %16 to %19 : !fir.ref<i32>
+ %20 = fir.load %2 : !fir.ref<i32>
+ %21 = arith.addi %20, %10 overflow<nsw> : i32
+ fir.result %21 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_array(r,n)
+// use data, only : glob_arr_var
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_arr_var(1)
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_array(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_arr_var) : !fir.ref<!fir.array<10xf32>>
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]](%[[SHAPE_0]]) {uniq_name = "_QMdataEglob_arr_var"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_arrayEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_arrayEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_arrayEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_1:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_1]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_arrayEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_0]](%[[SHAPE_0]]) %[[CONSTANT_0]] : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_1]] : (f32) -> i32
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_1]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_array(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_arr_var) : !fir.ref<!fir.array<10xf32>>
+ %2 = fir.shape %c10 : (index) -> !fir.shape<1>
+ %3 = fir.declare %1(%2) {uniq_name = "_QMdataEglob_arr_var"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ %4 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_arrayEi"}
+ %5 = fir.declare %4 {uniq_name = "_QFtest_global_arrayEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %6 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_arrayEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %7 = fir.assumed_size_extent : index
+ %8 = fir.shape %7 : (index) -> !fir.shape<1>
+ %9 = fir.declare %arg0(%8) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_arrayEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %10 = fir.load %6 : !fir.ref<i32>
+ %11 = fir.convert %10 : (i32) -> index
+ %12 = fir.convert %c1 : (index) -> i32
+ %13 = fir.do_loop %arg2 = %c1 to %11 step %c1 iter_args(%arg3 = %12) -> (i32) {
+ fir.store %arg3 to %5 : !fir.ref<i32>
+ %14 = fir.array_coor %3(%2) %c1 : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>
+ %15 = fir.load %14 : !fir.ref<f32>
+ %16 = fir.convert %15 : (f32) -> i32
+ %17 = fir.load %5 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> i64
+ %19 = fir.array_coor %9(%8) %18 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %16 to %19 : !fir.ref<i32>
+ %20 = fir.load %5 : !fir.ref<i32>
+ %21 = arith.addi %20, %12 overflow<nsw> : i32
+ fir.result %21 : i32
+ }
+ fir.store %13 to %5 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_array_allocatable(r,n)
+// use data, only : glob_arr_alloc
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_arr_alloc(1)
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_array_allocatable(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+// CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_arr_alloc) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMdataEglob_arr_alloc"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_array_allocatableEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_array_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_array_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_array_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_1]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_1]] to %[[CONVERT_0]] step %[[CONSTANT_1]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+// CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_0]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+// CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_0]]#0, %[[BOX_DIMS_0]]#1 : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[BOX_ADDR_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_1]] : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>, index) -> !fir.ref<f32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (f32) -> i32
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_array_allocatable(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_arr_alloc) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %2 = fir.declare %1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMdataEglob_arr_alloc"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_array_allocatableEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_array_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_array_allocatableEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_array_allocatableEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %14 = fir.box_addr %13 : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+ %15:3 = fir.box_dims %13, %c0 : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+ %16 = fir.shape_shift %15#0, %15#1 : (index, index) -> !fir.shapeshift<1>
+ %17 = fir.array_coor %14(%16) %c1 : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>, index) -> !fir.ref<f32>
+ %18 = fir.load %17 : !fir.ref<f32>
+ %19 = fir.convert %18 : (f32) -> i32
+ %20 = fir.load %4 : !fir.ref<i32>
+ %21 = fir.convert %20 : (i32) -> i64
+ %22 = fir.array_coor %8(%7) %21 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %19 to %22 : !fir.ref<i32>
+ %23 = fir.load %4 : !fir.ref<i32>
+ %24 = arith.addi %23, %11 overflow<nsw> : i32
+ fir.result %24 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_global_array_pointer(r,n)
+// use data, only : glob_arr_ptr
+// integer :: r(*), n
+// do i=1,n
+// r(i) = glob_arr_ptr(1)
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_global_array_pointer(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+// CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMdataEglob_arr_ptr) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMdataEglob_arr_ptr"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_array_pointerEi"}
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_global_array_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {uniq_name = "_QFtest_global_array_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_global_array_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_2]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_1]] : (index) -> i32
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_1]] to %[[CONVERT_0]] step %[[CONSTANT_1]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_0]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+// CHECK: %[[SHIFT_0:.*]] = fir.shift %[[BOX_DIMS_0]]#0 : (index) -> !fir.shift<1>
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[LOAD_1]](%[[SHIFT_0]]) %[[CONSTANT_1]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>, index) -> !fir.ref<f32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[ARRAY_COOR_0]] : !fir.ref<f32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (f32) -> i32
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_1:.*]] = fir.array_coor %[[DECLARE_3]](%[[SHAPE_0]]) %[[CONVERT_3]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[CONVERT_2]] to %[[ARRAY_COOR_1]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_global_array_pointer(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMdataEglob_arr_ptr) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ %2 = fir.declare %1 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMdataEglob_arr_ptr"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ %3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_global_array_pointerEi"}
+ %4 = fir.declare %3 {uniq_name = "_QFtest_global_array_pointerEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_global_array_pointerEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.assumed_size_extent : index
+ %7 = fir.shape %6 : (index) -> !fir.shape<1>
+ %8 = fir.declare %arg0(%7) dummy_scope %0 arg 1 {uniq_name = "_QFtest_global_array_pointerEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %c1 : (index) -> i32
+ %12 = fir.do_loop %arg2 = %c1 to %10 step %c1 iter_args(%arg3 = %11) -> (i32) {
+ fir.store %arg3 to %4 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ %14:3 = fir.box_dims %13, %c0 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+ %15 = fir.shift %14#0 : (index) -> !fir.shift<1>
+ %16 = fir.array_coor %13(%15) %c1 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>, index) -> !fir.ref<f32>
+ %17 = fir.load %16 : !fir.ref<f32>
+ %18 = fir.convert %17 : (f32) -> i32
+ %19 = fir.load %4 : !fir.ref<i32>
+ %20 = fir.convert %19 : (i32) -> i64
+ %21 = fir.array_coor %8(%7) %20 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %18 to %21 : !fir.ref<i32>
+ %22 = fir.load %4 : !fir.ref<i32>
+ %23 = arith.addi %22, %11 overflow<nsw> : i32
+ fir.result %23 : i32
+ }
+ fir.store %12 to %4 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_scalar_optional(r,x,n)
+// integer :: r(*), n
+// integer, optional :: x
+// do i=1,n
+// r(i) = x
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_scalar_optional(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "x", fir.optional},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_optionalEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_scalar_optionalEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_scalar_optionalEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_scalar_optionalEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest_dummy_scalar_optionalEx"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_1]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_scalar_optional(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<i32> {fir.bindc_name = "x", fir.optional}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_optionalEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_scalar_optionalEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_scalar_optionalEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_scalar_optionalEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest_dummy_scalar_optionalEx"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<i32>
+ %13 = fir.load %2 : !fir.ref<i32>
+ %14 = fir.convert %13 : (i32) -> i64
+ %15 = fir.array_coor %6(%5) %14 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %12 to %15 : !fir.ref<i32>
+ %16 = fir.load %2 : !fir.ref<i32>
+ %17 = arith.addi %16, %10 overflow<nsw> : i32
+ fir.result %17 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_scalar_allocatable_optional(r,x,n)
+// integer :: r(*), n
+// integer, allocatable, optional :: x
+// do i=1,n
+// r(i) = x
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_scalar_allocatable_optional(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "x", fir.optional},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<allocatable, optional>, uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEx"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_scalar_allocatable_optional(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "x", fir.optional}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<allocatable, optional>, uniq_name = "_QFtest_dummy_scalar_allocatable_optionalEx"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %13 = fir.box_addr %12 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ %14 = fir.load %13 : !fir.heap<i32>
+ %15 = fir.load %2 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> i64
+ %17 = fir.array_coor %6(%5) %16 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %14 to %17 : !fir.ref<i32>
+ %18 = fir.load %2 : !fir.ref<i32>
+ %19 = arith.addi %18, %10 overflow<nsw> : i32
+ fir.result %19 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
+
+// -----
+// subroutine test_dummy_scalar_pointer_optional(r,x,n)
+// integer :: r(*), n
+// integer, pointer, optional :: x
+// do i=1,n
+// r(i) = x
+// end do
+// end subroutine
+// CHECK-LABEL: func.func @_QPtest_dummy_scalar_pointer_optional(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"},
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "x", fir.optional},
+// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_pointer_optionalEi"}
+// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtest_dummy_scalar_pointer_optionalEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ARG2]] dummy_scope %[[DUMMY_SCOPE_0]] arg 3 {uniq_name = "_QFtest_dummy_scalar_pointer_optionalEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[ASSUMED_SIZE_EXTENT_0:.*]] = fir.assumed_size_extent : index
+// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[ASSUMED_SIZE_EXTENT_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {uniq_name = "_QFtest_dummy_scalar_pointer_optionalEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ARG1]] dummy_scope %[[DUMMY_SCOPE_0]] arg 2 {fortran_attrs = #fir.var_attrs<optional, pointer>, uniq_name = "_QFtest_dummy_scalar_pointer_optionalEx"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+// CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
+// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[CONSTANT_0]] : (index) -> i32
+// CHECK: %[[DO_LOOP_0:.*]] = fir.do_loop %[[VAL_0:.*]] = %[[CONSTANT_0]] to %[[CONVERT_0]] step %[[CONSTANT_0]] iter_args(%[[VAL_1:.*]] = %[[CONVERT_1]]) -> (i32) {
+// CHECK: fir.store %[[VAL_1]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+// CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+// CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr<i32>
+// CHECK: %[[LOAD_3:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[LOAD_3]] : (i32) -> i64
+// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[DECLARE_2]](%[[SHAPE_0]]) %[[CONVERT_2]] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+// CHECK: fir.store %[[LOAD_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
+// CHECK: %[[LOAD_4:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_4]], %[[CONVERT_1]] overflow<nsw> : i32
+// CHECK: fir.result %[[ADDI_0]] : i32
+// CHECK: }
+// CHECK: fir.store %[[DO_LOOP_0]] to %[[DECLARE_0]] : !fir.ref<i32>
+// CHECK: return
+// CHECK: }
+func.func @_QPtest_dummy_scalar_pointer_optional(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "r"}, %arg1: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "x", fir.optional}, %arg2: !fir.ref<i32> {fir.bindc_name = "n"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_dummy_scalar_pointer_optionalEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFtest_dummy_scalar_pointer_optionalEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dummy_scalar_pointer_optionalEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %4 = fir.assumed_size_extent : index
+ %5 = fir.shape %4 : (index) -> !fir.shape<1>
+ %6 = fir.declare %arg0(%5) dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_scalar_pointer_optionalEr"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
+ %7 = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<optional, pointer>, uniq_name = "_QFtest_dummy_scalar_pointer_optionalEx"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+ %8 = fir.load %3 : !fir.ref<i32>
+ %9 = fir.convert %8 : (i32) -> index
+ %10 = fir.convert %c1 : (index) -> i32
+ %11 = fir.do_loop %arg3 = %c1 to %9 step %c1 iter_args(%arg4 = %10) -> (i32) {
+ fir.store %arg4 to %2 : !fir.ref<i32>
+ %12 = fir.load %7 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+ %13 = fir.box_addr %12 : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+ %14 = fir.load %13 : !fir.ptr<i32>
+ %15 = fir.load %2 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> i64
+ %17 = fir.array_coor %6(%5) %16 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
+ fir.store %14 to %17 : !fir.ref<i32>
+ %18 = fir.load %2 : !fir.ref<i32>
+ %19 = arith.addi %18, %10 overflow<nsw> : i32
+ fir.result %19 : i32
+ }
+ fir.store %11 to %2 : !fir.ref<i32>
+ return
+}
>From f94a10107bb0a0e7792b6c8ee1892f32c6d67a90 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 23 Dec 2025 17:12:30 -0800
Subject: [PATCH 3/3] clang-format
---
flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py b/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py
index 953f1a2545781..48c79ecc7f07b 100755
--- a/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py
+++ b/flang/test/Analysis/AliasAnalysis/gen_mod_ref_test.py
@@ -27,7 +27,7 @@
line,
)
line, count = re.subn(
- r'(fir.box_addr.*) :',
+ r"(fir.box_addr.*) :",
rf'\1 {{test.ptr ="box_addr_{box_addr_counter}"}} :',
line,
)
More information about the flang-commits
mailing list