[flang-commits] [flang] d8beb2c - [flang][NFC] Add forall lowering tests

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Tue Mar 22 13:35:22 PDT 2022


Author: Valentin Clement
Date: 2022-03-22T21:34:59+01:00
New Revision: d8beb2c33db8b2c4594a3714e0d034c2e830b9e4

URL: https://github.com/llvm/llvm-project/commit/d8beb2c33db8b2c4594a3714e0d034c2e830b9e4
DIFF: https://github.com/llvm/llvm-project/commit/d8beb2c33db8b2c4594a3714e0d034c2e830b9e4.diff

LOG: [flang][NFC] Add forall lowering tests

This patch adds some lowering tests for the `forall` construct.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D122253

Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    flang/test/Lower/forall/array-subscripts.f90
    flang/test/Lower/forall/character-1.f90
    flang/test/Lower/forall/forall-allocatable-2.f90
    flang/test/Lower/forall/forall-allocatable.f90
    flang/test/Lower/forall/forall-array.f90
    flang/test/Lower/forall/forall-construct-2.f90
    flang/test/Lower/forall/forall-construct-3.f90
    flang/test/Lower/forall/forall-ranked.f90
    flang/test/Lower/forall/forall-slice.f90
    flang/test/Lower/forall/forall-stmt.f90
    flang/test/Lower/forall/forall-where-2.f90
    flang/test/Lower/forall/forall-where.f90
    flang/test/Lower/forall/test9.f90

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/flang/test/Lower/forall/array-subscripts.f90 b/flang/test/Lower/forall/array-subscripts.f90
new file mode 100644
index 0000000000000..9fc721db4f60b
--- /dev/null
+++ b/flang/test/Lower/forall/array-subscripts.f90
@@ -0,0 +1,21 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+  ! Make sure we use array values for subscripts that are arrays on the lhs so
+  ! that copy-in/copy-out works correctly.
+  integer :: a(4,4)
+  forall(i=1:4,j=1:4)
+    a(a(i,j),a(j,i)) = j - i*100
+  end forall
+end
+
+! CHECK-LABEL: func @_QQmain
+! CHECK: %[[a:.*]] = fir.address_of(@_QFEa) : !fir.ref<!fir.array<4x4xi32>>
+! CHECK: %[[a1:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref<!fir.array<4x4xi32>>, !fir.shape<2>) -> !fir.array<4x4xi32>
+! CHECK: %[[a2:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref<!fir.array<4x4xi32>>, !fir.shape<2>) -> !fir.array<4x4xi32>
+! CHECK: %[[a3:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref<!fir.array<4x4xi32>>, !fir.shape<2>) -> !fir.array<4x4xi32>
+! CHECK: %[[av:.*]] = fir.do_loop
+! CHECK: fir.do_loop
+! CHECK: = fir.array_fetch %[[a2]], %{{.*}}, %{{.*}} : (!fir.array<4x4xi32>, index, index) -> i32
+! CHECK: = fir.array_fetch %[[a3]], %{{.*}}, %{{.*}} : (!fir.array<4x4xi32>, index, index) -> i32
+! CHECK: = fir.array_update %{{.*}}, %{{.*}}, %{{.*}} : (!fir.array<4x4xi32>, i32, index, index) -> !fir.array<4x4xi32>
+! CHECK : fir.array_merge_store %[[a1]], %[[av]] to %[[a]] : !fir.array<4x4xi32>, !fir.array<4x4xi32>, !fir.ref<!fir.array<4x4xi32>>

diff  --git a/flang/test/Lower/forall/character-1.f90 b/flang/test/Lower/forall/character-1.f90
new file mode 100644
index 0000000000000..a491e2feef93f
--- /dev/null
+++ b/flang/test/Lower/forall/character-1.f90
@@ -0,0 +1,31 @@
+! RUN: bbc %s -o - | tco | FileCheck %s
+! Test from Fortran source through to LLVM IR.
+! UNSUPPORTED: system-windows
+
+! Assumed size array of assumed length character.
+program test
+  character :: x(3) = (/ '1','2','3' /)
+  call sub(x)
+contains
+  subroutine sub(x)
+    character(*) x(:)
+    forall (i=1:2)
+       x(i:i)(1:1) = x(i+1:i+1)(1:1)
+    end forall
+    print *,x
+  end subroutine sub
+end program test
+
+! CHECK-LABEL: define void @_QFPsub({
+! CHECK-SAME: , [1 x [3 x i64]] }* %[[arg:.*]])
+! CHECK: %[[extent:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, { {{.*}}, [1 x [3 x i64]] }* %[[arg]], i32 0, i32 7, i64 0, i32 1
+! CHECK: %[[extval:.*]] = load i64, i64* %[[extent]]
+! CHECK: %[[elesize:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, { {{.*}}, [1 x [3 x i64]] }* %[[arg]], i32 0, i32 1
+! CHECK: %[[esval:.*]] = load i64, i64* %[[elesize]]
+! CHECK: %[[mul:.*]] = mul i64 1, %[[esval]]
+! CHECK: %[[mul2:.*]] = mul i64 %[[mul]], %[[extval]], !dbg !18
+! CHECK: %[[buff:.*]] = call i8* @malloc(i64 %[[mul2]])
+! CHECK: %[[to:.*]] = getelementptr i8, i8* %[[buff]], i64 %
+! CHECK: call void @llvm.memmove.p0i8.p0i8.i64(i8* %[[to]], i8* %{{.*}}, i64 %{{.*}}, i1 false)
+! CHECK: call void @free(i8* %[[buff]])
+! CHECK: call i8* @_FortranAioBeginExternalListOutput

diff  --git a/flang/test/Lower/forall/forall-allocatable-2.f90 b/flang/test/Lower/forall/forall-allocatable-2.f90
new file mode 100644
index 0000000000000..0c72102ca0118
--- /dev/null
+++ b/flang/test/Lower/forall/forall-allocatable-2.f90
@@ -0,0 +1,60 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+subroutine forall_with_allocatable2(a1)
+  real :: a1(:)
+  type t
+     integer :: i
+     real, allocatable :: arr(:)
+  end type t
+  type(t) :: thing
+  forall (i=5:15)
+     thing%arr(i) = a1(i)
+  end forall
+end subroutine forall_with_allocatable2
+
+! CHECK-LABEL: func @_QPforall_with_allocatable2(
+! CHECK-SAME:                                    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
+! CHECK:         %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_2:.*]] = fir.alloca !fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}> {bindc_name = "thing", uniq_name = "_QFforall_with_allocatable2Ething"}
+! CHECK:         %[[VAL_3:.*]] = fir.embox %[[VAL_2]] : (!fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+! CHECK:         %[[VAL_4:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,
+! CHECK:         %[[VAL_5:.*]] = arith.constant {{.*}} : i32
+! CHECK:         %[[VAL_6:.*]] = fir.convert %[[VAL_3]] : (!fir.box<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<none>
+! CHECK:         %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+! CHECK:         %[[VAL_8:.*]] = fir.call @_FortranAInitialize(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
+! CHECK:         %[[VAL_9:.*]] = arith.constant 5 : i32
+! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
+! CHECK:         %[[VAL_11:.*]] = arith.constant 15 : i32
+! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i32) -> index
+! CHECK:         %[[VAL_13:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_14:.*]] = fir.field_index arr, !fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
+! CHECK:         %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_14]] : (!fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:         %[[VAL_16:.*]] = fir.load %[[VAL_15]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:         %[[VAL_17:.*]] = arith.constant 0 : index
+! CHECK:         %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_16]], %[[VAL_17]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK:         %[[VAL_19:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+! CHECK:         %[[VAL_20:.*]] = fir.shape_shift %[[VAL_18]]#0, %[[VAL_18]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK:         %[[VAL_21:.*]] = fir.array_load %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_22:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_23:.*]] = fir.do_loop %[[VAL_24:.*]] = %[[VAL_10]] to %[[VAL_12]] step %[[VAL_13]] unordered iter_args(%[[VAL_25:.*]] = %[[VAL_21]]) -> (!fir.array<?xf32>) {
+! CHECK:           %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_26]] to %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_27:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_28:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64
+! CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
+! CHECK:           %[[VAL_31:.*]] = arith.subi %[[VAL_30]], %[[VAL_27]] : index
+! CHECK:           %[[VAL_32:.*]] = fir.array_fetch %[[VAL_22]], %[[VAL_31]] : (!fir.array<?xf32>, index) -> f32
+! CHECK:           %[[VAL_33:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_34:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i32) -> i64
+! CHECK:           %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i64) -> index
+! CHECK:           %[[VAL_37:.*]] = arith.subi %[[VAL_36]], %[[VAL_33]] : index
+! CHECK:           %[[VAL_38:.*]] = fir.array_update %[[VAL_25]], %[[VAL_32]], %[[VAL_37]] : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>
+! CHECK:           fir.result %[[VAL_38]] : !fir.array<?xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_21]], %[[VAL_39:.*]] to %[[VAL_19]] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.heap<!fir.array<?xf32>>
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/forall-allocatable.f90 b/flang/test/Lower/forall/forall-allocatable.f90
new file mode 100644
index 0000000000000..522d119aa72f1
--- /dev/null
+++ b/flang/test/Lower/forall/forall-allocatable.f90
@@ -0,0 +1,51 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+subroutine forall_with_allocatable(a1)
+  real :: a1(:)
+  real, allocatable :: arr(:)
+  forall (i=5:15)
+     arr(i) = a1(i)
+  end forall
+end subroutine forall_with_allocatable
+
+! CHECK-LABEL: func @_QPforall_with_allocatable(
+! CHECK-SAME:                                   %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
+! CHECK:         %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "arr", uniq_name = "_QFforall_with_allocatableEarr"}
+! CHECK:         %[[VAL_3:.*]] = fir.alloca !fir.heap<!fir.array<?xf32>> {uniq_name = "_QFforall_with_allocatableEarr.addr"}
+! CHECK:         %[[VAL_4:.*]] = fir.alloca index {uniq_name = "_QFforall_with_allocatableEarr.lb0"}
+! CHECK:         %[[VAL_5:.*]] = fir.alloca index {uniq_name = "_QFforall_with_allocatableEarr.ext0"}
+! CHECK:         %[[VAL_6:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+! CHECK:         fir.store %[[VAL_6]] to %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
+! CHECK:         %[[VAL_7:.*]] = arith.constant 5 : i32
+! CHECK:         %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index
+! CHECK:         %[[VAL_9:.*]] = arith.constant 15 : i32
+! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
+! CHECK:         %[[VAL_11:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_12:.*]] = fir.load %[[VAL_4]] : !fir.ref<index>
+! CHECK:         %[[VAL_13:.*]] = fir.load %[[VAL_5]] : !fir.ref<index>
+! CHECK:         %[[VAL_14:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
+! CHECK:         %[[VAL_15:.*]] = fir.shape_shift %[[VAL_12]], %[[VAL_13]] : (index, index) -> !fir.shapeshift<1>
+! CHECK:         %[[VAL_16:.*]] = fir.array_load %[[VAL_14]](%[[VAL_15]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_17:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_18:.*]] = fir.do_loop %[[VAL_19:.*]] = %[[VAL_8]] to %[[VAL_10]] step %[[VAL_11]] unordered iter_args(%[[VAL_20:.*]] = %[[VAL_16]]) -> (!fir.array<?xf32>) {
+! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_21]] to %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_22:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_23:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (i32) -> i64
+! CHECK:           %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i64) -> index
+! CHECK:           %[[VAL_26:.*]] = arith.subi %[[VAL_25]], %[[VAL_22]] : index
+! CHECK:           %[[VAL_27:.*]] = fir.array_fetch %[[VAL_17]], %[[VAL_26]] : (!fir.array<?xf32>, index) -> f32
+! CHECK:           %[[VAL_29:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i32) -> i64
+! CHECK:           %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i64) -> index
+! CHECK:           %[[VAL_32:.*]] = arith.subi %[[VAL_31]], %[[VAL_12]] : index
+! CHECK:           %[[VAL_33:.*]] = fir.array_update %[[VAL_20]], %[[VAL_27]], %[[VAL_32]] : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>
+! CHECK:           fir.result %[[VAL_33]] : !fir.array<?xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_16]], %[[VAL_34:.*]] to %[[VAL_14]] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.heap<!fir.array<?xf32>>
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/forall-array.f90 b/flang/test/Lower/forall/forall-array.f90
new file mode 100644
index 0000000000000..8c7daaae91eea
--- /dev/null
+++ b/flang/test/Lower/forall/forall-array.f90
@@ -0,0 +1,65 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+!*** Test a FORALL construct with an array assignment
+!    This is similar to the following embedded WHERE construct test, but the
+!    elements are assigned unconditionally.
+subroutine test_forall_with_array_assignment(aa,bb)
+  type t
+     integer(kind=8) :: block1(64)
+     integer(kind=8) :: block2(64)
+  end type t
+  type(t) :: aa(10), bb(10)
+
+  forall (i=1:10:2)
+     aa(i)%block1 = bb(i+1)%block2
+  end forall
+end subroutine test_forall_with_array_assignment
+
+! CHECK-LABEL: func @_QPtest_forall_with_array_assignment(
+! CHECK-SAME:     %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>>{{.*}}) {
+! CHECK:         %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_3:.*]] = arith.constant 10 : index
+! CHECK:         %[[VAL_4:.*]] = arith.constant 10 : index
+! CHECK:         %[[VAL_5:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index
+! CHECK:         %[[VAL_7:.*]] = arith.constant 10 : i32
+! CHECK:         %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index
+! CHECK:         %[[VAL_9:.*]] = arith.constant 2 : i32
+! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
+! CHECK:         %[[VAL_11:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_12:.*]] = fir.array_load %[[VAL_0]](%[[VAL_11]]) : (!fir.ref<!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>>, !fir.shape<1>) -> !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>
+! CHECK:         %[[VAL_13:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_14:.*]] = fir.array_load %[[VAL_1]](%[[VAL_13]]) : (!fir.ref<!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>>, !fir.shape<1>) -> !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>
+! CHECK:         %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_6]] to %[[VAL_8]] step %[[VAL_10]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_12]]) -> (!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>) {
+! CHECK:           %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_18]] to %[[VAL_2]] : !fir.ref<i32>
+! CHECK:           %[[VAL_19:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_20:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i32) -> i64
+! CHECK:           %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i64) -> index
+! CHECK:           %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_19]] : index
+! CHECK:           %[[VAL_24:.*]] = fir.field_index block1, !fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>
+! CHECK:           %[[VAL_26:.*]] = arith.constant 64 : index
+! CHECK:           %[[VAL_27:.*]] = arith.constant 1 : index
+! CHECK-DAG:       %[[VAL_28:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK-DAG:       %[[VAL_29:.*]] = arith.constant 1 : i32
+! CHECK:           %[[VAL_30:.*]] = arith.addi %[[VAL_28]], %[[VAL_29]] : i32
+! CHECK:           %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i32) -> i64
+! CHECK:           %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i64) -> index
+! CHECK:           %[[VAL_33:.*]] = arith.subi %[[VAL_32]], %[[VAL_27]] : index
+! CHECK:           %[[VAL_34:.*]] = fir.field_index block2, !fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>
+! CHECK:           %[[VAL_35:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_36:.*]] = arith.constant 0 : index
+! CHECK:           %[[VAL_37:.*]] = arith.subi %[[VAL_26]], %[[VAL_35]] : index
+! CHECK:           %[[VAL_38:.*]] = fir.do_loop %[[VAL_39:.*]] = %[[VAL_36]] to %[[VAL_37]] step %[[VAL_35]] unordered iter_args(%[[VAL_40:.*]] = %[[VAL_17]]) -> (!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>) {
+! CHECK:             %[[VAL_41:.*]] = fir.array_fetch %[[VAL_14]], %[[VAL_33]], %[[VAL_34]], %[[VAL_39]] : (!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>, index, !fir.field, index) -> i64
+! CHECK:             %[[VAL_42:.*]] = fir.array_update %[[VAL_40]], %[[VAL_41]], %[[VAL_23]], %[[VAL_24]], %[[VAL_39]] : (!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>, i64, index, !fir.field, index) -> !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>
+! CHECK:             fir.result %[[VAL_42]] : !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_43:.*]] : !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_12]], %[[VAL_44:.*]] to %[[VAL_0]] : !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>, !fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>, !fir.ref<!fir.array<10x!fir.type<_QFtest_forall_with_array_assignmentTt{block1:!fir.array<64xi64>,block2:!fir.array<64xi64>}>>>
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/forall-construct-2.f90 b/flang/test/Lower/forall/forall-construct-2.f90
new file mode 100644
index 0000000000000..dff0898375559
--- /dev/null
+++ b/flang/test/Lower/forall/forall-construct-2.f90
@@ -0,0 +1,124 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+!*** Test forall with multiple assignment statements
+subroutine test2_forall_construct(a,b)
+  real :: a(100,400), b(200,200)
+  forall (i=1:100, j=1:200)
+     a(i,j) = b(i,j) + b(i+1,j)
+     a(i,200+j) = 1.0 / b(j, i)
+  end forall
+end subroutine test2_forall_construct
+
+! CHECK-LABEL: func @_QPtest2_forall_construct(
+! CHECK-SAME:       %[[VAL_0:.*]]: !fir.ref<!fir.array<100x400xf32>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<200x200xf32>>{{.*}}) {
+! CHECK:         %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_4:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_5:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_6:.*]] = arith.constant 100 : index
+! CHECK:         %[[VAL_7:.*]] = arith.constant 400 : index
+! CHECK:         %[[VAL_8:.*]] = arith.constant 200 : index
+! CHECK:         %[[VAL_9:.*]] = arith.constant 200 : index
+! CHECK:         %[[VAL_10:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> index
+! CHECK:         %[[VAL_12:.*]] = arith.constant 100 : i32
+! CHECK:         %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i32) -> index
+! CHECK:         %[[VAL_14:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_15:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> index
+! CHECK:         %[[VAL_17:.*]] = arith.constant 200 : i32
+! CHECK:         %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index
+! CHECK:         %[[VAL_19:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_20:.*]] = fir.shape %[[VAL_6]], %[[VAL_7]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_21:.*]] = fir.array_load %[[VAL_0]](%[[VAL_20]]) : (!fir.ref<!fir.array<100x400xf32>>, !fir.shape<2>) -> !fir.array<100x400xf32>
+! CHECK:         %[[VAL_22:.*]] = fir.shape %[[VAL_8]], %[[VAL_9]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_23:.*]] = fir.array_load %[[VAL_1]](%[[VAL_22]]) : (!fir.ref<!fir.array<200x200xf32>>, !fir.shape<2>) -> !fir.array<200x200xf32>
+! CHECK:         %[[VAL_24:.*]] = fir.shape %[[VAL_8]], %[[VAL_9]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_25:.*]] = fir.array_load %[[VAL_1]](%[[VAL_24]]) : (!fir.ref<!fir.array<200x200xf32>>, !fir.shape<2>) -> !fir.array<200x200xf32>
+! CHECK:         %[[VAL_26:.*]] = fir.do_loop %[[VAL_27:.*]] = %[[VAL_11]] to %[[VAL_13]] step %[[VAL_14]] unordered iter_args(%[[VAL_28:.*]] = %[[VAL_21]]) -> (!fir.array<100x400xf32>) {
+! CHECK:           %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_29]] to %[[VAL_5]] : !fir.ref<i32>
+! CHECK:           %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_16]] to %[[VAL_18]] step %[[VAL_19]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_28]]) -> (!fir.array<100x400xf32>) {
+! CHECK:             %[[VAL_33:.*]] = fir.convert %[[VAL_31]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_33]] to %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_34:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_35:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:             %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> i64
+! CHECK:             %[[VAL_37:.*]] = fir.convert %[[VAL_36]] : (i64) -> index
+! CHECK:             %[[VAL_38:.*]] = arith.subi %[[VAL_37]], %[[VAL_34]] : index
+! CHECK:             %[[VAL_39:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (i32) -> i64
+! CHECK:             %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i64) -> index
+! CHECK:             %[[VAL_42:.*]] = arith.subi %[[VAL_41]], %[[VAL_34]] : index
+! CHECK:             %[[VAL_43:.*]] = arith.constant 1 : index
+! CHECK-DAG:         %[[VAL_44:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK-DAG:         %[[VAL_45:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_46:.*]] = arith.addi %[[VAL_44]], %[[VAL_45]] : i32
+! CHECK:             %[[VAL_47:.*]] = fir.convert %[[VAL_46]] : (i32) -> i64
+! CHECK:             %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (i64) -> index
+! CHECK:             %[[VAL_49:.*]] = arith.subi %[[VAL_48]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_50:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_51:.*]] = fir.convert %[[VAL_50]] : (i32) -> i64
+! CHECK:             %[[VAL_52:.*]] = fir.convert %[[VAL_51]] : (i64) -> index
+! CHECK:             %[[VAL_53:.*]] = arith.subi %[[VAL_52]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_54:.*]] = fir.array_fetch %[[VAL_23]], %[[VAL_38]], %[[VAL_42]] : (!fir.array<200x200xf32>, index, index) -> f32
+! CHECK:             %[[VAL_55:.*]] = fir.array_fetch %[[VAL_25]], %[[VAL_49]], %[[VAL_53]] : (!fir.array<200x200xf32>, index, index) -> f32
+! CHECK:             %[[VAL_56:.*]] = arith.addf %[[VAL_54]], %[[VAL_55]] : f32
+! CHECK:             %[[VAL_57:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_58:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:             %[[VAL_59:.*]] = fir.convert %[[VAL_58]] : (i32) -> i64
+! CHECK:             %[[VAL_60:.*]] = fir.convert %[[VAL_59]] : (i64) -> index
+! CHECK:             %[[VAL_61:.*]] = arith.subi %[[VAL_60]], %[[VAL_57]] : index
+! CHECK:             %[[VAL_62:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_63:.*]] = fir.convert %[[VAL_62]] : (i32) -> i64
+! CHECK:             %[[VAL_64:.*]] = fir.convert %[[VAL_63]] : (i64) -> index
+! CHECK:             %[[VAL_65:.*]] = arith.subi %[[VAL_64]], %[[VAL_57]] : index
+! CHECK:             %[[VAL_66:.*]] = fir.array_update %[[VAL_32]], %[[VAL_56]], %[[VAL_61]], %[[VAL_65]] : (!fir.array<100x400xf32>, f32, index, index) -> !fir.array<100x400xf32>
+! CHECK:             fir.result %[[VAL_66]] : !fir.array<100x400xf32>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_67:.*]] : !fir.array<100x400xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_21]], %[[VAL_68:.*]] to %[[VAL_0]] : !fir.array<100x400xf32>, !fir.array<100x400xf32>, !fir.ref<!fir.array<100x400xf32>>
+! CHECK:         %[[VAL_69:.*]] = fir.shape %[[VAL_6]], %[[VAL_7]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_70:.*]] = fir.array_load %[[VAL_0]](%[[VAL_69]]) : (!fir.ref<!fir.array<100x400xf32>>, !fir.shape<2>) -> !fir.array<100x400xf32>
+! CHECK:         %[[VAL_71:.*]] = fir.shape %[[VAL_8]], %[[VAL_9]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_72:.*]] = fir.array_load %[[VAL_1]](%[[VAL_71]]) : (!fir.ref<!fir.array<200x200xf32>>, !fir.shape<2>) -> !fir.array<200x200xf32>
+! CHECK:         %[[VAL_73:.*]] = fir.do_loop %[[VAL_74:.*]] = %[[VAL_11]] to %[[VAL_13]] step %[[VAL_14]] unordered iter_args(%[[VAL_75:.*]] = %[[VAL_70]]) -> (!fir.array<100x400xf32>) {
+! CHECK:           %[[VAL_76:.*]] = fir.convert %[[VAL_74]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_76]] to %[[VAL_3]] : !fir.ref<i32>
+! CHECK:           %[[VAL_77:.*]] = fir.do_loop %[[VAL_78:.*]] = %[[VAL_16]] to %[[VAL_18]] step %[[VAL_19]] unordered iter_args(%[[VAL_79:.*]] = %[[VAL_75]]) -> (!fir.array<100x400xf32>) {
+! CHECK:             %[[VAL_80:.*]] = fir.convert %[[VAL_78]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_80]] to %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_81:.*]] = arith.constant 1.000000e+00 : f32
+! CHECK:             %[[VAL_82:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_83:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_84:.*]] = fir.convert %[[VAL_83]] : (i32) -> i64
+! CHECK:             %[[VAL_85:.*]] = fir.convert %[[VAL_84]] : (i64) -> index
+! CHECK:             %[[VAL_86:.*]] = arith.subi %[[VAL_85]], %[[VAL_82]] : index
+! CHECK:             %[[VAL_87:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_88:.*]] = fir.convert %[[VAL_87]] : (i32) -> i64
+! CHECK:             %[[VAL_89:.*]] = fir.convert %[[VAL_88]] : (i64) -> index
+! CHECK:             %[[VAL_90:.*]] = arith.subi %[[VAL_89]], %[[VAL_82]] : index
+! CHECK:             %[[VAL_91:.*]] = fir.array_fetch %[[VAL_72]], %[[VAL_86]], %[[VAL_90]] : (!fir.array<200x200xf32>, index, index) -> f32
+! CHECK:             %[[VAL_92:.*]] = arith.divf %[[VAL_81]], %[[VAL_91]] : f32
+! CHECK:             %[[VAL_93:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_94:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_95:.*]] = fir.convert %[[VAL_94]] : (i32) -> i64
+! CHECK:             %[[VAL_96:.*]] = fir.convert %[[VAL_95]] : (i64) -> index
+! CHECK:             %[[VAL_97:.*]] = arith.subi %[[VAL_96]], %[[VAL_93]] : index
+! CHECK:             %[[VAL_98:.*]] = arith.constant 200 : i32
+! CHECK:             %[[VAL_99:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_100:.*]] = arith.addi %[[VAL_98]], %[[VAL_99]] : i32
+! CHECK:             %[[VAL_101:.*]] = fir.convert %[[VAL_100]] : (i32) -> i64
+! CHECK:             %[[VAL_102:.*]] = fir.convert %[[VAL_101]] : (i64) -> index
+! CHECK:             %[[VAL_103:.*]] = arith.subi %[[VAL_102]], %[[VAL_93]] : index
+! CHECK:             %[[VAL_104:.*]] = fir.array_update %[[VAL_79]], %[[VAL_92]], %[[VAL_97]], %[[VAL_103]] : (!fir.array<100x400xf32>, f32, index, index) -> !fir.array<100x400xf32>
+! CHECK:             fir.result %[[VAL_104]] : !fir.array<100x400xf32>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_105:.*]] : !fir.array<100x400xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_70]], %[[VAL_106:.*]] to %[[VAL_0]] : !fir.array<100x400xf32>, !fir.array<100x400xf32>, !fir.ref<!fir.array<100x400xf32>>
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/forall-construct-3.f90 b/flang/test/Lower/forall/forall-construct-3.f90
new file mode 100644
index 0000000000000..823b18872b778
--- /dev/null
+++ b/flang/test/Lower/forall/forall-construct-3.f90
@@ -0,0 +1,157 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+!*** Test forall with multiple assignment statements and mask
+subroutine test3_forall_construct(a,b, mask)
+  real :: a(100,400), b(200,200)
+  logical :: mask(100,200)
+  forall (i=1:100, j=1:200, mask(i,j))
+     a(i,j) = b(i,j) + b(i+1,j)
+     a(i,200+j) = 1.0 / b(j, i)
+  end forall
+end subroutine test3_forall_construct
+
+! CHECK-LABEL: func @_QPtest3_forall_construct(
+! CHECK-SAME:        %[[VAL_0:.*]]: !fir.ref<!fir.array<100x400xf32>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<200x200xf32>>{{.*}}, %[[VAL_2:.*]]: !fir.ref<!fir.array<100x200x!fir.logical<4>>>{{.*}}) {
+! CHECK:         %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_4:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_5:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_6:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_7:.*]] = arith.constant 100 : index
+! CHECK:         %[[VAL_8:.*]] = arith.constant 400 : index
+! CHECK:         %[[VAL_9:.*]] = arith.constant 200 : index
+! CHECK:         %[[VAL_10:.*]] = arith.constant 200 : index
+! CHECK:         %[[VAL_11:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i32) -> index
+! CHECK:         %[[VAL_13:.*]] = arith.constant 100 : i32
+! CHECK:         %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i32) -> index
+! CHECK:         %[[VAL_15:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_16:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i32) -> index
+! CHECK:         %[[VAL_18:.*]] = arith.constant 200 : i32
+! CHECK:         %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> index
+! CHECK:         %[[VAL_20:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_21:.*]] = fir.shape %[[VAL_7]], %[[VAL_8]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_22:.*]] = fir.array_load %[[VAL_0]](%[[VAL_21]]) : (!fir.ref<!fir.array<100x400xf32>>, !fir.shape<2>) -> !fir.array<100x400xf32>
+! CHECK:         %[[VAL_23:.*]] = fir.shape %[[VAL_9]], %[[VAL_10]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_24:.*]] = fir.array_load %[[VAL_1]](%[[VAL_23]]) : (!fir.ref<!fir.array<200x200xf32>>, !fir.shape<2>) -> !fir.array<200x200xf32>
+! CHECK:         %[[VAL_25:.*]] = fir.shape %[[VAL_9]], %[[VAL_10]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_26:.*]] = fir.array_load %[[VAL_1]](%[[VAL_25]]) : (!fir.ref<!fir.array<200x200xf32>>, !fir.shape<2>) -> !fir.array<200x200xf32>
+! CHECK:         %[[VAL_27:.*]] = fir.do_loop %[[VAL_28:.*]] = %[[VAL_12]] to %[[VAL_14]] step %[[VAL_15]] unordered iter_args(%[[VAL_29:.*]] = %[[VAL_22]]) -> (!fir.array<100x400xf32>) {
+! CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_30]] to %[[VAL_6]] : !fir.ref<i32>
+! CHECK:           %[[VAL_31:.*]] = fir.do_loop %[[VAL_32:.*]] = %[[VAL_17]] to %[[VAL_19]] step %[[VAL_20]] unordered iter_args(%[[VAL_33:.*]] = %[[VAL_29]]) -> (!fir.array<100x400xf32>) {
+! CHECK:             %[[VAL_34:.*]] = fir.convert %[[VAL_32]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_34]] to %[[VAL_5]] : !fir.ref<i32>
+! CHECK:             %[[VAL_35:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32>
+! CHECK:             %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> i64
+! CHECK:             %[[VAL_37:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_38:.*]] = arith.subi %[[VAL_36]], %[[VAL_37]] : i64
+! CHECK:             %[[VAL_39:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:             %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (i32) -> i64
+! CHECK:             %[[VAL_41:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_42:.*]] = arith.subi %[[VAL_40]], %[[VAL_41]] : i64
+! CHECK:             %[[VAL_43:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_38]], %[[VAL_42]] : (!fir.ref<!fir.array<100x200x!fir.logical<4>>>, i64, i64) -> !fir.ref<!fir.logical<4>>
+! CHECK:             %[[VAL_44:.*]] = fir.load %[[VAL_43]] : !fir.ref<!fir.logical<4>>
+! CHECK:             %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (!fir.logical<4>) -> i1
+! CHECK:             %[[VAL_46:.*]] = fir.if %[[VAL_45]] -> (!fir.array<100x400xf32>) {
+! CHECK:               %[[VAL_47:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_48:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32>
+! CHECK:               %[[VAL_49:.*]] = fir.convert %[[VAL_48]] : (i32) -> i64
+! CHECK:               %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (i64) -> index
+! CHECK:               %[[VAL_51:.*]] = arith.subi %[[VAL_50]], %[[VAL_47]] : index
+! CHECK:               %[[VAL_52:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:               %[[VAL_53:.*]] = fir.convert %[[VAL_52]] : (i32) -> i64
+! CHECK:               %[[VAL_54:.*]] = fir.convert %[[VAL_53]] : (i64) -> index
+! CHECK:               %[[VAL_55:.*]] = arith.subi %[[VAL_54]], %[[VAL_47]] : index
+! CHECK:               %[[VAL_56:.*]] = arith.constant 1 : index
+! CHECK-DAG:           %[[VAL_57:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32>
+! CHECK-DAG:           %[[VAL_58:.*]] = arith.constant 1 : i32
+! CHECK:               %[[VAL_59:.*]] = arith.addi %[[VAL_57]], %[[VAL_58]] : i32
+! CHECK:               %[[VAL_60:.*]] = fir.convert %[[VAL_59]] : (i32) -> i64
+! CHECK:               %[[VAL_61:.*]] = fir.convert %[[VAL_60]] : (i64) -> index
+! CHECK:               %[[VAL_62:.*]] = arith.subi %[[VAL_61]], %[[VAL_56]] : index
+! CHECK:               %[[VAL_63:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:               %[[VAL_64:.*]] = fir.convert %[[VAL_63]] : (i32) -> i64
+! CHECK:               %[[VAL_65:.*]] = fir.convert %[[VAL_64]] : (i64) -> index
+! CHECK:               %[[VAL_66:.*]] = arith.subi %[[VAL_65]], %[[VAL_56]] : index
+! CHECK:               %[[VAL_67:.*]] = fir.array_fetch %[[VAL_24]], %[[VAL_51]], %[[VAL_55]] : (!fir.array<200x200xf32>, index, index) -> f32
+! CHECK:               %[[VAL_68:.*]] = fir.array_fetch %[[VAL_26]], %[[VAL_62]], %[[VAL_66]] : (!fir.array<200x200xf32>, index, index) -> f32
+! CHECK:               %[[VAL_69:.*]] = arith.addf %[[VAL_67]], %[[VAL_68]] : f32
+! CHECK:               %[[VAL_70:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_71:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32>
+! CHECK:               %[[VAL_72:.*]] = fir.convert %[[VAL_71]] : (i32) -> i64
+! CHECK:               %[[VAL_73:.*]] = fir.convert %[[VAL_72]] : (i64) -> index
+! CHECK:               %[[VAL_74:.*]] = arith.subi %[[VAL_73]], %[[VAL_70]] : index
+! CHECK:               %[[VAL_75:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:               %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (i32) -> i64
+! CHECK:               %[[VAL_77:.*]] = fir.convert %[[VAL_76]] : (i64) -> index
+! CHECK:               %[[VAL_78:.*]] = arith.subi %[[VAL_77]], %[[VAL_70]] : index
+! CHECK:               %[[VAL_79:.*]] = fir.array_update %[[VAL_33]], %[[VAL_69]], %[[VAL_74]], %[[VAL_78]] : (!fir.array<100x400xf32>, f32, index, index) -> !fir.array<100x400xf32>
+! CHECK:               fir.result %[[VAL_79]] : !fir.array<100x400xf32>
+! CHECK:             } else {
+! CHECK:               fir.result %[[VAL_33]] : !fir.array<100x400xf32>
+! CHECK:             }
+! CHECK:             fir.result %[[VAL_80:.*]] : !fir.array<100x400xf32>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_81:.*]] : !fir.array<100x400xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_22]], %[[VAL_82:.*]] to %[[VAL_0]] : !fir.array<100x400xf32>, !fir.array<100x400xf32>, !fir.ref<!fir.array<100x400xf32>>
+! CHECK:         %[[VAL_83:.*]] = fir.shape %[[VAL_7]], %[[VAL_8]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_84:.*]] = fir.array_load %[[VAL_0]](%[[VAL_83]]) : (!fir.ref<!fir.array<100x400xf32>>, !fir.shape<2>) -> !fir.array<100x400xf32>
+! CHECK:         %[[VAL_85:.*]] = fir.shape %[[VAL_9]], %[[VAL_10]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_86:.*]] = fir.array_load %[[VAL_1]](%[[VAL_85]]) : (!fir.ref<!fir.array<200x200xf32>>, !fir.shape<2>) -> !fir.array<200x200xf32>
+! CHECK:         %[[VAL_87:.*]] = fir.do_loop %[[VAL_88:.*]] = %[[VAL_12]] to %[[VAL_14]] step %[[VAL_15]] unordered iter_args(%[[VAL_89:.*]] = %[[VAL_84]]) -> (!fir.array<100x400xf32>) {
+! CHECK:           %[[VAL_90:.*]] = fir.convert %[[VAL_88]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_90]] to %[[VAL_4]] : !fir.ref<i32>
+! CHECK:           %[[VAL_91:.*]] = fir.do_loop %[[VAL_92:.*]] = %[[VAL_17]] to %[[VAL_19]] step %[[VAL_20]] unordered iter_args(%[[VAL_93:.*]] = %[[VAL_89]]) -> (!fir.array<100x400xf32>) {
+! CHECK:             %[[VAL_94:.*]] = fir.convert %[[VAL_92]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_94]] to %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_95:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_96:.*]] = fir.convert %[[VAL_95]] : (i32) -> i64
+! CHECK:             %[[VAL_97:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_98:.*]] = arith.subi %[[VAL_96]], %[[VAL_97]] : i64
+! CHECK:             %[[VAL_99:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_100:.*]] = fir.convert %[[VAL_99]] : (i32) -> i64
+! CHECK:             %[[VAL_101:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_102:.*]] = arith.subi %[[VAL_100]], %[[VAL_101]] : i64
+! CHECK:             %[[VAL_103:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_98]], %[[VAL_102]] : (!fir.ref<!fir.array<100x200x!fir.logical<4>>>, i64, i64) -> !fir.ref<!fir.logical<4>>
+! CHECK:             %[[VAL_104:.*]] = fir.load %[[VAL_103]] : !fir.ref<!fir.logical<4>>
+! CHECK:             %[[VAL_105:.*]] = fir.convert %[[VAL_104]] : (!fir.logical<4>) -> i1
+! CHECK:             %[[VAL_106:.*]] = fir.if %[[VAL_105]] -> (!fir.array<100x400xf32>) {
+! CHECK:               %[[VAL_107:.*]] = arith.constant 1.000000e+00 : f32
+! CHECK:               %[[VAL_108:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_109:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:               %[[VAL_110:.*]] = fir.convert %[[VAL_109]] : (i32) -> i64
+! CHECK:               %[[VAL_111:.*]] = fir.convert %[[VAL_110]] : (i64) -> index
+! CHECK:               %[[VAL_112:.*]] = arith.subi %[[VAL_111]], %[[VAL_108]] : index
+! CHECK:               %[[VAL_113:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:               %[[VAL_114:.*]] = fir.convert %[[VAL_113]] : (i32) -> i64
+! CHECK:               %[[VAL_115:.*]] = fir.convert %[[VAL_114]] : (i64) -> index
+! CHECK:               %[[VAL_116:.*]] = arith.subi %[[VAL_115]], %[[VAL_108]] : index
+! CHECK:               %[[VAL_117:.*]] = fir.array_fetch %[[VAL_86]], %[[VAL_112]], %[[VAL_116]] : (!fir.array<200x200xf32>, index, index) -> f32
+! CHECK:               %[[VAL_118:.*]] = arith.divf %[[VAL_107]], %[[VAL_117]] : f32
+! CHECK:               %[[VAL_119:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_120:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:               %[[VAL_121:.*]] = fir.convert %[[VAL_120]] : (i32) -> i64
+! CHECK:               %[[VAL_122:.*]] = fir.convert %[[VAL_121]] : (i64) -> index
+! CHECK:               %[[VAL_123:.*]] = arith.subi %[[VAL_122]], %[[VAL_119]] : index
+! CHECK:               %[[VAL_124:.*]] = arith.constant 200 : i32
+! CHECK:               %[[VAL_125:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:               %[[VAL_126:.*]] = arith.addi %[[VAL_124]], %[[VAL_125]] : i32
+! CHECK:               %[[VAL_127:.*]] = fir.convert %[[VAL_126]] : (i32) -> i64
+! CHECK:               %[[VAL_128:.*]] = fir.convert %[[VAL_127]] : (i64) -> index
+! CHECK:               %[[VAL_129:.*]] = arith.subi %[[VAL_128]], %[[VAL_119]] : index
+! CHECK:               %[[VAL_130:.*]] = fir.array_update %[[VAL_93]], %[[VAL_118]], %[[VAL_123]], %[[VAL_129]] : (!fir.array<100x400xf32>, f32, index, index) -> !fir.array<100x400xf32>
+! CHECK:               fir.result %[[VAL_130]] : !fir.array<100x400xf32>
+! CHECK:             } else {
+! CHECK:               fir.result %[[VAL_93]] : !fir.array<100x400xf32>
+! CHECK:             }
+! CHECK:             fir.result %[[VAL_131:.*]] : !fir.array<100x400xf32>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_132:.*]] : !fir.array<100x400xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_84]], %[[VAL_133:.*]] to %[[VAL_0]] : !fir.array<100x400xf32>, !fir.array<100x400xf32>, !fir.ref<!fir.array<100x400xf32>>
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/forall-ranked.f90 b/flang/test/Lower/forall/forall-ranked.f90
new file mode 100644
index 0000000000000..4af3fa3fda247
--- /dev/null
+++ b/flang/test/Lower/forall/forall-ranked.f90
@@ -0,0 +1,75 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPtest_forall_with_ranked_dimension() {
+! CHECK:         %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_1:.*]] = arith.constant 10 : index
+! CHECK:         %[[VAL_2:.*]] = arith.constant 10 : index
+! CHECK:         %[[VAL_3:.*]] = fir.alloca !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>> {bindc_name = "a", uniq_name = "_QFtest_forall_with_ranked_dimensionEa"}
+! CHECK:         %[[VAL_4:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index
+! CHECK:         %[[VAL_6:.*]] = arith.constant 5 : i32
+! CHECK:         %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> index
+! CHECK:         %[[VAL_8:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_9:.*]] = fir.shape %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_10:.*]] = fir.array_load %[[VAL_3]](%[[VAL_9]]) : (!fir.ref<!fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>>, !fir.shape<2>) -> !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>
+! CHECK:         %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_5]] to %[[VAL_7]] step %[[VAL_8]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_10]]) -> (!fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>) {
+! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_14]] to %[[VAL_0]] : !fir.ref<i32>
+! CHECK:           %[[VAL_16:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_17:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_18:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
+! CHECK:           %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64
+! CHECK:           %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i64) -> index
+! CHECK:           %[[VAL_21:.*]] = arith.subi %[[VAL_20]], %[[VAL_17]] : index
+! CHECK:           %[[VAL_22:.*]] = arith.constant 1 : i64
+! CHECK:           %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index
+! CHECK:           %[[VAL_24:.*]] = arith.addi %[[VAL_17]], %[[VAL_2]] : index
+! CHECK:           %[[VAL_25:.*]] = arith.subi %[[VAL_24]], %[[VAL_17]] : index
+! CHECK:           %[[VAL_26:.*]] = arith.constant 0 : index
+! CHECK:           %[[VAL_27:.*]] = arith.subi %[[VAL_25]], %[[VAL_17]] : index
+! CHECK:           %[[VAL_28:.*]] = arith.addi %[[VAL_27]], %[[VAL_23]] : index
+! CHECK:           %[[VAL_29:.*]] = arith.divsi %[[VAL_28]], %[[VAL_23]] : index
+! CHECK:           %[[VAL_30:.*]] = arith.cmpi sgt, %[[VAL_29]], %[[VAL_26]] : index
+! CHECK:           %[[VAL_31:.*]] = arith.select %[[VAL_30]], %[[VAL_29]], %[[VAL_26]] : index
+! CHECK:           %[[VAL_32:.*]] = fir.field_index arr, !fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>
+! CHECK-DAG:       %[[VAL_33:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
+! CHECK-DAG:       %[[VAL_34:.*]] = arith.constant 4 : i32
+! CHECK:           %[[VAL_35:.*]] = arith.addi %[[VAL_33]], %[[VAL_34]] : i32
+! CHECK:           %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> i64
+! CHECK:           %[[VAL_37:.*]] = fir.convert %[[VAL_36]] : (i64) -> index
+! CHECK:           %[[VAL_38:.*]] = arith.subi %[[VAL_37]], %[[VAL_16]] : index
+! CHECK:           %[[VAL_39:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_40:.*]] = arith.constant 0 : index
+! CHECK:           %[[VAL_41:.*]] = arith.subi %[[VAL_31]], %[[VAL_39]] : index
+! CHECK:           %[[VAL_42:.*]] = fir.do_loop %[[VAL_43:.*]] = %[[VAL_40]] to %[[VAL_41]] step %[[VAL_39]] unordered iter_args(%[[VAL_44:.*]] = %[[VAL_13]]) -> (!fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>) {
+! CHECK:             %[[VAL_45:.*]] = fir.call @_QPf(%[[VAL_0]]) : (!fir.ref<i32>) -> i32
+! CHECK:             %[[VAL_46:.*]] = arith.subi %[[VAL_17]], %[[VAL_17]] : index
+! CHECK:             %[[VAL_47:.*]] = arith.muli %[[VAL_43]], %[[VAL_23]] : index
+! CHECK:             %[[VAL_48:.*]] = arith.addi %[[VAL_46]], %[[VAL_47]] : index
+! CHECK:             %[[VAL_49:.*]] = fir.array_update %[[VAL_44]], %[[VAL_45]], %[[VAL_21]], %[[VAL_48]], %[[VAL_32]], %[[VAL_38]] : (!fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>, i32, index, index, !fir.field, index) -> !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>
+! CHECK:             fir.result %[[VAL_49]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_50:.*]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_10]], %[[VAL_51:.*]] to %[[VAL_3]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>, !fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>, !fir.ref<!fir.array<10x10x!fir.type<_QFtest_forall_with_ranked_dimensionTt{arr:!fir.array<11xi32>}>>>
+! CHECK:         return
+! CHECK:       }
+
+subroutine test_forall_with_ranked_dimension
+  interface
+     pure integer function f(i)
+       integer, intent(in) :: i
+     end function f
+  end interface
+  type t
+     !integer :: arr(5:15)
+     integer :: arr(11)
+  end type t
+  type(t) :: a(10,10)
+  
+  forall (i=1:5)
+     a(i,:)%arr(i+4) = f(i)
+  end forall
+end subroutine test_forall_with_ranked_dimension

diff  --git a/flang/test/Lower/forall/forall-slice.f90 b/flang/test/Lower/forall/forall-slice.f90
new file mode 100644
index 0000000000000..77f977ca2b8fa
--- /dev/null
+++ b/flang/test/Lower/forall/forall-slice.f90
@@ -0,0 +1,91 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPtest_forall_with_slice(
+! CHECK-SAME:       %[[VAL_0:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_1:.*]]: !fir.ref<i32>{{.*}}) {
+! CHECK:         %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_4:.*]] = arith.constant 10 : index
+! CHECK:         %[[VAL_5:.*]] = arith.constant 10 : index
+! CHECK:         %[[VAL_6:.*]] = fir.alloca !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>> {bindc_name = "a", uniq_name = "_QFtest_forall_with_sliceEa"}
+! CHECK:         %[[VAL_7:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index
+! CHECK:         %[[VAL_9:.*]] = arith.constant 5 : i32
+! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
+! CHECK:         %[[VAL_11:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_12:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i32) -> index
+! CHECK:         %[[VAL_14:.*]] = arith.constant 10 : i32
+! CHECK:         %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> index
+! CHECK:         %[[VAL_16:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_17:.*]] = fir.shape %[[VAL_4]], %[[VAL_5]] : (index, index) -> !fir.shape<2>
+! CHECK:         %[[VAL_18:.*]] = fir.array_load %[[VAL_6]](%[[VAL_17]]) : (!fir.ref<!fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>>, !fir.shape<2>) -> !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>
+! CHECK:         %[[VAL_19:.*]] = fir.do_loop %[[VAL_20:.*]] = %[[VAL_8]] to %[[VAL_10]] step %[[VAL_11]] unordered iter_args(%[[VAL_21:.*]] = %[[VAL_18]]) -> (!fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>) {
+! CHECK:           %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_22]] to %[[VAL_3]] : !fir.ref<i32>
+! CHECK:           %[[VAL_23:.*]] = fir.do_loop %[[VAL_24:.*]] = %[[VAL_13]] to %[[VAL_15]] step %[[VAL_16]] unordered iter_args(%[[VAL_25:.*]] = %[[VAL_21]]) -> (!fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>) {
+! CHECK:             %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_26]] to %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_27:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_28:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64
+! CHECK:             %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
+! CHECK:             %[[VAL_31:.*]] = arith.subi %[[VAL_30]], %[[VAL_27]] : index
+! CHECK:             %[[VAL_32:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (i32) -> i64
+! CHECK:             %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (i64) -> index
+! CHECK:             %[[VAL_35:.*]] = arith.subi %[[VAL_34]], %[[VAL_27]] : index
+! CHECK:             %[[VAL_36:.*]] = fir.field_index arr, !fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>
+! CHECK:             %[[VAL_37:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_38:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (i32) -> i64
+! CHECK:             %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (i64) -> index
+! CHECK:             %[[VAL_41:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:             %[[VAL_42:.*]] = fir.convert %[[VAL_41]] : (i32) -> i64
+! CHECK:             %[[VAL_43:.*]] = fir.convert %[[VAL_42]] : (i64) -> index
+! CHECK:             %[[VAL_44:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
+! CHECK:             %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (i32) -> i64
+! CHECK:             %[[VAL_46:.*]] = fir.convert %[[VAL_45]] : (i64) -> index
+! CHECK:             %[[VAL_47:.*]] = arith.constant 0 : index
+! CHECK:             %[[VAL_48:.*]] = arith.subi %[[VAL_46]], %[[VAL_40]] : index
+! CHECK:             %[[VAL_49:.*]] = arith.addi %[[VAL_48]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_50:.*]] = arith.divsi %[[VAL_49]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_51:.*]] = arith.cmpi sgt, %[[VAL_50]], %[[VAL_47]] : index
+! CHECK:             %[[VAL_52:.*]] = arith.select %[[VAL_51]], %[[VAL_50]], %[[VAL_47]] : index
+! CHECK:             %[[VAL_53:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_54:.*]] = arith.constant 0 : index
+! CHECK:             %[[VAL_55:.*]] = arith.subi %[[VAL_52]], %[[VAL_53]] : index
+! CHECK:             %[[VAL_56:.*]] = fir.do_loop %[[VAL_57:.*]] = %[[VAL_54]] to %[[VAL_55]] step %[[VAL_53]] unordered iter_args(%[[VAL_58:.*]] = %[[VAL_25]]) -> (!fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>) {
+! CHECK:               %[[VAL_59:.*]] = fir.call @_QPf(%[[VAL_3]]) : (!fir.ref<i32>) -> i32
+! CHECK:               %[[VAL_60:.*]] = arith.subi %[[VAL_40]], %[[VAL_37]] : index
+! CHECK:               %[[VAL_61:.*]] = arith.muli %[[VAL_57]], %[[VAL_43]] : index
+! CHECK:               %[[VAL_62:.*]] = arith.addi %[[VAL_60]], %[[VAL_61]] : index
+! CHECK:               %[[VAL_63:.*]] = fir.array_update %[[VAL_58]], %[[VAL_59]], %[[VAL_31]], %[[VAL_35]], %[[VAL_36]], %[[VAL_62]] : (!fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>, i32, index, index, !fir.field, index) -> !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>
+! CHECK:               fir.result %[[VAL_63]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>
+! CHECK:             }
+! CHECK:             fir.result %[[VAL_64:.*]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_65:.*]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_18]], %[[VAL_66:.*]] to %[[VAL_6]] : !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>, !fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>, !fir.ref<!fir.array<10x10x!fir.type<_QFtest_forall_with_sliceTt{arr:!fir.array<11xi32>}>>>
+! CHECK:         return
+! CHECK:       }
+
+subroutine test_forall_with_slice(i1,i2)
+  interface
+     pure integer function f(i)
+       integer i
+       intent(in) i
+     end function f
+  end interface
+  type t
+     !integer :: arr(5:15)
+     integer :: arr(11)
+  end type t
+  type(t) :: a(10,10)
+
+  forall (i=1:5, j=1:10)
+     a(i,j)%arr(i:i1:i2) = f(i)
+  end forall
+end subroutine test_forall_with_slice

diff  --git a/flang/test/Lower/forall/forall-stmt.f90 b/flang/test/Lower/forall/forall-stmt.f90
new file mode 100644
index 0000000000000..4067cdb1ba054
--- /dev/null
+++ b/flang/test/Lower/forall/forall-stmt.f90
@@ -0,0 +1,50 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+!*** Test a FORALL statement
+subroutine test_forall_stmt(x, mask)
+
+  logical :: mask(200)
+  real :: x(200)
+  forall (i=1:100,mask(i)) x(i) = 1.
+end subroutine test_forall_stmt
+
+! CHECK-LABEL: func @_QPtest_forall_stmt(
+! CHECK-SAME:    %[[VAL_0:.*]]: !fir.ref<!fir.array<200xf32>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<200x!fir.logical<4>>>{{.*}}) {
+! CHECK:         %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_3:.*]] = arith.constant 200 : index
+! CHECK:         %[[VAL_4:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index
+! CHECK:         %[[VAL_6:.*]] = arith.constant 100 : i32
+! CHECK:         %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> index
+! CHECK:         %[[VAL_8:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_9:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_10:.*]] = fir.array_load %[[VAL_0]](%[[VAL_9]]) : (!fir.ref<!fir.array<200xf32>>, !fir.shape<1>) -> !fir.array<200xf32>
+! CHECK:         %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_5]] to %[[VAL_7]] step %[[VAL_8]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_10]]) -> (!fir.array<200xf32>) {
+! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_14]] to %[[VAL_2]] : !fir.ref<i32>
+! CHECK:           %[[VAL_15:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64
+! CHECK:           %[[VAL_17:.*]] = arith.constant 1 : i64
+! CHECK:           %[[VAL_18:.*]] = arith.subi %[[VAL_16]], %[[VAL_17]] : i64
+! CHECK:           %[[VAL_19:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_18]] : (!fir.ref<!fir.array<200x!fir.logical<4>>>, i64) -> !fir.ref<!fir.logical<4>>
+! CHECK:           %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<!fir.logical<4>>
+! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.logical<4>) -> i1
+! CHECK:           %[[VAL_22:.*]] = fir.if %[[VAL_21]] -> (!fir.array<200xf32>) {
+! CHECK:             %[[VAL_23:.*]] = arith.constant 1.000000e+00 : f32
+! CHECK:             %[[VAL_24:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_25:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> i64
+! CHECK:             %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i64) -> index
+! CHECK:             %[[VAL_28:.*]] = arith.subi %[[VAL_27]], %[[VAL_24]] : index
+! CHECK:             %[[VAL_29:.*]] = fir.array_update %[[VAL_13]], %[[VAL_23]], %[[VAL_28]] : (!fir.array<200xf32>, f32, index) -> !fir.array<200xf32>
+! CHECK:             fir.result %[[VAL_29]] : !fir.array<200xf32>
+! CHECK:           } else {
+! CHECK:             fir.result %[[VAL_13]] : !fir.array<200xf32>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_30:.*]] : !fir.array<200xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_10]], %[[VAL_31:.*]] to %[[VAL_0]] : !fir.array<200xf32>, !fir.array<200xf32>, !fir.ref<!fir.array<200xf32>>
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/forall-where-2.f90 b/flang/test/Lower/forall/forall-where-2.f90
new file mode 100644
index 0000000000000..6686d651d2bb1
--- /dev/null
+++ b/flang/test/Lower/forall/forall-where-2.f90
@@ -0,0 +1,76 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+
+! Test a FORALL construct with a nested WHERE construct where the mask
+! contains temporary array expressions.
+
+subroutine test_nested_forall_where_with_temp_in_mask(a,b)  
+  interface
+    function temp_foo(i, j)
+      integer :: i, j
+      real, allocatable :: temp_foo(:)
+    end function
+  end interface
+  type t
+     real data(100)
+  end type t
+  type(t) :: a(:,:), b(:,:)
+  forall (i=1:ubound(a,1), j=1:ubound(a,2))
+     where (b(j,i)%data > temp_foo(i, j))
+        a(i,j)%data = b(j,i)%data / 3.14
+     elsewhere
+        a(i,j)%data = -b(j,i)%data
+     end where
+  end forall
+end subroutine
+
+! CHECK:  func @_QPtest_nested_forall_where_with_temp_in_mask({{.*}}) {
+! CHECK:   %[[tempResultBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = ".result"}
+           ! Where condition pre-evaluation 
+! CHECK:   fir.do_loop {{.*}} {
+! CHECK:      fir.do_loop {{.*}} {
+                ! Evaluation of mask for iteration (i,j) into ragged array temp 
+! CHECK:        %[[tempResult:.*]] = fir.call @_QPtemp_foo
+! CHECK:        fir.save_result %[[tempResult]] to %[[tempResultBox]] : !fir.box<!fir.heap<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:        fir.if {{.*}} {
+! CHECK:          @_FortranARaggedArrayAllocate
+! CHECK:        }
+! CHECK:        fir.do_loop {{.*}} {
+                  ! store into ragged array temp element
+! CHECK:        }
+! CHECK:        %[[box:.*]] = fir.load %[[tempResultBox]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:        %[[tempAddr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+                ! local temps that were generated during the evaluation are cleaned-up after the value were stored
+                ! into the ragged array temp.
+! CHECK:        fir.freemem %[[tempAddr]]
+! CHECK:      }
+! CHECK:    }
+            ! Where assignment
+! CHECK:    fir.do_loop {{.*}} {
+! CHECK:      fir.do_loop {{.*}} {
+                ! Array assignment at iteration (i, j)
+! CHECK:        fir.do_loop {{.*}} {
+! CHECK:          fir.if {{.*}} {  
+! CHECK:            arith.divf
+! CHECK:          } else {
+! CHECK:          }
+! CHECK:        }
+! CHECK:      }
+! CHECK:    }
+            ! Elsewhere assignment
+! CHECK:    fir.do_loop {{.*}} {
+! CHECK:      fir.do_loop {{.*}} {
+                ! Array assignment at iteration (i, j)
+! CHECK:        fir.do_loop {{.*}} {
+! CHECK:          fir.if {{.*}} {  
+! CHECK:          } else {
+! CHECK:            arith.negf
+! CHECK:          }
+! CHECK:        }
+! CHECK:      }
+! CHECK:    }
+            ! Ragged array clean-up
+! CHECK:    fir.call @_FortranARaggedArrayDeallocate
+! CHECK:  }

diff  --git a/flang/test/Lower/forall/forall-where.f90 b/flang/test/Lower/forall/forall-where.f90
new file mode 100644
index 0000000000000..6cf7d80f84b99
--- /dev/null
+++ b/flang/test/Lower/forall/forall-where.f90
@@ -0,0 +1,385 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+!*** Test a FORALL construct with a nested WHERE construct.
+!    This has both an explicit and implicit iteration space. The WHERE construct
+!    makes the assignments conditional and the where mask evaluation must happen
+!    prior to evaluating the array assignment statement.
+subroutine test_nested_forall_where(a,b)  
+  type t
+     real data(100)
+  end type t
+  type(t) :: a(:,:), b(:,:)
+  forall (i=1:ubound(a,1), j=1:ubound(a,2))
+     where (b(j,i)%data > 0.0)
+        a(i,j)%data = b(j,i)%data / 3.14
+     elsewhere
+        a(i,j)%data = -b(j,i)%data
+     end where
+  end forall
+end subroutine test_nested_forall_where
+
+! CHECK-LABEL: func @_QPtest_nested_forall_where(
+! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>{{.*}}, %[[VAL_1:.*]]: !fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>{{.*}}) {
+! CHECK:         %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_4:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_5:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_6:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
+! CHECK:         %[[VAL_7:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_8:.*]] = fir.alloca tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>
+! CHECK:         %[[VAL_9:.*]] = arith.constant 0 : i32
+! CHECK:         %[[VAL_10:.*]] = arith.constant 0 : i64
+! CHECK:         %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_9]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<i64>
+! CHECK:         fir.store %[[VAL_10]] to %[[VAL_11]] : !fir.ref<i64>
+! CHECK:         %[[VAL_12:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_13:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi8>>
+! CHECK:         %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_12]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:         fir.store %[[VAL_13]] to %[[VAL_14]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:         %[[VAL_15:.*]] = arith.constant 2 : i32
+! CHECK:         %[[VAL_16:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi64>>
+! CHECK:         %[[VAL_17:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_15]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi64>>>
+! CHECK:         fir.store %[[VAL_16]] to %[[VAL_17]] : !fir.ref<!fir.heap<!fir.array<?xi64>>>
+! CHECK:         %[[VAL_18:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> index
+! CHECK:         %[[VAL_20:.*]] = arith.constant 0 : index
+! CHECK:         %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>, index) -> (index, index, index)
+! CHECK:         %[[VAL_22:.*]] = fir.convert %[[VAL_21]]#1 : (index) -> i64
+! CHECK:         %[[VAL_23:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (index) -> i64
+! CHECK:         %[[VAL_25:.*]] = arith.addi %[[VAL_22]], %[[VAL_24]] : i64
+! CHECK:         %[[VAL_26:.*]] = arith.constant 1 : i64
+! CHECK:         %[[VAL_27:.*]] = arith.subi %[[VAL_25]], %[[VAL_26]] : i64
+! CHECK:         %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i64) -> i32
+! CHECK:         %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> index
+! CHECK:         %[[VAL_30:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_31:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i32) -> index
+! CHECK:         %[[VAL_33:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_34:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_33]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>, index) -> (index, index, index)
+! CHECK:         %[[VAL_35:.*]] = fir.convert %[[VAL_34]]#1 : (index) -> i64
+! CHECK:         %[[VAL_36:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_37:.*]] = fir.convert %[[VAL_36]] : (index) -> i64
+! CHECK:         %[[VAL_38:.*]] = arith.addi %[[VAL_35]], %[[VAL_37]] : i64
+! CHECK:         %[[VAL_39:.*]] = arith.constant 1 : i64
+! CHECK:         %[[VAL_40:.*]] = arith.subi %[[VAL_38]], %[[VAL_39]] : i64
+! CHECK:         %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i64) -> i32
+! CHECK:         %[[VAL_42:.*]] = fir.convert %[[VAL_41]] : (i32) -> index
+! CHECK:         %[[VAL_43:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_44:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>) -> !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         %[[VAL_45:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>) -> !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         %[[VAL_46:.*]] = fir.do_loop %[[VAL_47:.*]] = %[[VAL_19]] to %[[VAL_29]] step %[[VAL_30]] unordered iter_args(%[[VAL_48:.*]] = %[[VAL_44]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:           %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_49]] to %[[VAL_7]] : !fir.ref<i32>
+! CHECK:           %[[VAL_50:.*]] = fir.do_loop %[[VAL_51:.*]] = %[[VAL_32]] to %[[VAL_42]] step %[[VAL_43]] unordered iter_args(%[[VAL_52:.*]] = %[[VAL_48]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:             %[[VAL_53:.*]] = fir.convert %[[VAL_51]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_53]] to %[[VAL_6]] : !fir.ref<i32>
+! CHECK:             %[[VAL_54:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_55:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_56:.*]] = fir.convert %[[VAL_19]] : (index) -> i64
+! CHECK:             %[[VAL_57:.*]] = fir.convert %[[VAL_29]] : (index) -> i64
+! CHECK:             %[[VAL_58:.*]] = fir.convert %[[VAL_30]] : (index) -> i64
+! CHECK:             %[[VAL_59:.*]] = arith.subi %[[VAL_57]], %[[VAL_56]] : i64
+! CHECK:             %[[VAL_60:.*]] = arith.addi %[[VAL_59]], %[[VAL_58]] : i64
+! CHECK:             %[[VAL_61:.*]] = arith.divsi %[[VAL_60]], %[[VAL_58]] : i64
+! CHECK:             %[[VAL_62:.*]] = arith.cmpi sgt, %[[VAL_61]], %[[VAL_55]] : i64
+! CHECK:             %[[VAL_63:.*]] = arith.select %[[VAL_62]], %[[VAL_61]], %[[VAL_55]] : i64
+! CHECK:             %[[VAL_64:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_65:.*]] = fir.convert %[[VAL_32]] : (index) -> i64
+! CHECK:             %[[VAL_66:.*]] = fir.convert %[[VAL_42]] : (index) -> i64
+! CHECK:             %[[VAL_67:.*]] = fir.convert %[[VAL_43]] : (index) -> i64
+! CHECK:             %[[VAL_68:.*]] = arith.subi %[[VAL_66]], %[[VAL_65]] : i64
+! CHECK:             %[[VAL_69:.*]] = arith.addi %[[VAL_68]], %[[VAL_67]] : i64
+! CHECK:             %[[VAL_70:.*]] = arith.divsi %[[VAL_69]], %[[VAL_67]] : i64
+! CHECK:             %[[VAL_71:.*]] = arith.cmpi sgt, %[[VAL_70]], %[[VAL_64]] : i64
+! CHECK:             %[[VAL_72:.*]] = arith.select %[[VAL_71]], %[[VAL_70]], %[[VAL_64]] : i64
+! CHECK:             %[[VAL_73:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_74:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_73]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (!fir.heap<!fir.array<?xi8>>) -> i64
+! CHECK:             %[[VAL_77:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_78:.*]] = arith.cmpi eq, %[[VAL_76]], %[[VAL_77]] : i64
+! CHECK:             fir.if %[[VAL_78]] {
+! CHECK:               %[[VAL_79:.*]] = arith.constant true
+! CHECK:               %[[VAL_80:.*]] = arith.constant 2 : i64
+! CHECK:               %[[VAL_81:.*]] = fir.allocmem !fir.array<2xi64>
+! CHECK:               %[[VAL_82:.*]] = arith.constant 0 : i32
+! CHECK:               %[[VAL_83:.*]] = fir.coordinate_of %[[VAL_81]], %[[VAL_82]] : (!fir.heap<!fir.array<2xi64>>, i32) -> !fir.ref<i64>
+! CHECK:               fir.store %[[VAL_63]] to %[[VAL_83]] : !fir.ref<i64>
+! CHECK:               %[[VAL_84:.*]] = arith.constant 1 : i32
+! CHECK:               %[[VAL_85:.*]] = fir.coordinate_of %[[VAL_81]], %[[VAL_84]] : (!fir.heap<!fir.array<2xi64>>, i32) -> !fir.ref<i64>
+! CHECK:               fir.store %[[VAL_72]] to %[[VAL_85]] : !fir.ref<i64>
+! CHECK:               %[[VAL_86:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>) -> !fir.llvm_ptr<i8>
+! CHECK:               %[[VAL_87:.*]] = fir.convert %[[VAL_81]] : (!fir.heap<!fir.array<2xi64>>) -> !fir.ref<i64>
+! CHECK:               %[[VAL_88:.*]] = fir.call @_FortranARaggedArrayAllocate(%[[VAL_86]], %[[VAL_79]], %[[VAL_80]], %[[VAL_54]], %[[VAL_87]]) : (!fir.llvm_ptr<i8>, i1, i64, i64, !fir.ref<i64>) -> !fir.llvm_ptr<i8>
+! CHECK:             }
+! CHECK:             %[[VAL_89:.*]] = arith.subi %[[VAL_47]], %[[VAL_19]] : index
+! CHECK:             %[[VAL_90:.*]] = arith.divsi %[[VAL_89]], %[[VAL_30]] : index
+! CHECK:             %[[VAL_91:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_92:.*]] = arith.addi %[[VAL_90]], %[[VAL_91]] : index
+! CHECK:             %[[VAL_93:.*]] = arith.subi %[[VAL_51]], %[[VAL_32]] : index
+! CHECK:             %[[VAL_94:.*]] = arith.divsi %[[VAL_93]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_95:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_96:.*]] = arith.addi %[[VAL_94]], %[[VAL_95]] : index
+! CHECK:             %[[VAL_97:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_98:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_97]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_99:.*]] = fir.load %[[VAL_98]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_100:.*]] = fir.convert %[[VAL_99]] : (!fir.heap<!fir.array<?xi8>>) -> !fir.ref<!fir.array<?x?xtuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>>
+! CHECK:             %[[VAL_101:.*]] = fir.shape %[[VAL_63]], %[[VAL_72]] : (i64, i64) -> !fir.shape<2>
+! CHECK:             %[[VAL_102:.*]] = fir.array_coor %[[VAL_100]](%[[VAL_101]]) %[[VAL_92]], %[[VAL_96]] : (!fir.ref<!fir.array<?x?xtuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>>, !fir.shape<2>, index, index) -> !fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>
+! CHECK:             %[[VAL_103:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32>
+! CHECK:             %[[VAL_104:.*]] = fir.convert %[[VAL_103]] : (i32) -> i64
+! CHECK:             %[[VAL_105:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_106:.*]] = arith.subi %[[VAL_104]], %[[VAL_105]] : i64
+! CHECK:             %[[VAL_107:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32>
+! CHECK:             %[[VAL_108:.*]] = fir.convert %[[VAL_107]] : (i32) -> i64
+! CHECK:             %[[VAL_109:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_110:.*]] = arith.subi %[[VAL_108]], %[[VAL_109]] : i64
+! CHECK:             %[[VAL_111:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_106]], %[[VAL_110]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>, i64, i64) -> !fir.ref<!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:             %[[VAL_112:.*]] = fir.field_index data, !fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>
+! CHECK:             %[[VAL_113:.*]] = fir.coordinate_of %[[VAL_111]], %[[VAL_112]] : (!fir.ref<!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, !fir.field) -> !fir.ref<!fir.array<100xf32>>
+! CHECK:             %[[VAL_114:.*]] = arith.constant 100 : index
+! CHECK:             %[[VAL_115:.*]] = fir.shape %[[VAL_114]] : (index) -> !fir.shape<1>
+! CHECK:             %[[VAL_116:.*]] = fir.array_load %[[VAL_113]](%[[VAL_115]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.array<100xf32>
+! CHECK:             %[[VAL_117:.*]] = arith.constant 0.000000e+00 : f32
+! CHECK:             %[[VAL_118:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_119:.*]] = fir.coordinate_of %[[VAL_102]], %[[VAL_118]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_120:.*]] = fir.load %[[VAL_119]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_121:.*]] = fir.shape %[[VAL_114]] : (index) -> !fir.shape<1>
+! CHECK:             %[[VAL_122:.*]] = fir.array_load %[[VAL_120]](%[[VAL_121]]) : (!fir.heap<!fir.array<?xi8>>, !fir.shape<1>) -> !fir.array<?xi8>
+! CHECK:             %[[VAL_123:.*]] = arith.constant 1 : i64
+! CHECK:             %[[VAL_124:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_125:.*]] = fir.coordinate_of %[[VAL_102]], %[[VAL_124]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_126:.*]] = fir.load %[[VAL_125]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_127:.*]] = fir.convert %[[VAL_126]] : (!fir.heap<!fir.array<?xi8>>) -> i64
+! CHECK:             %[[VAL_128:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_129:.*]] = arith.cmpi eq, %[[VAL_127]], %[[VAL_128]] : i64
+! CHECK:             fir.if %[[VAL_129]] {
+! CHECK:               %[[VAL_130:.*]] = arith.constant false
+! CHECK:               %[[VAL_131:.*]] = arith.constant 1 : i64
+! CHECK:               %[[VAL_132:.*]] = fir.allocmem !fir.array<1xi64>
+! CHECK:               %[[VAL_133:.*]] = arith.constant 0 : i32
+! CHECK:               %[[VAL_134:.*]] = fir.coordinate_of %[[VAL_132]], %[[VAL_133]] : (!fir.heap<!fir.array<1xi64>>, i32) -> !fir.ref<i64>
+! CHECK:               %[[VAL_135:.*]] = fir.convert %[[VAL_114]] : (index) -> i64
+! CHECK:               fir.store %[[VAL_135]] to %[[VAL_134]] : !fir.ref<i64>
+! CHECK:               %[[VAL_136:.*]] = fir.convert %[[VAL_102]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>) -> !fir.llvm_ptr<i8>
+! CHECK:               %[[VAL_137:.*]] = fir.convert %[[VAL_132]] : (!fir.heap<!fir.array<1xi64>>) -> !fir.ref<i64>
+! CHECK:               %[[VAL_138:.*]] = fir.call @_FortranARaggedArrayAllocate(%[[VAL_136]], %[[VAL_130]], %[[VAL_131]], %[[VAL_123]], %[[VAL_137]]) : (!fir.llvm_ptr<i8>, i1, i64, i64, !fir.ref<i64>) -> !fir.llvm_ptr<i8>
+! CHECK:             }
+! CHECK:             %[[VAL_139:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_140:.*]] = arith.constant 0 : index
+! CHECK:             %[[VAL_141:.*]] = arith.subi %[[VAL_114]], %[[VAL_139]] : index
+! CHECK:             %[[VAL_142:.*]] = fir.do_loop %[[VAL_143:.*]] = %[[VAL_140]] to %[[VAL_141]] step %[[VAL_139]] unordered iter_args(%[[VAL_144:.*]] = %[[VAL_122]]) -> (!fir.array<?xi8>) {
+! CHECK:               %[[VAL_145:.*]] = fir.array_fetch %[[VAL_116]], %[[VAL_143]] : (!fir.array<100xf32>, index) -> f32
+! CHECK:               %[[VAL_146:.*]] = arith.cmpf ogt, %[[VAL_145]], %[[VAL_117]] : f32
+! CHECK:               %[[VAL_147:.*]] = arith.constant 1 : i32
+! CHECK:               %[[VAL_148:.*]] = fir.coordinate_of %[[VAL_102]], %[[VAL_147]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:               %[[VAL_149:.*]] = fir.load %[[VAL_148]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:               %[[VAL_150:.*]] = fir.shape %[[VAL_114]] : (index) -> !fir.shape<1>
+! CHECK:               %[[VAL_151:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_152:.*]] = arith.addi %[[VAL_143]], %[[VAL_151]] : index
+! CHECK:               %[[VAL_153:.*]] = fir.array_coor %[[VAL_149]](%[[VAL_150]]) %[[VAL_152]] : (!fir.heap<!fir.array<?xi8>>, !fir.shape<1>, index) -> !fir.ref<i8>
+! CHECK:               %[[VAL_154:.*]] = fir.convert %[[VAL_146]] : (i1) -> i8
+! CHECK:               fir.store %[[VAL_154]] to %[[VAL_153]] : !fir.ref<i8>
+! CHECK:               fir.result %[[VAL_144]] : !fir.array<?xi8>
+! CHECK:             }
+! CHECK:             fir.result %[[VAL_52]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_155:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         }
+! CHECK:         %[[VAL_156:.*]] = fir.do_loop %[[VAL_157:.*]] = %[[VAL_19]] to %[[VAL_29]] step %[[VAL_30]] unordered iter_args(%[[VAL_158:.*]] = %[[VAL_44]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:           %[[VAL_159:.*]] = fir.convert %[[VAL_157]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_159]] to %[[VAL_5]] : !fir.ref<i32>
+! CHECK:           %[[VAL_160:.*]] = fir.do_loop %[[VAL_161:.*]] = %[[VAL_32]] to %[[VAL_42]] step %[[VAL_43]] unordered iter_args(%[[VAL_162:.*]] = %[[VAL_158]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:             %[[VAL_163:.*]] = fir.convert %[[VAL_161]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_163]] to %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_164:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_165:.*]] = fir.convert %[[VAL_19]] : (index) -> i64
+! CHECK:             %[[VAL_166:.*]] = fir.convert %[[VAL_29]] : (index) -> i64
+! CHECK:             %[[VAL_167:.*]] = fir.convert %[[VAL_30]] : (index) -> i64
+! CHECK:             %[[VAL_168:.*]] = arith.subi %[[VAL_166]], %[[VAL_165]] : i64
+! CHECK:             %[[VAL_169:.*]] = arith.addi %[[VAL_168]], %[[VAL_167]] : i64
+! CHECK:             %[[VAL_170:.*]] = arith.divsi %[[VAL_169]], %[[VAL_167]] : i64
+! CHECK:             %[[VAL_171:.*]] = arith.cmpi sgt, %[[VAL_170]], %[[VAL_164]] : i64
+! CHECK:             %[[VAL_172:.*]] = arith.select %[[VAL_171]], %[[VAL_170]], %[[VAL_164]] : i64
+! CHECK:             %[[VAL_173:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_174:.*]] = fir.convert %[[VAL_32]] : (index) -> i64
+! CHECK:             %[[VAL_175:.*]] = fir.convert %[[VAL_42]] : (index) -> i64
+! CHECK:             %[[VAL_176:.*]] = fir.convert %[[VAL_43]] : (index) -> i64
+! CHECK:             %[[VAL_177:.*]] = arith.subi %[[VAL_175]], %[[VAL_174]] : i64
+! CHECK:             %[[VAL_178:.*]] = arith.addi %[[VAL_177]], %[[VAL_176]] : i64
+! CHECK:             %[[VAL_179:.*]] = arith.divsi %[[VAL_178]], %[[VAL_176]] : i64
+! CHECK:             %[[VAL_180:.*]] = arith.cmpi sgt, %[[VAL_179]], %[[VAL_173]] : i64
+! CHECK:             %[[VAL_181:.*]] = arith.select %[[VAL_180]], %[[VAL_179]], %[[VAL_173]] : i64
+! CHECK:             %[[VAL_182:.*]] = arith.subi %[[VAL_157]], %[[VAL_19]] : index
+! CHECK:             %[[VAL_183:.*]] = arith.divsi %[[VAL_182]], %[[VAL_30]] : index
+! CHECK:             %[[VAL_184:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_185:.*]] = arith.addi %[[VAL_183]], %[[VAL_184]] : index
+! CHECK:             %[[VAL_186:.*]] = arith.subi %[[VAL_161]], %[[VAL_32]] : index
+! CHECK:             %[[VAL_187:.*]] = arith.divsi %[[VAL_186]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_188:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_189:.*]] = arith.addi %[[VAL_187]], %[[VAL_188]] : index
+! CHECK:             %[[VAL_190:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_191:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_190]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_192:.*]] = fir.load %[[VAL_191]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_193:.*]] = fir.convert %[[VAL_192]] : (!fir.heap<!fir.array<?xi8>>) -> !fir.ref<!fir.array<?x?xtuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>>
+! CHECK:             %[[VAL_194:.*]] = fir.shape %[[VAL_172]], %[[VAL_181]] : (i64, i64) -> !fir.shape<2>
+! CHECK:             %[[VAL_195:.*]] = fir.array_coor %[[VAL_193]](%[[VAL_194]]) %[[VAL_185]], %[[VAL_189]] : (!fir.ref<!fir.array<?x?xtuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>>, !fir.shape<2>, index, index) -> !fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>
+! CHECK:             %[[VAL_196:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_197:.*]] = fir.coordinate_of %[[VAL_195]], %[[VAL_196]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_198:.*]] = fir.load %[[VAL_197]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_199:.*]] = fir.convert %[[VAL_198]] : (!fir.heap<!fir.array<?xi8>>) -> !fir.ref<!fir.array<?xi8>>
+! CHECK:             %[[VAL_200:.*]] = arith.constant 2 : i32
+! CHECK:             %[[VAL_201:.*]] = fir.coordinate_of %[[VAL_195]], %[[VAL_200]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi64>>>
+! CHECK:             %[[VAL_202:.*]] = fir.load %[[VAL_201]] : !fir.ref<!fir.heap<!fir.array<?xi64>>>
+! CHECK:             %[[VAL_203:.*]] = arith.constant 0 : i32
+! CHECK:             %[[VAL_204:.*]] = fir.coordinate_of %[[VAL_202]], %[[VAL_203]] : (!fir.heap<!fir.array<?xi64>>, i32) -> !fir.ref<i64>
+! CHECK:             %[[VAL_205:.*]] = fir.load %[[VAL_204]] : !fir.ref<i64>
+! CHECK:             %[[VAL_206:.*]] = fir.convert %[[VAL_205]] : (i64) -> index
+! CHECK:             %[[VAL_207:.*]] = fir.shape %[[VAL_206]] : (index) -> !fir.shape<1>
+! CHECK:             %[[VAL_208:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_209:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:             %[[VAL_210:.*]] = fir.convert %[[VAL_209]] : (i32) -> i64
+! CHECK:             %[[VAL_211:.*]] = fir.convert %[[VAL_210]] : (i64) -> index
+! CHECK:             %[[VAL_212:.*]] = arith.subi %[[VAL_211]], %[[VAL_208]] : index
+! CHECK:             %[[VAL_213:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_214:.*]] = fir.convert %[[VAL_213]] : (i32) -> i64
+! CHECK:             %[[VAL_215:.*]] = fir.convert %[[VAL_214]] : (i64) -> index
+! CHECK:             %[[VAL_216:.*]] = arith.subi %[[VAL_215]], %[[VAL_208]] : index
+! CHECK:             %[[VAL_217:.*]] = fir.field_index data, !fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>
+! CHECK:             %[[VAL_218:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_219:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
+! CHECK:             %[[VAL_220:.*]] = fir.convert %[[VAL_219]] : (i32) -> i64
+! CHECK:             %[[VAL_221:.*]] = fir.convert %[[VAL_220]] : (i64) -> index
+! CHECK:             %[[VAL_222:.*]] = arith.subi %[[VAL_221]], %[[VAL_218]] : index
+! CHECK:             %[[VAL_223:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
+! CHECK:             %[[VAL_224:.*]] = fir.convert %[[VAL_223]] : (i32) -> i64
+! CHECK:             %[[VAL_225:.*]] = fir.convert %[[VAL_224]] : (i64) -> index
+! CHECK:             %[[VAL_226:.*]] = arith.subi %[[VAL_225]], %[[VAL_218]] : index
+! CHECK:             %[[VAL_227:.*]] = fir.field_index data, !fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>
+! CHECK:             %[[VAL_228:.*]] = arith.constant 3.140000e+00 : f32
+! CHECK:             %[[VAL_229:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_230:.*]] = arith.constant 0 : index
+! CHECK:             %[[VAL_231:.*]] = arith.subi %[[VAL_206]], %[[VAL_229]] : index
+! CHECK:             %[[VAL_232:.*]] = fir.do_loop %[[VAL_233:.*]] = %[[VAL_230]] to %[[VAL_231]] step %[[VAL_229]] unordered iter_args(%[[VAL_234:.*]] = %[[VAL_162]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:               %[[VAL_235:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_236:.*]] = arith.addi %[[VAL_233]], %[[VAL_235]] : index
+! CHECK:               %[[VAL_237:.*]] = fir.array_coor %[[VAL_199]](%[[VAL_207]]) %[[VAL_236]] : (!fir.ref<!fir.array<?xi8>>, !fir.shape<1>, index) -> !fir.ref<i8>
+! CHECK:               %[[VAL_238:.*]] = fir.load %[[VAL_237]] : !fir.ref<i8>
+! CHECK:               %[[VAL_239:.*]] = fir.convert %[[VAL_238]] : (i8) -> i1
+! CHECK:               %[[VAL_240:.*]] = fir.if %[[VAL_239]] -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:                 %[[VAL_241:.*]] = fir.array_fetch %[[VAL_45]], %[[VAL_222]], %[[VAL_226]], %[[VAL_227]], %[[VAL_233]] : (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, index, index, !fir.field, index) -> f32
+! CHECK:                 %[[VAL_242:.*]] = arith.divf %[[VAL_241]], %[[VAL_228]] : f32
+! CHECK:                 %[[VAL_243:.*]] = fir.array_update %[[VAL_234]], %[[VAL_242]], %[[VAL_212]], %[[VAL_216]], %[[VAL_217]], %[[VAL_233]] : (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, f32, index, index, !fir.field, index) -> !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:                 fir.result %[[VAL_243]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:               } else {
+! CHECK:                 fir.result %[[VAL_234]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:               }
+! CHECK:               fir.result %[[VAL_244:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:             }
+! CHECK:             fir.result %[[VAL_245:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_246:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_44]], %[[VAL_247:.*]] to %[[VAL_0]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, !fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>
+! CHECK:         %[[VAL_248:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>) -> !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         %[[VAL_249:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>) -> !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         %[[VAL_250:.*]] = fir.do_loop %[[VAL_251:.*]] = %[[VAL_19]] to %[[VAL_29]] step %[[VAL_30]] unordered iter_args(%[[VAL_252:.*]] = %[[VAL_248]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:           %[[VAL_253:.*]] = fir.convert %[[VAL_251]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_253]] to %[[VAL_3]] : !fir.ref<i32>
+! CHECK:           %[[VAL_254:.*]] = fir.do_loop %[[VAL_255:.*]] = %[[VAL_32]] to %[[VAL_42]] step %[[VAL_43]] unordered iter_args(%[[VAL_256:.*]] = %[[VAL_252]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:             %[[VAL_257:.*]] = fir.convert %[[VAL_255]] : (index) -> i32
+! CHECK:             fir.store %[[VAL_257]] to %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_258:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_259:.*]] = fir.convert %[[VAL_19]] : (index) -> i64
+! CHECK:             %[[VAL_260:.*]] = fir.convert %[[VAL_29]] : (index) -> i64
+! CHECK:             %[[VAL_261:.*]] = fir.convert %[[VAL_30]] : (index) -> i64
+! CHECK:             %[[VAL_262:.*]] = arith.subi %[[VAL_260]], %[[VAL_259]] : i64
+! CHECK:             %[[VAL_263:.*]] = arith.addi %[[VAL_262]], %[[VAL_261]] : i64
+! CHECK:             %[[VAL_264:.*]] = arith.divsi %[[VAL_263]], %[[VAL_261]] : i64
+! CHECK:             %[[VAL_265:.*]] = arith.cmpi sgt, %[[VAL_264]], %[[VAL_258]] : i64
+! CHECK:             %[[VAL_266:.*]] = arith.select %[[VAL_265]], %[[VAL_264]], %[[VAL_258]] : i64
+! CHECK:             %[[VAL_267:.*]] = arith.constant 0 : i64
+! CHECK:             %[[VAL_268:.*]] = fir.convert %[[VAL_32]] : (index) -> i64
+! CHECK:             %[[VAL_269:.*]] = fir.convert %[[VAL_42]] : (index) -> i64
+! CHECK:             %[[VAL_270:.*]] = fir.convert %[[VAL_43]] : (index) -> i64
+! CHECK:             %[[VAL_271:.*]] = arith.subi %[[VAL_269]], %[[VAL_268]] : i64
+! CHECK:             %[[VAL_272:.*]] = arith.addi %[[VAL_271]], %[[VAL_270]] : i64
+! CHECK:             %[[VAL_273:.*]] = arith.divsi %[[VAL_272]], %[[VAL_270]] : i64
+! CHECK:             %[[VAL_274:.*]] = arith.cmpi sgt, %[[VAL_273]], %[[VAL_267]] : i64
+! CHECK:             %[[VAL_275:.*]] = arith.select %[[VAL_274]], %[[VAL_273]], %[[VAL_267]] : i64
+! CHECK:             %[[VAL_276:.*]] = arith.subi %[[VAL_251]], %[[VAL_19]] : index
+! CHECK:             %[[VAL_277:.*]] = arith.divsi %[[VAL_276]], %[[VAL_30]] : index
+! CHECK:             %[[VAL_278:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_279:.*]] = arith.addi %[[VAL_277]], %[[VAL_278]] : index
+! CHECK:             %[[VAL_280:.*]] = arith.subi %[[VAL_255]], %[[VAL_32]] : index
+! CHECK:             %[[VAL_281:.*]] = arith.divsi %[[VAL_280]], %[[VAL_43]] : index
+! CHECK:             %[[VAL_282:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_283:.*]] = arith.addi %[[VAL_281]], %[[VAL_282]] : index
+! CHECK:             %[[VAL_284:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_285:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_284]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_286:.*]] = fir.load %[[VAL_285]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_287:.*]] = fir.convert %[[VAL_286]] : (!fir.heap<!fir.array<?xi8>>) -> !fir.ref<!fir.array<?x?xtuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>>
+! CHECK:             %[[VAL_288:.*]] = fir.shape %[[VAL_266]], %[[VAL_275]] : (i64, i64) -> !fir.shape<2>
+! CHECK:             %[[VAL_289:.*]] = fir.array_coor %[[VAL_287]](%[[VAL_288]]) %[[VAL_279]], %[[VAL_283]] : (!fir.ref<!fir.array<?x?xtuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>>, !fir.shape<2>, index, index) -> !fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>
+! CHECK:             %[[VAL_290:.*]] = arith.constant 1 : i32
+! CHECK:             %[[VAL_291:.*]] = fir.coordinate_of %[[VAL_289]], %[[VAL_290]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_292:.*]] = fir.load %[[VAL_291]] : !fir.ref<!fir.heap<!fir.array<?xi8>>>
+! CHECK:             %[[VAL_293:.*]] = fir.convert %[[VAL_292]] : (!fir.heap<!fir.array<?xi8>>) -> !fir.ref<!fir.array<?xi8>>
+! CHECK:             %[[VAL_294:.*]] = arith.constant 2 : i32
+! CHECK:             %[[VAL_295:.*]] = fir.coordinate_of %[[VAL_289]], %[[VAL_294]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>, i32) -> !fir.ref<!fir.heap<!fir.array<?xi64>>>
+! CHECK:             %[[VAL_296:.*]] = fir.load %[[VAL_295]] : !fir.ref<!fir.heap<!fir.array<?xi64>>>
+! CHECK:             %[[VAL_297:.*]] = arith.constant 0 : i32
+! CHECK:             %[[VAL_298:.*]] = fir.coordinate_of %[[VAL_296]], %[[VAL_297]] : (!fir.heap<!fir.array<?xi64>>, i32) -> !fir.ref<i64>
+! CHECK:             %[[VAL_299:.*]] = fir.load %[[VAL_298]] : !fir.ref<i64>
+! CHECK:             %[[VAL_300:.*]] = fir.convert %[[VAL_299]] : (i64) -> index
+! CHECK:             %[[VAL_301:.*]] = fir.shape %[[VAL_300]] : (index) -> !fir.shape<1>
+! CHECK:             %[[VAL_302:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_303:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_304:.*]] = fir.convert %[[VAL_303]] : (i32) -> i64
+! CHECK:             %[[VAL_305:.*]] = fir.convert %[[VAL_304]] : (i64) -> index
+! CHECK:             %[[VAL_306:.*]] = arith.subi %[[VAL_305]], %[[VAL_302]] : index
+! CHECK:             %[[VAL_307:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_308:.*]] = fir.convert %[[VAL_307]] : (i32) -> i64
+! CHECK:             %[[VAL_309:.*]] = fir.convert %[[VAL_308]] : (i64) -> index
+! CHECK:             %[[VAL_310:.*]] = arith.subi %[[VAL_309]], %[[VAL_302]] : index
+! CHECK:             %[[VAL_311:.*]] = fir.field_index data, !fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>
+! CHECK:             %[[VAL_312:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_313:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:             %[[VAL_314:.*]] = fir.convert %[[VAL_313]] : (i32) -> i64
+! CHECK:             %[[VAL_315:.*]] = fir.convert %[[VAL_314]] : (i64) -> index
+! CHECK:             %[[VAL_316:.*]] = arith.subi %[[VAL_315]], %[[VAL_312]] : index
+! CHECK:             %[[VAL_317:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:             %[[VAL_318:.*]] = fir.convert %[[VAL_317]] : (i32) -> i64
+! CHECK:             %[[VAL_319:.*]] = fir.convert %[[VAL_318]] : (i64) -> index
+! CHECK:             %[[VAL_320:.*]] = arith.subi %[[VAL_319]], %[[VAL_312]] : index
+! CHECK:             %[[VAL_321:.*]] = fir.field_index data, !fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>
+! CHECK:             %[[VAL_322:.*]] = arith.constant 1 : index
+! CHECK:             %[[VAL_323:.*]] = arith.constant 0 : index
+! CHECK:             %[[VAL_324:.*]] = arith.subi %[[VAL_300]], %[[VAL_322]] : index
+! CHECK:             %[[VAL_325:.*]] = fir.do_loop %[[VAL_326:.*]] = %[[VAL_323]] to %[[VAL_324]] step %[[VAL_322]] unordered iter_args(%[[VAL_327:.*]] = %[[VAL_256]]) -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:               %[[VAL_328:.*]] = arith.constant 1 : index
+! CHECK:               %[[VAL_329:.*]] = arith.addi %[[VAL_326]], %[[VAL_328]] : index
+! CHECK:               %[[VAL_330:.*]] = fir.array_coor %[[VAL_293]](%[[VAL_301]]) %[[VAL_329]] : (!fir.ref<!fir.array<?xi8>>, !fir.shape<1>, index) -> !fir.ref<i8>
+! CHECK:               %[[VAL_331:.*]] = fir.load %[[VAL_330]] : !fir.ref<i8>
+! CHECK:               %[[VAL_332:.*]] = fir.convert %[[VAL_331]] : (i8) -> i1
+! CHECK:               %[[VAL_333:.*]] = fir.if %[[VAL_332]] -> (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>) {
+! CHECK:                 fir.result %[[VAL_327]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:               } else {
+! CHECK:                 %[[VAL_334:.*]] = fir.array_fetch %[[VAL_249]], %[[VAL_316]], %[[VAL_320]], %[[VAL_321]], %[[VAL_326]] : (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, index, index, !fir.field, index) -> f32
+! CHECK:                 %[[VAL_335:.*]] = arith.negf %[[VAL_334]] : f32
+! CHECK:                 %[[VAL_336:.*]] = fir.array_update %[[VAL_327]], %[[VAL_335]], %[[VAL_306]], %[[VAL_310]], %[[VAL_311]], %[[VAL_326]] : (!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, f32, index, index, !fir.field, index) -> !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:                 fir.result %[[VAL_336]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:               }
+! CHECK:               fir.result %[[VAL_337:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:             }
+! CHECK:             fir.result %[[VAL_338:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:           }
+! CHECK:           fir.result %[[VAL_339:.*]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_248]], %[[VAL_340:.*]] to %[[VAL_0]] : !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, !fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>, !fir.box<!fir.array<?x?x!fir.type<_QFtest_nested_forall_whereTt{data:!fir.array<100xf32>}>>>
+! CHECK:         %[[VAL_341:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<tuple<i64, !fir.heap<!fir.array<?xi8>>, !fir.heap<!fir.array<?xi64>>>>) -> !fir.llvm_ptr<i8>
+! CHECK:         %[[VAL_342:.*]] = fir.call @_FortranARaggedArrayDeallocate(%[[VAL_341]]) : (!fir.llvm_ptr<i8>) -> none
+! CHECK:         return
+! CHECK:       }

diff  --git a/flang/test/Lower/forall/test9.f90 b/flang/test/Lower/forall/test9.f90
new file mode 100644
index 0000000000000..1d20cad06feed
--- /dev/null
+++ b/flang/test/Lower/forall/test9.f90
@@ -0,0 +1,68 @@
+! Test forall lowering
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+!*** This FORALL construct does present a potential loop-carried dependence if
+!*** implemented naively (and incorrectly). The final value of a(3) must be the
+!*** value of a(2) before loopy begins execution added to b(2).
+subroutine test9(a,b,n)
+
+  integer :: n
+  real, intent(inout) :: a(n)
+  real, intent(in) :: b(n)
+  loopy: FORALL (i=1:n-1)
+     a(i+1) = a(i) + b(i)
+  END FORALL loopy
+end subroutine test9
+
+! CHECK-LABEL: func @_QPtest9(
+! CHECK-SAME:    %[[VAL_0:.*]]: !fir.ref<!fir.array<?xf32>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<?xf32>>{{.*}}, %[[VAL_2:.*]]: !fir.ref<i32>{{.*}}) {
+! CHECK:         %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_4:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:         %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> i64
+! CHECK:         %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i64) -> index
+! CHECK:         %[[VAL_7:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:         %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> i64
+! CHECK:         %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> index
+! CHECK:         %[[VAL_10:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> index
+! CHECK:         %[[VAL_12:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK:         %[[VAL_13:.*]] = arith.constant 1 : i32
+! CHECK:         %[[VAL_14:.*]] = arith.subi %[[VAL_12]], %[[VAL_13]] : i32
+! CHECK:         %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> index
+! CHECK:         %[[VAL_16:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_17:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_18:.*]] = fir.array_load %[[VAL_0]](%[[VAL_17]]) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_19:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_20:.*]] = fir.array_load %[[VAL_0]](%[[VAL_19]]) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_21:.*]] = fir.shape %[[VAL_9]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_22:.*]] = fir.array_load %[[VAL_1]](%[[VAL_21]]) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_23:.*]] = fir.do_loop %[[VAL_24:.*]] = %[[VAL_11]] to %[[VAL_15]] step %[[VAL_16]] unordered iter_args(%[[VAL_25:.*]] = %[[VAL_18]]) -> (!fir.array<?xf32>) {
+! CHECK:           %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_26]] to %[[VAL_3]] : !fir.ref<i32>
+! CHECK:           %[[VAL_27:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_28:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:           %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64
+! CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
+! CHECK:           %[[VAL_31:.*]] = arith.subi %[[VAL_30]], %[[VAL_27]] : index
+! CHECK:           %[[VAL_32:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_33:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK:           %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (i32) -> i64
+! CHECK:           %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i64) -> index
+! CHECK:           %[[VAL_36:.*]] = arith.subi %[[VAL_35]], %[[VAL_32]] : index
+! CHECK:           %[[VAL_37:.*]] = fir.array_fetch %[[VAL_20]], %[[VAL_31]] : (!fir.array<?xf32>, index) -> f32
+! CHECK:           %[[VAL_38:.*]] = fir.array_fetch %[[VAL_22]], %[[VAL_36]] : (!fir.array<?xf32>, index) -> f32
+! CHECK:           %[[VAL_39:.*]] = arith.addf %[[VAL_37]], %[[VAL_38]] : f32
+! CHECK:           %[[VAL_40:.*]] = arith.constant 1 : index
+! CHECK-DAG:       %[[VAL_41:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
+! CHECK-DAG:       %[[VAL_42:.*]] = arith.constant 1 : i32
+! CHECK:           %[[VAL_43:.*]] = arith.addi %[[VAL_41]], %[[VAL_42]] : i32
+! CHECK:           %[[VAL_44:.*]] = fir.convert %[[VAL_43]] : (i32) -> i64
+! CHECK:           %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (i64) -> index
+! CHECK:           %[[VAL_46:.*]] = arith.subi %[[VAL_45]], %[[VAL_40]] : index
+! CHECK:           %[[VAL_47:.*]] = fir.array_update %[[VAL_25]], %[[VAL_39]], %[[VAL_46]] : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>
+! CHECK:           fir.result %[[VAL_47]] : !fir.array<?xf32>
+! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_18]], %[[VAL_48:.*]] to %[[VAL_0]] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.ref<!fir.array<?xf32>>
+! CHECK:         return
+! CHECK:       }


        


More information about the flang-commits mailing list