diff --git a/flang/test/Lower/forall/array-subscripts.f90 b/flang/test/Lower/forall/array-subscripts.f90 new file mode 100644 --- /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> +! CHECK: %[[a1:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<2>) -> !fir.array<4x4xi32> +! CHECK: %[[a2:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<2>) -> !fir.array<4x4xi32> +! CHECK: %[[a3:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !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> diff --git a/flang/test/Lower/forall/character-1.f90 b/flang/test/Lower/forall/character-1.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/forall/character-1.f90 @@ -0,0 +1,30 @@ +! RUN: bbc %s -o - | tco | FileCheck %s +! Test from Fortran source through to LLVM IR. + +! 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 --- /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>{{.*}}) { +! 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>>}> {bindc_name = "thing", uniq_name = "_QFforall_with_allocatable2Ething"} +! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_2]] : (!fir.ref>>}>>) -> !fir.box>>}>> +! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>>}>>) -> !fir.box +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAInitialize(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) : (!fir.box, !fir.ref, 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>>}> +! CHECK: %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_14]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> +! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_15]] : !fir.ref>>> +! CHECK: %[[VAL_17:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_16]], %[[VAL_17]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box>>) -> !fir.heap> +! 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.shapeshift<1>) -> !fir.array +! CHECK: %[[VAL_22:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array +! 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) { +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32 +! CHECK: fir.store %[[VAL_26]] to %[[VAL_1]] : !fir.ref +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_1]] : !fir.ref +! 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, index) -> f32 +! CHECK: %[[VAL_33:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_1]] : !fir.ref +! 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, f32, index) -> !fir.array +! CHECK: fir.result %[[VAL_38]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_21]], %[[VAL_39:.*]] to %[[VAL_19]] : !fir.array, !fir.array, !fir.heap> +! 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 --- /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>{{.*}}) { +! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} +! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box>> {bindc_name = "arr", uniq_name = "_QFforall_with_allocatableEarr"} +! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.heap> {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> +! CHECK: fir.store %[[VAL_6]] to %[[VAL_3]] : !fir.ref>> +! 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 +! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_5]] : !fir.ref +! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_3]] : !fir.ref>> +! 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.shapeshift<1>) -> !fir.array +! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array +! 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) { +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (index) -> i32 +! CHECK: fir.store %[[VAL_21]] to %[[VAL_1]] : !fir.ref +! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_1]] : !fir.ref +! 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, index) -> f32 +! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_1]] : !fir.ref +! 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, f32, index) -> !fir.array +! CHECK: fir.result %[[VAL_33]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_16]], %[[VAL_34:.*]] to %[[VAL_14]] : !fir.array, !fir.array, !fir.heap> +! 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 --- /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,block2:!fir.array<64xi64>}>>>{{.*}}, %[[VAL_1:.*]]: !fir.ref,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,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,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 +! CHECK: %[[VAL_19:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_2]] : !fir.ref +! 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 +! 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,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 --- /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>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { +! 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.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.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.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 +! 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 +! CHECK: %[[VAL_34:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_35:.*]] = fir.load %[[VAL_5]] : !fir.ref +! 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 +! 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 +! 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 +! 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 +! 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 +! 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> +! 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.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.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 +! 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 +! 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 +! 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 +! 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 +! 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 +! 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> +! 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 --- /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>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref>>{{.*}}) { +! 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.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.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.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 +! 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 +! CHECK: %[[VAL_35:.*]] = fir.load %[[VAL_6]] : !fir.ref +! 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 +! 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>>, i64, i64) -> !fir.ref> +! CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_43]] : !fir.ref> +! 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 +! 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 +! 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 +! 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 +! 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 +! 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 +! 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> +! 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.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.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 +! 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 +! CHECK: %[[VAL_95:.*]] = fir.load %[[VAL_4]] : !fir.ref +! 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 +! 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>>, i64, i64) -> !fir.ref> +! CHECK: %[[VAL_104:.*]] = fir.load %[[VAL_103]] : !fir.ref> +! 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 +! 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 +! 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 +! 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 +! 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> +! 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 --- /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.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 +! CHECK: %[[VAL_16:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_17:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_0]] : !fir.ref +! 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 +! 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 +! 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}>>> +! 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 --- /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{{.*}}, %[[VAL_1:.*]]: !fir.ref{{.*}}) { +! 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.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 +! 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 +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_3]] : !fir.ref +! 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 +! 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 +! 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 +! 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 +! 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 +! 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}>>> +! 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 --- /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>{{.*}}, %[[VAL_1:.*]]: !fir.ref>>{{.*}}) { +! 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.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 +! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_2]] : !fir.ref +! 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>>, i64) -> !fir.ref> +! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref> +! 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 +! 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> +! 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 --- /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>> {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.ref>>> +! CHECK: fir.if {{.*}} { +! CHECK: @_FortranARaggedArrayAllocate +! CHECK: } +! CHECK: fir.do_loop {{.*}} { + ! store into ragged array temp element +! CHECK: } +! CHECK: %[[box:.*]] = fir.load %[[tempResultBox]] : !fir.ref>>> +! CHECK: %[[tempAddr:.*]] = fir.box_addr %[[box]] : (!fir.box>>) -> !fir.heap> + ! 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 --- /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}>>>{{.*}}, %[[VAL_1:.*]]: !fir.box}>>>{{.*}}) { +! 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>, !fir.heap>> +! 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>, !fir.heap>>>, i32) -> !fir.ref +! CHECK: fir.store %[[VAL_10]] to %[[VAL_11]] : !fir.ref +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_13:.*]] = fir.zero_bits !fir.heap> +! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_12]] : (!fir.ref>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: fir.store %[[VAL_13]] to %[[VAL_14]] : !fir.ref>> +! CHECK: %[[VAL_15:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_16:.*]] = fir.zero_bits !fir.heap> +! CHECK: %[[VAL_17:.*]] = fir.coordinate_of %[[VAL_8]], %[[VAL_15]] : (!fir.ref>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: fir.store %[[VAL_16]] to %[[VAL_17]] : !fir.ref>> +! 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}>>>, 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}>>>, 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}>> +! CHECK: %[[VAL_45:.*]] = fir.array_load %[[VAL_1]] : (!fir.box}>>>) -> !fir.array}>> +! 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}>>) { +! CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (index) -> i32 +! CHECK: fir.store %[[VAL_49]] to %[[VAL_7]] : !fir.ref +! 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}>>) { +! CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_51]] : (index) -> i32 +! CHECK: fir.store %[[VAL_53]] to %[[VAL_6]] : !fir.ref +! 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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref>> +! CHECK: %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (!fir.heap>) -> 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>, i32) -> !fir.ref +! CHECK: fir.store %[[VAL_63]] to %[[VAL_83]] : !fir.ref +! CHECK: %[[VAL_84:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_85:.*]] = fir.coordinate_of %[[VAL_81]], %[[VAL_84]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: fir.store %[[VAL_72]] to %[[VAL_85]] : !fir.ref +! CHECK: %[[VAL_86:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>, !fir.heap>>>) -> !fir.llvm_ptr +! CHECK: %[[VAL_87:.*]] = fir.convert %[[VAL_81]] : (!fir.heap>) -> !fir.ref +! CHECK: %[[VAL_88:.*]] = fir.call @_FortranARaggedArrayAllocate(%[[VAL_86]], %[[VAL_79]], %[[VAL_80]], %[[VAL_54]], %[[VAL_87]]) : (!fir.llvm_ptr, i1, i64, i64, !fir.ref) -> !fir.llvm_ptr +! 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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_99:.*]] = fir.load %[[VAL_98]] : !fir.ref>> +! CHECK: %[[VAL_100:.*]] = fir.convert %[[VAL_99]] : (!fir.heap>) -> !fir.ref>, !fir.heap>>>> +! 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.heap>>>>, !fir.shape<2>, index, index) -> !fir.ref>, !fir.heap>>> +! CHECK: %[[VAL_103:.*]] = fir.load %[[VAL_6]] : !fir.ref +! 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 +! 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}>>>, i64, i64) -> !fir.ref}>> +! 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.field) -> !fir.ref> +! 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.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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_120:.*]] = fir.load %[[VAL_119]] : !fir.ref>> +! CHECK: %[[VAL_121:.*]] = fir.shape %[[VAL_114]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_122:.*]] = fir.array_load %[[VAL_120]](%[[VAL_121]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array +! 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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_126:.*]] = fir.load %[[VAL_125]] : !fir.ref>> +! CHECK: %[[VAL_127:.*]] = fir.convert %[[VAL_126]] : (!fir.heap>) -> 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>, i32) -> !fir.ref +! CHECK: %[[VAL_135:.*]] = fir.convert %[[VAL_114]] : (index) -> i64 +! CHECK: fir.store %[[VAL_135]] to %[[VAL_134]] : !fir.ref +! CHECK: %[[VAL_136:.*]] = fir.convert %[[VAL_102]] : (!fir.ref>, !fir.heap>>>) -> !fir.llvm_ptr +! CHECK: %[[VAL_137:.*]] = fir.convert %[[VAL_132]] : (!fir.heap>) -> !fir.ref +! CHECK: %[[VAL_138:.*]] = fir.call @_FortranARaggedArrayAllocate(%[[VAL_136]], %[[VAL_130]], %[[VAL_131]], %[[VAL_123]], %[[VAL_137]]) : (!fir.llvm_ptr, i1, i64, i64, !fir.ref) -> !fir.llvm_ptr +! 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) { +! 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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_149:.*]] = fir.load %[[VAL_148]] : !fir.ref>> +! 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.shape<1>, index) -> !fir.ref +! CHECK: %[[VAL_154:.*]] = fir.convert %[[VAL_146]] : (i1) -> i8 +! CHECK: fir.store %[[VAL_154]] to %[[VAL_153]] : !fir.ref +! CHECK: fir.result %[[VAL_144]] : !fir.array +! CHECK: } +! CHECK: fir.result %[[VAL_52]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_155:.*]] : !fir.array}>> +! 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}>>) { +! CHECK: %[[VAL_159:.*]] = fir.convert %[[VAL_157]] : (index) -> i32 +! CHECK: fir.store %[[VAL_159]] to %[[VAL_5]] : !fir.ref +! 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}>>) { +! CHECK: %[[VAL_163:.*]] = fir.convert %[[VAL_161]] : (index) -> i32 +! CHECK: fir.store %[[VAL_163]] to %[[VAL_4]] : !fir.ref +! 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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_192:.*]] = fir.load %[[VAL_191]] : !fir.ref>> +! CHECK: %[[VAL_193:.*]] = fir.convert %[[VAL_192]] : (!fir.heap>) -> !fir.ref>, !fir.heap>>>> +! 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.heap>>>>, !fir.shape<2>, index, index) -> !fir.ref>, !fir.heap>>> +! CHECK: %[[VAL_196:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_197:.*]] = fir.coordinate_of %[[VAL_195]], %[[VAL_196]] : (!fir.ref>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_198:.*]] = fir.load %[[VAL_197]] : !fir.ref>> +! CHECK: %[[VAL_199:.*]] = fir.convert %[[VAL_198]] : (!fir.heap>) -> !fir.ref> +! CHECK: %[[VAL_200:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_201:.*]] = fir.coordinate_of %[[VAL_195]], %[[VAL_200]] : (!fir.ref>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_202:.*]] = fir.load %[[VAL_201]] : !fir.ref>> +! CHECK: %[[VAL_203:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_204:.*]] = fir.coordinate_of %[[VAL_202]], %[[VAL_203]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: %[[VAL_205:.*]] = fir.load %[[VAL_204]] : !fir.ref +! 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 +! 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 +! 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 +! 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 +! 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}>>) { +! 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.shape<1>, index) -> !fir.ref +! CHECK: %[[VAL_238:.*]] = fir.load %[[VAL_237]] : !fir.ref +! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_238]] : (i8) -> i1 +! CHECK: %[[VAL_240:.*]] = fir.if %[[VAL_239]] -> (!fir.array}>>) { +! CHECK: %[[VAL_241:.*]] = fir.array_fetch %[[VAL_45]], %[[VAL_222]], %[[VAL_226]], %[[VAL_227]], %[[VAL_233]] : (!fir.array}>>, 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}>>, f32, index, index, !fir.field, index) -> !fir.array}>> +! CHECK: fir.result %[[VAL_243]] : !fir.array}>> +! CHECK: } else { +! CHECK: fir.result %[[VAL_234]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_244:.*]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_245:.*]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_246:.*]] : !fir.array}>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_44]], %[[VAL_247:.*]] to %[[VAL_0]] : !fir.array}>>, !fir.array}>>, !fir.box}>>> +! CHECK: %[[VAL_248:.*]] = fir.array_load %[[VAL_0]] : (!fir.box}>>>) -> !fir.array}>> +! CHECK: %[[VAL_249:.*]] = fir.array_load %[[VAL_1]] : (!fir.box}>>>) -> !fir.array}>> +! 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}>>) { +! CHECK: %[[VAL_253:.*]] = fir.convert %[[VAL_251]] : (index) -> i32 +! CHECK: fir.store %[[VAL_253]] to %[[VAL_3]] : !fir.ref +! 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}>>) { +! CHECK: %[[VAL_257:.*]] = fir.convert %[[VAL_255]] : (index) -> i32 +! CHECK: fir.store %[[VAL_257]] to %[[VAL_2]] : !fir.ref +! 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>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_286:.*]] = fir.load %[[VAL_285]] : !fir.ref>> +! CHECK: %[[VAL_287:.*]] = fir.convert %[[VAL_286]] : (!fir.heap>) -> !fir.ref>, !fir.heap>>>> +! 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.heap>>>>, !fir.shape<2>, index, index) -> !fir.ref>, !fir.heap>>> +! CHECK: %[[VAL_290:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_291:.*]] = fir.coordinate_of %[[VAL_289]], %[[VAL_290]] : (!fir.ref>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_292:.*]] = fir.load %[[VAL_291]] : !fir.ref>> +! CHECK: %[[VAL_293:.*]] = fir.convert %[[VAL_292]] : (!fir.heap>) -> !fir.ref> +! CHECK: %[[VAL_294:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_295:.*]] = fir.coordinate_of %[[VAL_289]], %[[VAL_294]] : (!fir.ref>, !fir.heap>>>, i32) -> !fir.ref>> +! CHECK: %[[VAL_296:.*]] = fir.load %[[VAL_295]] : !fir.ref>> +! CHECK: %[[VAL_297:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_298:.*]] = fir.coordinate_of %[[VAL_296]], %[[VAL_297]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: %[[VAL_299:.*]] = fir.load %[[VAL_298]] : !fir.ref +! 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 +! 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 +! 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 +! 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 +! 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}>>) { +! 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.shape<1>, index) -> !fir.ref +! CHECK: %[[VAL_331:.*]] = fir.load %[[VAL_330]] : !fir.ref +! CHECK: %[[VAL_332:.*]] = fir.convert %[[VAL_331]] : (i8) -> i1 +! CHECK: %[[VAL_333:.*]] = fir.if %[[VAL_332]] -> (!fir.array}>>) { +! CHECK: fir.result %[[VAL_327]] : !fir.array}>> +! CHECK: } else { +! CHECK: %[[VAL_334:.*]] = fir.array_fetch %[[VAL_249]], %[[VAL_316]], %[[VAL_320]], %[[VAL_321]], %[[VAL_326]] : (!fir.array}>>, 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}>>, f32, index, index, !fir.field, index) -> !fir.array}>> +! CHECK: fir.result %[[VAL_336]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_337:.*]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_338:.*]] : !fir.array}>> +! CHECK: } +! CHECK: fir.result %[[VAL_339:.*]] : !fir.array}>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_248]], %[[VAL_340:.*]] to %[[VAL_0]] : !fir.array}>>, !fir.array}>>, !fir.box}>>> +! CHECK: %[[VAL_341:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>, !fir.heap>>>) -> !fir.llvm_ptr +! CHECK: %[[VAL_342:.*]] = fir.call @_FortranARaggedArrayDeallocate(%[[VAL_341]]) : (!fir.llvm_ptr) -> none +! CHECK: return +! CHECK: } diff --git a/flang/test/Lower/forall/test9.f90 b/flang/test/Lower/forall/test9.f90 new file mode 100644 --- /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>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} +! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_2]] : !fir.ref +! 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 +! 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 +! 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.shape<1>) -> !fir.array +! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_0]](%[[VAL_19]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array +! CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_9]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_22:.*]] = fir.array_load %[[VAL_1]](%[[VAL_21]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array +! 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) { +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32 +! CHECK: fir.store %[[VAL_26]] to %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_3]] : !fir.ref +! 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 +! 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, index) -> f32 +! CHECK: %[[VAL_38:.*]] = fir.array_fetch %[[VAL_22]], %[[VAL_36]] : (!fir.array, 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 +! 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, f32, index) -> !fir.array +! CHECK: fir.result %[[VAL_47]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_18]], %[[VAL_48:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.ref> +! CHECK: return +! CHECK: }