[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 &region : 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 &region,
                                       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 &region : 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