diff --git a/flang/test/Lower/allocatable-globals.f90 b/flang/test/Lower/allocatable-globals.f90 index 6f0d227f47cf4..9d386688f8881 100644 --- a/flang/test/Lower/allocatable-globals.f90 +++ b/flang/test/Lower/allocatable-globals.f90 @@ -10,63 +10,63 @@ ! CHECK: fir.has_value %[[modcInitBox]] : !fir.box>>> module mod_allocatables - character(10), allocatable :: c(:) - end module + character(10), allocatable :: c(:) +end module - ! CHECK-LABEL: func @_QPtest_mod_allocatables() - subroutine test_mod_allocatables() - use mod_allocatables, only: c - ! CHECK: fir.address_of(@_QMmod_allocatablesEc) : !fir.ref>>>> - call bar(c(1)) - end subroutine - - - ! CHECK-LABEL: func @_QPtest_globals() - subroutine test_globals() - integer, allocatable :: gx, gy(:, :) - save :: gx, gy - ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgx) : !fir.ref>> - ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgy) : !fir.ref>>> - character(:), allocatable :: gc1, gc2(:, :) - character(10), allocatable :: gc3, gc4(:, :) - save :: gc1, gc2, gc3, gc4 - ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc1) : !fir.ref>>> - ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc2) : !fir.ref>>>> - ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc3) : !fir.ref>>> - ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc4) : !fir.ref>>>> - allocate(gx, gy(20, 30), gc3, gc4(40, 50)) - allocate(character(15):: gc1, gc2(60, 70)) - end subroutine - - ! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc1 : !fir.box>> - ! CHECK-DAG: %[[gc1NullAddr:.*]] = fir.zero_bits !fir.heap> - ! CHECK: %[[gc1InitBox:.*]] = fir.embox %[[gc1NullAddr]] typeparams %c0{{.*}} : (!fir.heap>, index) -> !fir.box>> - ! CHECK: fir.has_value %[[gc1InitBox]] : !fir.box>> - - ! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc2 : !fir.box>>> - ! CHECK-DAG: %[[gc2NullAddr:.*]] = fir.zero_bits !fir.heap>> - ! CHECK-DAG: %[[gc2NullShape:.*]] = fir.shape %c0{{.*}}, %c0{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[gc2InitBox:.*]] = fir.embox %[[gc2NullAddr]](%[[gc2NullShape]]) typeparams %c0{{.*}} : (!fir.heap>>, !fir.shape<2>, index) -> !fir.box>>> - ! CHECK: fir.has_value %[[gc2InitBox]] : !fir.box>>> - - ! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc3 : !fir.box>> - ! CHECK-DAG: %[[gc3NullAddr:.*]] = fir.zero_bits !fir.heap> - ! CHECK: %[[gc3InitBox:.*]] = fir.embox %[[gc3NullAddr]] : (!fir.heap>) -> !fir.box>> - ! CHECK: fir.has_value %[[gc3InitBox]] : !fir.box>> - - ! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc4 : !fir.box>>> - ! CHECK-DAG: %[[gc4NullAddr:.*]] = fir.zero_bits !fir.heap>> - ! CHECK-DAG: %[[gc4NullShape:.*]] = fir.shape %c0{{.*}}, %c0{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[gc4InitBox:.*]] = fir.embox %[[gc4NullAddr]](%[[gc4NullShape]]) : (!fir.heap>>, !fir.shape<2>) -> !fir.box>>> - ! CHECK: fir.has_value %[[gc4InitBox]] : !fir.box>>> - - ! CHECK-LABEL: fir.global internal @_QFtest_globalsEgx : !fir.box> - ! CHECK: %[[gxNullAddr:.*]] = fir.zero_bits !fir.heap - ! CHECK: %[[gxInitBox:.*]] = fir.embox %0 : (!fir.heap) -> !fir.box> - ! CHECK: fir.has_value %[[gxInitBox]] : !fir.box> - - ! CHECK-LABEL: fir.global internal @_QFtest_globalsEgy : !fir.box>> { - ! CHECK-DAG: %[[gyNullAddr:.*]] = fir.zero_bits !fir.heap> - ! CHECK-DAG: %[[gyShape:.*]] = fir.shape %c0{{.*}}, %c0{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[gyInitBox:.*]] = fir.embox %[[gyNullAddr]](%[[gyShape]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> - ! CHECK: fir.has_value %[[gyInitBox]] : !fir.box>> +! CHECK-LABEL: func @_QPtest_mod_allocatables() +subroutine test_mod_allocatables() + use mod_allocatables, only: c + ! CHECK: fir.address_of(@_QMmod_allocatablesEc) : !fir.ref>>>> + call bar(c(1)) +end subroutine + + +! CHECK-LABEL: func @_QPtest_globals() +subroutine test_globals() + integer, allocatable :: gx, gy(:, :) + save :: gx, gy + ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgx) : !fir.ref>> + ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgy) : !fir.ref>>> + character(:), allocatable :: gc1, gc2(:, :) + character(10), allocatable :: gc3, gc4(:, :) + save :: gc1, gc2, gc3, gc4 + ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc1) : !fir.ref>>> + ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc2) : !fir.ref>>>> + ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc3) : !fir.ref>>> + ! CHECK-DAG: fir.address_of(@_QFtest_globalsEgc4) : !fir.ref>>>> + allocate(gx, gy(20, 30), gc3, gc4(40, 50)) + allocate(character(15):: gc1, gc2(60, 70)) +end subroutine + +! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc1 : !fir.box>> + ! CHECK-DAG: %[[gc1NullAddr:.*]] = fir.zero_bits !fir.heap> + ! CHECK: %[[gc1InitBox:.*]] = fir.embox %[[gc1NullAddr]] typeparams %c0{{.*}} : (!fir.heap>, index) -> !fir.box>> + ! CHECK: fir.has_value %[[gc1InitBox]] : !fir.box>> + +! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc2 : !fir.box>>> + ! CHECK-DAG: %[[gc2NullAddr:.*]] = fir.zero_bits !fir.heap>> + ! CHECK-DAG: %[[gc2NullShape:.*]] = fir.shape %c0{{.*}}, %c0{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[gc2InitBox:.*]] = fir.embox %[[gc2NullAddr]](%[[gc2NullShape]]) typeparams %c0{{.*}} : (!fir.heap>>, !fir.shape<2>, index) -> !fir.box>>> + ! CHECK: fir.has_value %[[gc2InitBox]] : !fir.box>>> + +! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc3 : !fir.box>> + ! CHECK-DAG: %[[gc3NullAddr:.*]] = fir.zero_bits !fir.heap> + ! CHECK: %[[gc3InitBox:.*]] = fir.embox %[[gc3NullAddr]] : (!fir.heap>) -> !fir.box>> + ! CHECK: fir.has_value %[[gc3InitBox]] : !fir.box>> + +! CHECK-LABEL: fir.global internal @_QFtest_globalsEgc4 : !fir.box>>> + ! CHECK-DAG: %[[gc4NullAddr:.*]] = fir.zero_bits !fir.heap>> + ! CHECK-DAG: %[[gc4NullShape:.*]] = fir.shape %c0{{.*}}, %c0{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[gc4InitBox:.*]] = fir.embox %[[gc4NullAddr]](%[[gc4NullShape]]) : (!fir.heap>>, !fir.shape<2>) -> !fir.box>>> + ! CHECK: fir.has_value %[[gc4InitBox]] : !fir.box>>> + +! CHECK-LABEL: fir.global internal @_QFtest_globalsEgx : !fir.box> + ! CHECK: %[[gxNullAddr:.*]] = fir.zero_bits !fir.heap + ! CHECK: %[[gxInitBox:.*]] = fir.embox %0 : (!fir.heap) -> !fir.box> + ! CHECK: fir.has_value %[[gxInitBox]] : !fir.box> + +! CHECK-LABEL: fir.global internal @_QFtest_globalsEgy : !fir.box>> { + ! CHECK-DAG: %[[gyNullAddr:.*]] = fir.zero_bits !fir.heap> + ! CHECK-DAG: %[[gyShape:.*]] = fir.shape %c0{{.*}}, %c0{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[gyInitBox:.*]] = fir.embox %[[gyNullAddr]](%[[gyShape]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> + ! CHECK: fir.has_value %[[gyInitBox]] : !fir.box>> diff --git a/flang/test/Lower/alternate-return.f90 b/flang/test/Lower/alternate-return.f90 index c13c37796229b..15934e242adcd 100644 --- a/flang/test/Lower/alternate-return.f90 +++ b/flang/test/Lower/alternate-return.f90 @@ -2,48 +2,48 @@ ! CHECK-LABEL: func @_QPss subroutine ss(n) - print*, n - ! CHECK: return{{$}} - return - ! CHECK-LABEL: func @_QPee - entry ee(n,*) - print*, n - ! CHECK: return %{{.}} : index - return 1 - end - - ! CHECK-LABEL: func @_QQmain - call ss(7) - call ee(2, *3) - print*, 'default' - 3 print*, 3 - - print*, k(10,20) - print*, k(15,15) - print*, k(20,10) - end - - ! CHECK-LABEL: func @_QPk - function k(n1, n2) - ! CHECK-NOT: ^bb - ! CHECK: [[selector:%[0-9]+]] = fir.call @_QPs - ! CHECK-NEXT: fir.select [[selector]] : index [1, ^[[block1:bb[0-9]+]], 2, ^[[block2:bb[0-9]+]], unit, ^[[blockunit:bb[0-9]+]] - call s(n1, *5, n2, *7) - ! CHECK: ^[[blockunit]]: // pred: ^bb0 - k = 0; return; - ! CHECK: ^[[block1]]: // pred: ^bb0 - 5 k = -1; return; - ! CHECK: ^[[block2]]: // pred: ^bb0 - 7 k = 1; return - end - - ! CHECK-LABEL: func @_QPs - subroutine s(n1, *, n2, *) - ! CHECK: [[retval:%[0-9]+]] = fir.alloca index {{{.*}}bindc_name = "s"} - ! CHECK-COUNT-3: fir.store {{.*}} to [[retval]] : !fir.ref - if (n1 < n2) return 1 - if (n1 > n2) return 2 - ! CHECK: {{.*}} = fir.load [[retval]] : !fir.ref - ! CHECK-NEXT: return {{.*}} : index - return - end + print*, n + ! CHECK: return{{$}} + return +! CHECK-LABEL: func @_QPee +entry ee(n,*) + print*, n + ! CHECK: return %{{.}} : index + return 1 +end + +! CHECK-LABEL: func @_QQmain + call ss(7) + call ee(2, *3) + print*, 'default' +3 print*, 3 + + print*, k(10,20) + print*, k(15,15) + print*, k(20,10) +end + +! CHECK-LABEL: func @_QPk +function k(n1, n2) + ! CHECK-NOT: ^bb + ! CHECK: [[selector:%[0-9]+]] = fir.call @_QPs + ! CHECK-NEXT: fir.select [[selector]] : index [1, ^[[block1:bb[0-9]+]], 2, ^[[block2:bb[0-9]+]], unit, ^[[blockunit:bb[0-9]+]] + call s(n1, *5, n2, *7) + ! CHECK: ^[[blockunit]]: // pred: ^bb0 + k = 0; return; + ! CHECK: ^[[block1]]: // pred: ^bb0 +5 k = -1; return; + ! CHECK: ^[[block2]]: // pred: ^bb0 +7 k = 1; return +end + +! CHECK-LABEL: func @_QPs +subroutine s(n1, *, n2, *) + ! CHECK: [[retval:%[0-9]+]] = fir.alloca index {{{.*}}bindc_name = "s"} + ! CHECK-COUNT-3: fir.store {{.*}} to [[retval]] : !fir.ref + if (n1 < n2) return 1 + if (n1 > n2) return 2 + ! CHECK: {{.*}} = fir.load [[retval]] : !fir.ref + ! CHECK-NEXT: return {{.*}} : index + return +end diff --git a/flang/test/Lower/arithmetic-goto.f90 b/flang/test/Lower/arithmetic-goto.f90 index dd356e1f979f2..6cb98a658b119 100644 --- a/flang/test/Lower/arithmetic-goto.f90 +++ b/flang/test/Lower/arithmetic-goto.f90 @@ -2,36 +2,36 @@ ! CHECK-LABEL: func @_QPkagi function kagi(index) - ! CHECK: fir.select_case %{{.}} : i32 [#fir.upper, %c-1_i32, ^bb{{.}}, #fir.lower, %c1_i32, ^bb{{.}}, unit, ^bb{{.}}] - if (index) 7, 8, 9 - kagi = 0; return - 7 kagi = 1; return - 8 kagi = 2; return - 9 kagi = 3; return - end - - ! CHECK-LABEL: func @_QPkagf - function kagf(findex) - ! CHECK: %[[zero:.+]] = arith.constant 0.0 - ! CHECK: %{{.+}} = arith.cmpf olt, %{{.+}}, %[[zero]] : f32 - ! CHECK: cond_br % - ! CHECK: %{{.+}} = arith.cmpf ogt, %{{.+}}, %[[zero]] : f32 - ! CHECK: cond_br % - ! CHECK: br ^ - if (findex+findex) 7, 8, 9 - kagf = 0; return - 7 kagf = 1; return - 8 kagf = 2; return - 9 kagf = 3; return - end - - ! CHECK-LABEL: func @_QQmain - - print*, kagf(-2.0) - print*, kagf(-1.0) - print*, kagf(-0.0) - print*, kagf( 0.0) - print*, kagf(+0.0) - print*, kagf(+1.0) - print*, kagf(+2.0) - end + ! CHECK: fir.select_case %{{.}} : i32 [#fir.upper, %c-1_i32, ^bb{{.}}, #fir.lower, %c1_i32, ^bb{{.}}, unit, ^bb{{.}}] + if (index) 7, 8, 9 + kagi = 0; return +7 kagi = 1; return +8 kagi = 2; return +9 kagi = 3; return +end + +! CHECK-LABEL: func @_QPkagf +function kagf(findex) + ! CHECK: %[[zero:.+]] = arith.constant 0.0 + ! CHECK: %{{.+}} = arith.cmpf olt, %{{.+}}, %[[zero]] : f32 + ! CHECK: cond_br % + ! CHECK: %{{.+}} = arith.cmpf ogt, %{{.+}}, %[[zero]] : f32 + ! CHECK: cond_br % + ! CHECK: br ^ + if (findex+findex) 7, 8, 9 + kagf = 0; return +7 kagf = 1; return +8 kagf = 2; return +9 kagf = 3; return +end + +! CHECK-LABEL: func @_QQmain + + print*, kagf(-2.0) + print*, kagf(-1.0) + print*, kagf(-0.0) + print*, kagf( 0.0) + print*, kagf(+0.0) + print*, kagf(+1.0) + print*, kagf(+2.0) +end diff --git a/flang/test/Lower/array-character.f90 b/flang/test/Lower/array-character.f90 index d62c804ff1836..22ca5f8884fb7 100644 --- a/flang/test/Lower/array-character.f90 +++ b/flang/test/Lower/array-character.f90 @@ -3,171 +3,171 @@ ! CHECK-LABEL: func @_QPissue( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { subroutine issue(c1, c2) - ! CHECK-DAG: %[[VAL_2:.*]] = arith.constant false - ! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 32 : i8 - ! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_7:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_8:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_10:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: cf.br ^bb1(%[[VAL_6]], %[[VAL_4]] : index, index) - ! CHECK: ^bb1(%[[VAL_13:.*]]: index, %[[VAL_14:.*]]: index): - ! CHECK: %[[VAL_15:.*]] = arith.cmpi sgt, %[[VAL_14]], %[[VAL_6]] : index - ! CHECK: cf.cond_br %[[VAL_15]], ^bb2, ^bb6 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_13]], %[[VAL_7]] : index - ! CHECK: %[[VAL_17:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_16]] typeparams %[[VAL_10]]#1 : (!fir.ref>>, !fir.shape<1>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_18:.*]] = fir.array_coor %[[VAL_9]](%[[VAL_12]]) %[[VAL_16]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_19:.*]] = arith.cmpi slt, %[[VAL_5]], %[[VAL_10]]#1 : index - ! CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_19]], %[[VAL_5]], %[[VAL_10]]#1 : index - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (index) -> i64 - ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_17]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_22]], %[[VAL_23]], %[[VAL_21]], %[[VAL_2]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_24:.*]] = fir.undefined !fir.char<1> - ! CHECK: %[[VAL_25:.*]] = fir.insert_value %[[VAL_24]], %[[VAL_3]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> - ! CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_5]], %[[VAL_20]] : index - ! CHECK: cf.br ^bb3(%[[VAL_20]], %[[VAL_26]] : index, index) - ! CHECK: ^bb3(%[[VAL_27:.*]]: index, %[[VAL_28:.*]]: index): - ! CHECK: %[[VAL_29:.*]] = arith.cmpi sgt, %[[VAL_28]], %[[VAL_6]] : index - ! CHECK: cf.cond_br %[[VAL_29]], ^bb4, ^bb5 - ! CHECK: ^bb4: - ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_31:.*]] = fir.coordinate_of %[[VAL_30]], %[[VAL_27]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_25]] to %[[VAL_31]] : !fir.ref> - ! CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_27]], %[[VAL_7]] : index - ! CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_28]], %[[VAL_7]] : index - ! CHECK: cf.br ^bb3(%[[VAL_32]], %[[VAL_33]] : index, index) - ! CHECK: ^bb5: + ! CHECK-DAG: %[[VAL_2:.*]] = arith.constant false + ! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 32 : i8 + ! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 3 : index + ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 4 : index + ! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 0 : index + ! CHECK-DAG: %[[VAL_7:.*]] = arith.constant 1 : index + ! CHECK: %[[VAL_8:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) + ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]]#0 : (!fir.ref>) -> !fir.ref>> + ! CHECK: %[[VAL_10:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) + ! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]]#0 : (!fir.ref>) -> !fir.ref>> + ! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> + ! CHECK: cf.br ^bb1(%[[VAL_6]], %[[VAL_4]] : index, index) + ! CHECK: ^bb1(%[[VAL_13:.*]]: index, %[[VAL_14:.*]]: index): + ! CHECK: %[[VAL_15:.*]] = arith.cmpi sgt, %[[VAL_14]], %[[VAL_6]] : index + ! CHECK: cf.cond_br %[[VAL_15]], ^bb2, ^bb6 + ! CHECK: ^bb2: + ! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_13]], %[[VAL_7]] : index + ! CHECK: %[[VAL_17:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_16]] typeparams %[[VAL_10]]#1 : (!fir.ref>>, !fir.shape<1>, index, index) -> !fir.ref> + ! CHECK: %[[VAL_18:.*]] = fir.array_coor %[[VAL_9]](%[[VAL_12]]) %[[VAL_16]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_19:.*]] = arith.cmpi slt, %[[VAL_5]], %[[VAL_10]]#1 : index + ! CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_19]], %[[VAL_5]], %[[VAL_10]]#1 : index + ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (index) -> i64 + ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_17]] : (!fir.ref>) -> !fir.ref + ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_22]], %[[VAL_23]], %[[VAL_21]], %[[VAL_2]]) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: %[[VAL_24:.*]] = fir.undefined !fir.char<1> + ! CHECK: %[[VAL_25:.*]] = fir.insert_value %[[VAL_24]], %[[VAL_3]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> + ! CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_5]], %[[VAL_20]] : index + ! CHECK: cf.br ^bb3(%[[VAL_20]], %[[VAL_26]] : index, index) + ! CHECK: ^bb3(%[[VAL_27:.*]]: index, %[[VAL_28:.*]]: index): + ! CHECK: %[[VAL_29:.*]] = arith.cmpi sgt, %[[VAL_28]], %[[VAL_6]] : index + ! CHECK: cf.cond_br %[[VAL_29]], ^bb4, ^bb5 + ! CHECK: ^bb4: + ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref>> + ! CHECK: %[[VAL_31:.*]] = fir.coordinate_of %[[VAL_30]], %[[VAL_27]] : (!fir.ref>>, index) -> !fir.ref> + ! CHECK: fir.store %[[VAL_25]] to %[[VAL_31]] : !fir.ref> + ! CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_27]], %[[VAL_7]] : index + ! CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_28]], %[[VAL_7]] : index + ! CHECK: cf.br ^bb3(%[[VAL_32]], %[[VAL_33]] : index, index) + ! CHECK: ^bb5: - character(4) :: c1(3) - character(*) :: c2(3) - c1 = c2 - ! CHECK: return - ! CHECK: } - end subroutine - - ! CHECK-LABEL: func @_QQmain() { + character(4) :: c1(3) + character(*) :: c2(3) + c1 = c2 + ! CHECK: return + ! CHECK: } +end subroutine + +! CHECK-LABEL: func @_QQmain() { program p - ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_1:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_2:.*]] = arith.constant -1 : i32 - ! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QFEc1) : !fir.ref>> - ! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFEc2) : !fir.ref>> - ! CHECK: %[[VAL_7:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_2]], %[[VAL_8]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_6]](%[[VAL_10]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> - ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_9]], %[[VAL_12]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_9]]) : (!fir.ref) -> i32 - ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>>) -> !fir.ref> - ! CHECK: %[[VAL_16:.*]] = fir.emboxchar %[[VAL_15]], %[[VAL_0]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>) -> !fir.ref> - ! CHECK: %[[VAL_18:.*]] = fir.emboxchar %[[VAL_17]], %[[VAL_0]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPissue(%[[VAL_16]], %[[VAL_18]]) : (!fir.boxchar<1>, !fir.boxchar<1>) -> () - ! CHECK: %[[VAL_19:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_2]], %[[VAL_8]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_5]](%[[VAL_10]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_19]], %[[VAL_21]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: %[[VAL_23:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_19]]) : (!fir.ref) -> i32 - ! CHECK: fir.call @_QPcharlit() : () -> () - character(4) :: c1(3) - character(4) :: c2(3) = ["abcd", " ", " "] - print *, c2 - call issue(c1, c2) - print *, c1 - call charlit - ! CHECK: return - ! CHECK: } - end program p + ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 4 : index + ! CHECK-DAG: %[[VAL_1:.*]] = arith.constant 3 : index + ! CHECK-DAG: %[[VAL_2:.*]] = arith.constant -1 : i32 + ! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QFEc1) : !fir.ref>> + ! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFEc2) : !fir.ref>> + ! CHECK: %[[VAL_7:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_2]], %[[VAL_8]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref + ! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_6]](%[[VAL_10]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_9]], %[[VAL_12]]) : (!fir.ref, !fir.box) -> i1 + ! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_9]]) : (!fir.ref) -> i32 + ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>>) -> !fir.ref> + ! CHECK: %[[VAL_16:.*]] = fir.emboxchar %[[VAL_15]], %[[VAL_0]] : (!fir.ref>, index) -> !fir.boxchar<1> + ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>) -> !fir.ref> + ! CHECK: %[[VAL_18:.*]] = fir.emboxchar %[[VAL_17]], %[[VAL_0]] : (!fir.ref>, index) -> !fir.boxchar<1> + ! CHECK: fir.call @_QPissue(%[[VAL_16]], %[[VAL_18]]) : (!fir.boxchar<1>, !fir.boxchar<1>) -> () + ! CHECK: %[[VAL_19:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_2]], %[[VAL_8]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref + ! CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_5]](%[[VAL_10]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_19]], %[[VAL_21]]) : (!fir.ref, !fir.box) -> i1 + ! CHECK: %[[VAL_23:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_19]]) : (!fir.ref) -> i32 + ! CHECK: fir.call @_QPcharlit() : () -> () + character(4) :: c1(3) + character(4) :: c2(3) = ["abcd", " ", " "] + print *, c2 + call issue(c1, c2) + print *, c1 + call charlit + ! CHECK: return + ! CHECK: } +end program p - ! CHECK-LABEL: func @_QPcharlit() { +! CHECK-LABEL: func @_QPcharlit() { subroutine charlit - ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_4:.*]] = arith.constant false - ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_7:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_8:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_11:.*]] = fir.address_of(@_QQro.4x3xc1.1636b396a657de68ffb870a885ac44b4) : !fir.ref>> - ! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_13:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> - ! CHECK: cf.br ^bb1(%[[VAL_6]], %[[VAL_5]] : index, index) - ! CHECK: ^bb1(%[[VAL_14:.*]]: index, %[[VAL_15:.*]]: index): - ! CHECK: %[[VAL_16:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_6]] : index - ! CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_14]], %[[VAL_7]] : index - ! CHECK: %[[VAL_18:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_17]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_19:.*]] = fir.array_coor %[[VAL_13]](%[[VAL_12]]) %[[VAL_17]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_3]] : (index) -> i64 - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_21]], %[[VAL_22]], %[[VAL_20]], %[[VAL_4]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_15]], %[[VAL_7]] : index - ! CHECK: cf.br ^bb1(%[[VAL_17]], %[[VAL_23]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_13]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> - ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[VAL_26:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_10]], %[[VAL_25]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_13]] - ! CHECK: %[[VAL_27:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_10]]) : (!fir.ref) -> i32 - ! CHECK: %[[VAL_28:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_29:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> - ! CHECK: br ^bb4(%[[VAL_6]], %[[VAL_5]] : index, index) - ! CHECK: ^bb4(%[[VAL_30:.*]]: index, %[[VAL_31:.*]]: index): - ! CHECK: %[[VAL_32:.*]] = arith.cmpi sgt, %[[VAL_31]], %[[VAL_6]] : index - ! CHECK: cond_br %[[VAL_32]], ^bb5, ^bb6 - ! CHECK: ^bb5: - ! CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_30]], %[[VAL_7]] : index - ! CHECK: %[[VAL_34:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_33]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_35:.*]] = fir.array_coor %[[VAL_29]](%[[VAL_12]]) %[[VAL_33]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_3]] : (index) -> i64 - ! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_37]], %[[VAL_38]], %[[VAL_36]], %[[VAL_4]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_39:.*]] = arith.subi %[[VAL_31]], %[[VAL_7]] : index - ! CHECK: br ^bb4(%[[VAL_33]], %[[VAL_39]] : index, index) - ! CHECK: ^bb6: - ! CHECK: %[[VAL_40:.*]] = fir.embox %[[VAL_29]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> - ! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[VAL_42:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_28]], %[[VAL_41]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_29]] - ! CHECK: %[[VAL_43:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_28]]) : (!fir.ref) -> i32 - ! CHECK: %[[VAL_44:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_45:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> - ! CHECK: br ^bb7(%[[VAL_6]], %[[VAL_5]] : index, index) - ! CHECK: ^bb7(%[[VAL_46:.*]]: index, %[[VAL_47:.*]]: index): - ! CHECK: %[[VAL_48:.*]] = arith.cmpi sgt, %[[VAL_47]], %[[VAL_6]] : index - ! CHECK: cond_br %[[VAL_48]], ^bb8, ^bb9 - ! CHECK: ^bb8: - ! CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_46]], %[[VAL_7]] : index - ! CHECK: %[[VAL_50:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_49]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_51:.*]] = fir.array_coor %[[VAL_45]](%[[VAL_12]]) %[[VAL_49]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_3]] : (index) -> i64 - ! CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_50]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_53]], %[[VAL_54]], %[[VAL_52]], %[[VAL_4]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_55:.*]] = arith.subi %[[VAL_47]], %[[VAL_7]] : index - ! CHECK: br ^bb7(%[[VAL_49]], %[[VAL_55]] : index, index) - ! CHECK: ^bb9: - ! CHECK: %[[VAL_56:.*]] = fir.embox %[[VAL_45]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> - ! CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_56]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[VAL_58:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_44]], %[[VAL_57]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_45]] - ! CHECK: %[[VAL_59:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_44]]) : (!fir.ref) -> i32 - print*, ['AA ', 'MM ', 'MM ', 'ZZ '] - print*, ['AA ', 'MM ', 'MM ', 'ZZ '] - print*, ['AA ', 'MM ', 'MM ', 'ZZ '] - ! CHECK: return - ! CHECK: } - end + ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant -1 : i32 + ! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 3 : index + ! CHECK-DAG: %[[VAL_4:.*]] = arith.constant false + ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 4 : index + ! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 0 : index + ! CHECK-DAG: %[[VAL_7:.*]] = arith.constant 1 : index + ! CHECK: %[[VAL_8:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref + ! CHECK: %[[VAL_11:.*]] = fir.address_of(@_QQro.4x3xc1.1636b396a657de68ffb870a885ac44b4) : !fir.ref>> + ! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_13:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> + ! CHECK: cf.br ^bb1(%[[VAL_6]], %[[VAL_5]] : index, index) + ! CHECK: ^bb1(%[[VAL_14:.*]]: index, %[[VAL_15:.*]]: index): + ! CHECK: %[[VAL_16:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_6]] : index + ! CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3 + ! CHECK: ^bb2: + ! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_14]], %[[VAL_7]] : index + ! CHECK: %[[VAL_18:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_17]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_19:.*]] = fir.array_coor %[[VAL_13]](%[[VAL_12]]) %[[VAL_17]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_3]] : (index) -> i64 + ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref + ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_21]], %[[VAL_22]], %[[VAL_20]], %[[VAL_4]]) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_15]], %[[VAL_7]] : index + ! CHECK: cf.br ^bb1(%[[VAL_17]], %[[VAL_23]] : index, index) + ! CHECK: ^bb3: + ! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_13]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_26:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_10]], %[[VAL_25]]) : (!fir.ref, !fir.box) -> i1 + ! CHECK: fir.freemem %[[VAL_13]] + ! CHECK: %[[VAL_27:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_10]]) : (!fir.ref) -> i32 + ! CHECK: %[[VAL_28:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref + ! CHECK: %[[VAL_29:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> + ! CHECK: br ^bb4(%[[VAL_6]], %[[VAL_5]] : index, index) + ! CHECK: ^bb4(%[[VAL_30:.*]]: index, %[[VAL_31:.*]]: index): + ! CHECK: %[[VAL_32:.*]] = arith.cmpi sgt, %[[VAL_31]], %[[VAL_6]] : index + ! CHECK: cond_br %[[VAL_32]], ^bb5, ^bb6 + ! CHECK: ^bb5: + ! CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_30]], %[[VAL_7]] : index + ! CHECK: %[[VAL_34:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_33]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_35:.*]] = fir.array_coor %[[VAL_29]](%[[VAL_12]]) %[[VAL_33]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_3]] : (index) -> i64 + ! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref + ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_37]], %[[VAL_38]], %[[VAL_36]], %[[VAL_4]]) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: %[[VAL_39:.*]] = arith.subi %[[VAL_31]], %[[VAL_7]] : index + ! CHECK: br ^bb4(%[[VAL_33]], %[[VAL_39]] : index, index) + ! CHECK: ^bb6: + ! CHECK: %[[VAL_40:.*]] = fir.embox %[[VAL_29]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_42:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_28]], %[[VAL_41]]) : (!fir.ref, !fir.box) -> i1 + ! CHECK: fir.freemem %[[VAL_29]] + ! CHECK: %[[VAL_43:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_28]]) : (!fir.ref) -> i32 + ! CHECK: %[[VAL_44:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref + ! CHECK: %[[VAL_45:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> + ! CHECK: br ^bb7(%[[VAL_6]], %[[VAL_5]] : index, index) + ! CHECK: ^bb7(%[[VAL_46:.*]]: index, %[[VAL_47:.*]]: index): + ! CHECK: %[[VAL_48:.*]] = arith.cmpi sgt, %[[VAL_47]], %[[VAL_6]] : index + ! CHECK: cond_br %[[VAL_48]], ^bb8, ^bb9 + ! CHECK: ^bb8: + ! CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_46]], %[[VAL_7]] : index + ! CHECK: %[[VAL_50:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_12]]) %[[VAL_49]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_51:.*]] = fir.array_coor %[[VAL_45]](%[[VAL_12]]) %[[VAL_49]] : (!fir.heap>>, !fir.shape<1>, index) -> !fir.ref> + ! CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_3]] : (index) -> i64 + ! CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_50]] : (!fir.ref>) -> !fir.ref + ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_53]], %[[VAL_54]], %[[VAL_52]], %[[VAL_4]]) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: %[[VAL_55:.*]] = arith.subi %[[VAL_47]], %[[VAL_7]] : index + ! CHECK: br ^bb7(%[[VAL_49]], %[[VAL_55]] : index, index) + ! CHECK: ^bb9: + ! CHECK: %[[VAL_56:.*]] = fir.embox %[[VAL_45]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_56]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[VAL_58:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_44]], %[[VAL_57]]) : (!fir.ref, !fir.box) -> i1 + ! CHECK: fir.freemem %[[VAL_45]] + ! CHECK: %[[VAL_59:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_44]]) : (!fir.ref) -> i32 + print*, ['AA ', 'MM ', 'MM ', 'ZZ '] + print*, ['AA ', 'MM ', 'MM ', 'ZZ '] + print*, ['AA ', 'MM ', 'MM ', 'ZZ '] + ! CHECK: return + ! CHECK: } +end diff --git a/flang/test/Lower/array-constructor-1.f90 b/flang/test/Lower/array-constructor-1.f90 index d041d67d5c26e..9a13bf33ace1d 100644 --- a/flang/test/Lower/array-constructor-1.f90 +++ b/flang/test/Lower/array-constructor-1.f90 @@ -1,46 +1,46 @@ ! RUN: bbc -o - %s | FileCheck %s module units - integer, parameter :: preconnected_unit(3) = [0, 5, 6] - contains - ! CHECK-LABEL: _QMunitsPis_preconnected_unit - logical function is_preconnected_unit(u) - ! CHECK: [[units_ssa:%[0-9]+]] = fir.address_of(@_QMunitsECpreconnected_unit) : !fir.ref> - integer :: u - integer :: i - is_preconnected_unit = .true. - !do i = lbound(preconnected_unit,1), ubound(preconnected_unit,1) - ! CHECK: fir.coordinate_of [[units_ssa]] - if (preconnected_unit(i) == u) return - !end do - is_preconnected_unit = .false. - end function - end module units - - ! CHECK-LABEL: _QPcheck_units - subroutine check_units - use units - !do i=-1,8 - if (is_preconnected_unit(i)) print*, i - !enddo - end - - ! CHECK-LABEL: _QPzero - subroutine zero - complex, parameter :: a(0) = [(((k,k=1,10),j=-2,2,-1),i=2,-2,-2)] - complex, parameter :: b(0) = [(7,i=3,-3)] - ! CHECK: fir.address_of(@_QQro.0xz4.null) : !fir.ref>> - ! CHECK-NOT: _QQro - print*, '>', a, '<' - print*, '>', b, '<' - end - - ! CHECK-LABEL: _QQmain - program prog - call check_units - call zero - end - - ! CHECK: fir.global internal @_QFzeroECa constant : !fir.array<0x!fir.complex<4>> - ! CHECK: %0 = fir.undefined !fir.array<0x!fir.complex<4>> - ! CHECK: fir.has_value %0 : !fir.array<0x!fir.complex<4>> + integer, parameter :: preconnected_unit(3) = [0, 5, 6] +contains + ! CHECK-LABEL: _QMunitsPis_preconnected_unit + logical function is_preconnected_unit(u) + ! CHECK: [[units_ssa:%[0-9]+]] = fir.address_of(@_QMunitsECpreconnected_unit) : !fir.ref> + integer :: u + integer :: i + is_preconnected_unit = .true. + !do i = lbound(preconnected_unit,1), ubound(preconnected_unit,1) + ! CHECK: fir.coordinate_of [[units_ssa]] + if (preconnected_unit(i) == u) return + !end do + is_preconnected_unit = .false. + end function +end module units + +! CHECK-LABEL: _QPcheck_units +subroutine check_units + use units + !do i=-1,8 + if (is_preconnected_unit(i)) print*, i + !enddo +end + +! CHECK-LABEL: _QPzero +subroutine zero + complex, parameter :: a(0) = [(((k,k=1,10),j=-2,2,-1),i=2,-2,-2)] + complex, parameter :: b(0) = [(7,i=3,-3)] + ! CHECK: fir.address_of(@_QQro.0xz4.null) : !fir.ref>> + ! CHECK-NOT: _QQro + print*, '>', a, '<' + print*, '>', b, '<' +end + +! CHECK-LABEL: _QQmain +program prog + call check_units + call zero +end + +! CHECK: fir.global internal @_QFzeroECa constant : !fir.array<0x!fir.complex<4>> +! CHECK: %0 = fir.undefined !fir.array<0x!fir.complex<4>> +! CHECK: fir.has_value %0 : !fir.array<0x!fir.complex<4>> diff --git a/flang/test/Lower/array-constructor-2.f90 b/flang/test/Lower/array-constructor-2.f90 index 7f404c61000da..5ea08bde1fac9 100644 --- a/flang/test/Lower/array-constructor-2.f90 +++ b/flang/test/Lower/array-constructor-2.f90 @@ -3,175 +3,175 @@ ! Constant array ctor. ! CHECK-LABEL: func @_QPtest1( subroutine test1(a, b) - real :: a(3) - integer :: b(4) - integer, parameter :: constant_array(4) = [6, 7, 42, 9] - - ! Array ctors for constant arrays should be outlined as constant globals. - - ! Look at inline constructor case - ! CHECK: %{{.*}} = fir.address_of(@_QQro.3xr4.6e55f044605a4991f15fd4505d83faf4) : !fir.ref> - a = (/ 1.0, 2.0, 3.0 /) - - ! Look at PARAMETER case - ! CHECK: %{{.*}} = fir.address_of(@_QQro.4xi4.6a6af0eea868c84da59807d34f7e1a86) : !fir.ref> - b = constant_array - end subroutine test1 - - ! Dynamic array ctor with constant extent. - ! CHECK-LABEL: func @_QPtest2( - ! CHECK-SAME: %[[a:[^:]*]]: !fir.ref>{{.*}}, %[[b:[^:]*]]: !fir.ref{{.*}}) - subroutine test2(a, b) - real :: a(5), b - real, external :: f - - ! Look for the 5 store patterns - ! CHECK: %[[tmp:.*]] = fir.allocmem !fir.array<5xf32> - ! CHECK: %[[val:.*]] = fir.call @_QPf(%[[b]]) : (!fir.ref) -> f32 - ! CHECK: %[[loc:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>, index) -> !fir.ref - ! CHECK: fir.store %[[val]] to %[[loc]] : !fir.ref - ! CHECK: fir.call @_QPf(%{{.*}}) : (!fir.ref) -> f32 - ! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>, index) -> !fir.ref - ! CHECK: fir.store - ! CHECK: fir.call @_QPf( - ! CHECK: fir.coordinate_of % - ! CHECK: fir.store - ! CHECK: fir.call @_QPf( - ! CHECK: fir.coordinate_of % - ! CHECK: fir.store - ! CHECK: fir.call @_QPf( - ! CHECK: fir.coordinate_of % - ! CHECK: fir.store - - ! After the ctor done, loop to copy result to `a` - ! CHECK-DAG: fir.array_coor %[[tmp:.*]](% - ! CHECK-DAG: %[[ai:.*]] = fir.array_coor %[[a]](% - ! CHECK: fir.store %{{.*}} to %[[ai]] : !fir.ref - ! CHECK: fir.freemem %[[tmp]] - - a = [f(b), f(b+1), f(b+2), f(b+5), f(b+11)] - end subroutine test2 - - ! Dynamic array ctor with dynamic extent. - ! CHECK-LABEL: func @_QPtest3( - ! CHECK-SAME: %[[a:.*]]: !fir.box>{{.*}}) - subroutine test3(a) - real :: a(:) - real, allocatable :: b(:), c(:) - interface - subroutine test3b(x) - real, allocatable :: x(:) - end subroutine test3b - end interface - interface - function test3c - real, allocatable :: test3c(:) - end function test3c - end interface - - ! CHECK: fir.call @_QPtest3b - ! CHECK: %{{.*}}:3 = fir.box_dims %{{.*}}, %{{.*}} : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %{{.*}} = fir.box_addr %{{.*}} : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[tmp:.*]] = fir.allocmem f32, %c32 - call test3b(b) - ! CHECK: %[[hp1:.*]] = fir.allocmem !fir.array, %{{.*}} {uniq_name = ".array.expr"} - ! CHECK-DAG: %[[rep:.*]] = fir.convert %{{.*}} : (!fir.heap) -> !fir.ref - ! CHECK-DAG: %[[res:.*]] = fir.convert %{{.*}} : (index) -> i64 - ! CHECK: %{{.*}} = fir.call @realloc(%[[rep]], %[[res]]) : (!fir.ref, i64) -> !fir.ref - ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: fir.call @_QPtest3c - ! CHECK: fir.save_result - ! CHECK: %[[tmp2:.*]] = fir.allocmem !fir.array, %{{.*}}#1 {uniq_name = ".array.expr"} - ! CHECK: fir.call @realloc - ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(% - ! CHECK: fir.array_coor %[[tmp:.*]](%{{.*}}) %{{.*}} : (!fir.heap>, !fir.shape<1>, index) -> !fir.ref - ! CHECK-NEXT: fir.load - ! CHECK-NEXT: fir.array_coor %arg0 %{{.*}} : (!fir.box>, index) -> !fir.ref - ! CHECK-NEXT: fir.store - ! CHECK: fir.freemem %[[tmp]] - ! CHECK: fir.freemem %[[tmp2]] - ! CHECK: %[[alli:.*]] = fir.box_addr %{{.*}} : (!fir.box>>) -> !fir.heap> - ! CHECK: fir.freemem %[[alli]] - ! CHECK: fir.freemem %[[hp1]] - a = (/ b, test3c() /) - end subroutine test3 - - ! CHECK-LABEL: func @_QPtest4( - subroutine test4(a, b, n1, m1) - real :: a(:) - real :: b(:,:) - integer, external :: f1, f2, f3 - - ! Dynamic array ctor with dynamic extent using implied do loops. - ! CHECK-DAG: fir.alloca index {bindc_name = ".buff.pos"} - ! CHECK-DAG: fir.alloca index {bindc_name = ".buff.size"} - ! CHECK-DAG: %[[c32:.*]] = arith.constant 32 : index - ! CHECK: fir.allocmem f32, %[[c32]] - ! CHECK: fir.call @_QPf1(%{{.*}}) : (!fir.ref) -> i32 - ! CHECK: fir.call @_QPf2(%arg2) : (!fir.ref) -> i32 - ! CHECK: fir.call @_QPf3(%{{.*}}) : (!fir.ref) -> i32 - ! CHECK: %[[q:.*]] = fir.coordinate_of %arg1, %{{.*}}, %{{.*}} : (!fir.box>, i64, i64) -> !fir.ref - ! CHECK: %[[q2:.*]] = fir.load %[[q]] : !fir.ref - ! CHECK: fir.store %[[q2]] to %{{.*}} : !fir.ref - ! CHECK: fir.freemem %{{.*}} - ! CHECK-NEXT: return - a = [ ((b(i,j), j=f1(i),f2(n1),f3(m1+i)), i=1,n1,m1) ] - end subroutine test4 - - ! CHECK-LABEL: func @_QPtest5( - ! CHECK-SAME: %[[a:[^:]*]]: !fir.box>{{.*}}, %[[array2:[^:]*]]: !fir.ref>{{.*}}) - subroutine test5(a, array2) - real :: a(:) - real, parameter :: const_array1(2) = [ 1.0, 2.0 ] - real :: array2(2) - - ! Array ctor with runtime element values and constant extents. - ! Concatenation of array values of constant extent. - ! CHECK: %[[res:.*]] = fir.allocmem !fir.array<4xf32> - ! CHECK: fir.address_of(@_QQro.2xr4.057a7f5ab69cb695657046b18832c330) : !fir.ref> - ! CHECK: %[[tmp1:.*]] = fir.allocmem !fir.array<2xf32> - ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[tmp2:.*]] = fir.allocmem !fir.array<2xf32> - ! CHECK: = fir.array_coor %[[array2]](%{{.*}}) %{{.*}} : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref - ! CHECK: = fir.array_coor %[[tmp2]](%{{.*}}) %{{.*}} : (!fir.heap>, !fir.shape<1>, index) -> !fir.ref - ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: = fir.array_coor %{{.*}}(%{{.*}}) %{{.*}} : (!fir.heap>, !fir.shape<1>, index) -> !fir.ref - ! CHECK: = fir.array_coor %[[a]] %{{.*}} : (!fir.box>, index) -> !fir.ref - ! CHECK-DAG: fir.freemem %{{.*}} - ! CHECK-DAG: fir.freemem %[[tmp2]] - ! CHECK-DAG: fir.freemem %[[tmp1]] - ! CHECK: return - a = [ const_array1, array2 ] - end subroutine test5 - - ! CHECK-LABEL: func @_QPtest6( - subroutine test6(c, d, e) - character(5) :: c(3) - character(5) :: d, e - ! CHECK: = fir.allocmem !fir.array<2x!fir.char<1,5>> - ! CHECK: fir.call @realloc - ! CHECK: %[[t:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>>, index) -> !fir.ref> - ! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%[[to]], %{{.*}}, %{{.*}}, %false) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: fir.call @realloc - ! CHECK: %[[t:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>>, index) -> !fir.ref> - ! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%[[to]], %{{.*}}, %{{.*}}, %false) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: fir.freemem %{{.*}} - c = (/ d, e /) - end subroutine test6 - - ! CHECK-LABEL: func @_QPtest7( - ! CHECK: %[[i:.*]] = fir.convert %{{.*}} : (index) -> i8 - ! CHECK: %[[und:.*]] = fir.undefined !fir.char<1> - ! CHECK: %[[scalar:.*]] = fir.insert_value %[[und]], %[[i]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> - ! CHECK: ^bb{{[0-9]+}}(%{{.*}}: !fir.heap>): // 2 preds - ! CHECK: fir.store %[[scalar]] to %{{.*}} : !fir.ref> - subroutine test7(a, n) - character(1) :: a(n) - a = (/ (CHAR(i), i=1,n) /) - end subroutine test7 - - ! CHECK: fir.global internal @_QQro.3xr4.{{.*}}(dense<[1.000000e+00, 2.000000e+00, 3.000000e+00]> : tensor<3xf32>) constant : !fir.array<3xf32> - - ! CHECK: fir.global internal @_QQro.4xi4.{{.*}}(dense<[6, 7, 42, 9]> : tensor<4xi32>) constant : !fir.array<4xi32> + real :: a(3) + integer :: b(4) + integer, parameter :: constant_array(4) = [6, 7, 42, 9] + + ! Array ctors for constant arrays should be outlined as constant globals. + + ! Look at inline constructor case + ! CHECK: %{{.*}} = fir.address_of(@_QQro.3xr4.6e55f044605a4991f15fd4505d83faf4) : !fir.ref> + a = (/ 1.0, 2.0, 3.0 /) + + ! Look at PARAMETER case + ! CHECK: %{{.*}} = fir.address_of(@_QQro.4xi4.6a6af0eea868c84da59807d34f7e1a86) : !fir.ref> + b = constant_array +end subroutine test1 + +! Dynamic array ctor with constant extent. +! CHECK-LABEL: func @_QPtest2( +! CHECK-SAME: %[[a:[^:]*]]: !fir.ref>{{.*}}, %[[b:[^:]*]]: !fir.ref{{.*}}) +subroutine test2(a, b) + real :: a(5), b + real, external :: f + + ! Look for the 5 store patterns + ! CHECK: %[[tmp:.*]] = fir.allocmem !fir.array<5xf32> + ! CHECK: %[[val:.*]] = fir.call @_QPf(%[[b]]) : (!fir.ref) -> f32 + ! CHECK: %[[loc:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>, index) -> !fir.ref + ! CHECK: fir.store %[[val]] to %[[loc]] : !fir.ref + ! CHECK: fir.call @_QPf(%{{.*}}) : (!fir.ref) -> f32 + ! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>, index) -> !fir.ref + ! CHECK: fir.store + ! CHECK: fir.call @_QPf( + ! CHECK: fir.coordinate_of % + ! CHECK: fir.store + ! CHECK: fir.call @_QPf( + ! CHECK: fir.coordinate_of % + ! CHECK: fir.store + ! CHECK: fir.call @_QPf( + ! CHECK: fir.coordinate_of % + ! CHECK: fir.store + + ! After the ctor done, loop to copy result to `a` + ! CHECK-DAG: fir.array_coor %[[tmp:.*]](% + ! CHECK-DAG: %[[ai:.*]] = fir.array_coor %[[a]](% + ! CHECK: fir.store %{{.*}} to %[[ai]] : !fir.ref + ! CHECK: fir.freemem %[[tmp]] + + a = [f(b), f(b+1), f(b+2), f(b+5), f(b+11)] +end subroutine test2 + +! Dynamic array ctor with dynamic extent. +! CHECK-LABEL: func @_QPtest3( +! CHECK-SAME: %[[a:.*]]: !fir.box>{{.*}}) +subroutine test3(a) + real :: a(:) + real, allocatable :: b(:), c(:) + interface + subroutine test3b(x) + real, allocatable :: x(:) + end subroutine test3b + end interface + interface + function test3c + real, allocatable :: test3c(:) + end function test3c + end interface + + ! CHECK: fir.call @_QPtest3b + ! CHECK: %{{.*}}:3 = fir.box_dims %{{.*}}, %{{.*}} : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %{{.*}} = fir.box_addr %{{.*}} : (!fir.box>>) -> !fir.heap> + ! CHECK: %[[tmp:.*]] = fir.allocmem f32, %c32 + call test3b(b) + ! CHECK: %[[hp1:.*]] = fir.allocmem !fir.array, %{{.*}} {uniq_name = ".array.expr"} + ! CHECK-DAG: %[[rep:.*]] = fir.convert %{{.*}} : (!fir.heap) -> !fir.ref + ! CHECK-DAG: %[[res:.*]] = fir.convert %{{.*}} : (index) -> i64 + ! CHECK: %{{.*}} = fir.call @realloc(%[[rep]], %[[res]]) : (!fir.ref, i64) -> !fir.ref + ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: fir.call @_QPtest3c + ! CHECK: fir.save_result + ! CHECK: %[[tmp2:.*]] = fir.allocmem !fir.array, %{{.*}}#1 {uniq_name = ".array.expr"} + ! CHECK: fir.call @realloc + ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(% + ! CHECK: fir.array_coor %[[tmp:.*]](%{{.*}}) %{{.*}} : (!fir.heap>, !fir.shape<1>, index) -> !fir.ref + ! CHECK-NEXT: fir.load + ! CHECK-NEXT: fir.array_coor %arg0 %{{.*}} : (!fir.box>, index) -> !fir.ref + ! CHECK-NEXT: fir.store + ! CHECK: fir.freemem %[[tmp]] + ! CHECK: fir.freemem %[[tmp2]] + ! CHECK: %[[alli:.*]] = fir.box_addr %{{.*}} : (!fir.box>>) -> !fir.heap> + ! CHECK: fir.freemem %[[alli]] + ! CHECK: fir.freemem %[[hp1]] + a = (/ b, test3c() /) +end subroutine test3 + +! CHECK-LABEL: func @_QPtest4( +subroutine test4(a, b, n1, m1) + real :: a(:) + real :: b(:,:) + integer, external :: f1, f2, f3 + + ! Dynamic array ctor with dynamic extent using implied do loops. + ! CHECK-DAG: fir.alloca index {bindc_name = ".buff.pos"} + ! CHECK-DAG: fir.alloca index {bindc_name = ".buff.size"} + ! CHECK-DAG: %[[c32:.*]] = arith.constant 32 : index + ! CHECK: fir.allocmem f32, %[[c32]] + ! CHECK: fir.call @_QPf1(%{{.*}}) : (!fir.ref) -> i32 + ! CHECK: fir.call @_QPf2(%arg2) : (!fir.ref) -> i32 + ! CHECK: fir.call @_QPf3(%{{.*}}) : (!fir.ref) -> i32 + ! CHECK: %[[q:.*]] = fir.coordinate_of %arg1, %{{.*}}, %{{.*}} : (!fir.box>, i64, i64) -> !fir.ref + ! CHECK: %[[q2:.*]] = fir.load %[[q]] : !fir.ref + ! CHECK: fir.store %[[q2]] to %{{.*}} : !fir.ref + ! CHECK: fir.freemem %{{.*}} + ! CHECK-NEXT: return + a = [ ((b(i,j), j=f1(i),f2(n1),f3(m1+i)), i=1,n1,m1) ] +end subroutine test4 + +! CHECK-LABEL: func @_QPtest5( +! CHECK-SAME: %[[a:[^:]*]]: !fir.box>{{.*}}, %[[array2:[^:]*]]: !fir.ref>{{.*}}) +subroutine test5(a, array2) + real :: a(:) + real, parameter :: const_array1(2) = [ 1.0, 2.0 ] + real :: array2(2) + + ! Array ctor with runtime element values and constant extents. + ! Concatenation of array values of constant extent. + ! CHECK: %[[res:.*]] = fir.allocmem !fir.array<4xf32> + ! CHECK: fir.address_of(@_QQro.2xr4.057a7f5ab69cb695657046b18832c330) : !fir.ref> + ! CHECK: %[[tmp1:.*]] = fir.allocmem !fir.array<2xf32> + ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: %[[tmp2:.*]] = fir.allocmem !fir.array<2xf32> + ! CHECK: = fir.array_coor %[[array2]](%{{.*}}) %{{.*}} : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + ! CHECK: = fir.array_coor %[[tmp2]](%{{.*}}) %{{.*}} : (!fir.heap>, !fir.shape<1>, index) -> !fir.ref + ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: = fir.array_coor %{{.*}}(%{{.*}}) %{{.*}} : (!fir.heap>, !fir.shape<1>, index) -> !fir.ref + ! CHECK: = fir.array_coor %[[a]] %{{.*}} : (!fir.box>, index) -> !fir.ref + ! CHECK-DAG: fir.freemem %{{.*}} + ! CHECK-DAG: fir.freemem %[[tmp2]] + ! CHECK-DAG: fir.freemem %[[tmp1]] + ! CHECK: return + a = [ const_array1, array2 ] +end subroutine test5 + +! CHECK-LABEL: func @_QPtest6( +subroutine test6(c, d, e) + character(5) :: c(3) + character(5) :: d, e + ! CHECK: = fir.allocmem !fir.array<2x!fir.char<1,5>> + ! CHECK: fir.call @realloc + ! CHECK: %[[t:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>>, index) -> !fir.ref> + ! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref>) -> !fir.ref + ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%[[to]], %{{.*}}, %{{.*}}, %false) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: fir.call @realloc + ! CHECK: %[[t:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap>>, index) -> !fir.ref> + ! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref>) -> !fir.ref + ! CHECK: fir.call @llvm.memcpy.p0i8.p0i8.i64(%[[to]], %{{.*}}, %{{.*}}, %false) : (!fir.ref, !fir.ref, i64, i1) -> () + ! CHECK: fir.freemem %{{.*}} + c = (/ d, e /) +end subroutine test6 + +! CHECK-LABEL: func @_QPtest7( +! CHECK: %[[i:.*]] = fir.convert %{{.*}} : (index) -> i8 +! CHECK: %[[und:.*]] = fir.undefined !fir.char<1> +! CHECK: %[[scalar:.*]] = fir.insert_value %[[und]], %[[i]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> +! CHECK: ^bb{{[0-9]+}}(%{{.*}}: !fir.heap>): // 2 preds +! CHECK: fir.store %[[scalar]] to %{{.*}} : !fir.ref> +subroutine test7(a, n) + character(1) :: a(n) + a = (/ (CHAR(i), i=1,n) /) +end subroutine test7 + +! CHECK: fir.global internal @_QQro.3xr4.{{.*}}(dense<[1.000000e+00, 2.000000e+00, 3.000000e+00]> : tensor<3xf32>) constant : !fir.array<3xf32> + +! CHECK: fir.global internal @_QQro.4xi4.{{.*}}(dense<[6, 7, 42, 9]> : tensor<4xi32>) constant : !fir.array<4xi32> diff --git a/flang/test/Lower/array-elemental-calls-2.f90 b/flang/test/Lower/array-elemental-calls-2.f90 index dbcb9dfaa5135..d6cfad09ef016 100644 --- a/flang/test/Lower/array-elemental-calls-2.f90 +++ b/flang/test/Lower/array-elemental-calls-2.f90 @@ -6,197 +6,196 @@ ! (for the operation) module test_ops - interface - integer elemental function elem_func(i) - integer, intent(in) :: i - end function - integer elemental function elem_func_logical(l) - logical(8), intent(in) :: l - end function - integer elemental function elem_func_logical4(l) - logical, intent(in) :: l - end function - integer elemental function elem_func_real(x) - real(8), value :: x - end function - end interface - integer :: i(10), j(10), iscalar - logical(8) :: a(10), b(10) - real(8) :: x(10), y(10) - complex(8) :: z1(10), z2 - - contains - ! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops() { - subroutine check_binary_ops() - print *, elem_func(i+j) - ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 - ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 - ! CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_25]], %[[VAL_26]] : i32 - ! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops_2() { - subroutine check_binary_ops_2() - print *, elem_func(i*iscalar) - ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 - ! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 - ! CHECK: %[[VAL_27:.*]] = arith.muli %[[VAL_25]], %[[VAL_13]] : i32 - ! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_negate() { - subroutine check_negate() - print *, elem_func(-i) - ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 - ! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : i32 - ! CHECK: fir.store %[[VAL_23]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_convert() { - subroutine check_convert() - print *, elem_func(int(x)) - ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 - ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (f64) -> i32 - ! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_exteremum() { - subroutine check_exteremum() - print *, elem_func(min(i, j)) - ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 - ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 - ! CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i32 - ! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i32 - ! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_logical_unary_ops() { - subroutine check_logical_unary_ops() - print *, elem_func_logical(.not.b) - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8> - ! CHECK: %[[VAL_12:.*]] = arith.constant true - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_22:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> - ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.logical<8>) -> i1 - ! CHECK: %[[VAL_24:.*]] = arith.xori %[[VAL_23]], %[[VAL_12]] : i1 - ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i1) -> !fir.logical<8> - ! CHECK: fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref> - ! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) : (!fir.ref>) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_logical_binary_ops() { - subroutine check_logical_binary_ops() - print *, elem_func_logical(a.eqv.b) - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8> - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> - ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> - ! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (!fir.logical<8>) -> i1 - ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.logical<8>) -> i1 - ! CHECK: %[[VAL_29:.*]] = arith.cmpi eq, %[[VAL_27]], %[[VAL_28]] : i1 - ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i1) -> !fir.logical<8> - ! CHECK: fir.store %[[VAL_30]] to %[[VAL_0]] : !fir.ref> - ! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) : (!fir.ref>) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_compare() { - subroutine check_compare() - print *, elem_func_logical4(x.lt.y) - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<4> - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 - ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 - ! CHECK: %[[VAL_27:.*]] = arith.cmpf olt, %[[VAL_25]], %[[VAL_26]] : f64 - ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i1) -> !fir.logical<4> - ! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref> - ! CHECK: fir.call @_QPelem_func_logical4(%[[VAL_0]]) : (!fir.ref>) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_pow() { - subroutine check_pow() - print *, elem_func_real(x**y) - ! CHECK: %[[VAL_0:.*]] = fir.alloca f64 - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 - ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 - ! CHECK: %[[VAL_27:.*]] = fir.call @__fd_pow_1(%[[VAL_25]], %[[VAL_26]]) : (f64, f64) -> f64 - ! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref - ! CHECK: %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_cmplx_part() { - subroutine check_cmplx_part() - print *, elem_func_real(AIMAG(z1 + z2)) - ! CHECK: %[[VAL_0:.*]] = fir.alloca f64 - ! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref> - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.complex<8>>, index) -> !fir.complex<8> - ! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] : !fir.complex<8> - ! CHECK: %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (!fir.complex<8>) -> f64 - ! CHECK: fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() { - subroutine check_parentheses() - print *, elem_func_real((x)) - ! CHECK: %[[VAL_0:.*]] = fir.alloca f64 - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 - ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : f64 - ! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref - ! CHECK: fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 - end subroutine - - ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses_logical() { - subroutine check_parentheses_logical() - print *, elem_func_logical((a)) - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8> - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> - ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.logical<8> - ! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref> - ! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) : (!fir.ref>) -> i32 - end subroutine - - subroutine check_parentheses_derived(a) - type t - integer :: i - end type - interface - integer elemental function elem_func_derived(x) - import :: t - type(t), intent(in) :: x - end function - end interface - type(t), pointer :: a(:) - print *, elem_func_derived((a)) - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}> - ! CHECK: fir.do_loop - ! CHECK: %[[VAL_21:.*]] = fir.array_access %{{.}}, %{{.*}} - ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.ref> - ! CHECK: %[[FIELD:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}> - ! CHECK: %[[FROM:.*]] = fir.coordinate_of %[[VAL_22]], %[[FIELD]] : (!fir.ref>, !fir.field) -> !fir.ref - ! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], %[[FIELD]] : (!fir.ref>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL:.*]] = fir.load %[[FROM]] : !fir.ref - ! CHECK: fir.store %[[VAL]] to %[[TO]] : !fir.ref - ! CHECK: %25 = fir.call @_QPelem_func_derived(%[[VAL_0]]) : (!fir.ref>) -> i32 - end subroutine - end module - \ No newline at end of file + interface + integer elemental function elem_func(i) + integer, intent(in) :: i + end function + integer elemental function elem_func_logical(l) + logical(8), intent(in) :: l + end function + integer elemental function elem_func_logical4(l) + logical, intent(in) :: l + end function + integer elemental function elem_func_real(x) + real(8), value :: x + end function + end interface + integer :: i(10), j(10), iscalar + logical(8) :: a(10), b(10) + real(8) :: x(10), y(10) + complex(8) :: z1(10), z2 + +contains +! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops() { +subroutine check_binary_ops() + print *, elem_func(i+j) +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 +! CHECK: fir.do_loop +! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 +! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 +! CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_25]], %[[VAL_26]] : i32 +! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops_2() { +subroutine check_binary_ops_2() + print *, elem_func(i*iscalar) +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 +! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref +! CHECK: fir.do_loop +! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 +! CHECK: %[[VAL_27:.*]] = arith.muli %[[VAL_25]], %[[VAL_13]] : i32 +! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_negate() { +subroutine check_negate() + print *, elem_func(-i) +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 +! CHECK: fir.do_loop +! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 +! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : i32 +! CHECK: fir.store %[[VAL_23]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_convert() { +subroutine check_convert() + print *, elem_func(int(x)) +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 +! CHECK: fir.do_loop +! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 +! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (f64) -> i32 +! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_exteremum() { +subroutine check_exteremum() + print *, elem_func(min(i, j)) +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 +! CHECK: fir.do_loop +! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 +! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32 +! CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i32 +! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i32 +! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_logical_unary_ops() { +subroutine check_logical_unary_ops() + print *, elem_func_logical(.not.b) +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8> +! CHECK: %[[VAL_12:.*]] = arith.constant true +! CHECK: fir.do_loop +! CHECK: %[[VAL_22:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> +! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.logical<8>) -> i1 +! CHECK: %[[VAL_24:.*]] = arith.xori %[[VAL_23]], %[[VAL_12]] : i1 +! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i1) -> !fir.logical<8> +! CHECK: fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref> +! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) : (!fir.ref>) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_logical_binary_ops() { +subroutine check_logical_binary_ops() + print *, elem_func_logical(a.eqv.b) +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8> +! CHECK: fir.do_loop +! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> +! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> +! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (!fir.logical<8>) -> i1 +! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.logical<8>) -> i1 +! CHECK: %[[VAL_29:.*]] = arith.cmpi eq, %[[VAL_27]], %[[VAL_28]] : i1 +! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i1) -> !fir.logical<8> +! CHECK: fir.store %[[VAL_30]] to %[[VAL_0]] : !fir.ref> +! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) : (!fir.ref>) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_compare() { +subroutine check_compare() + print *, elem_func_logical4(x.lt.y) +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<4> +! CHECK: fir.do_loop +! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 +! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 +! CHECK: %[[VAL_27:.*]] = arith.cmpf olt, %[[VAL_25]], %[[VAL_26]] : f64 +! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i1) -> !fir.logical<4> +! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref> +! CHECK: fir.call @_QPelem_func_logical4(%[[VAL_0]]) : (!fir.ref>) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_pow() { +subroutine check_pow() + print *, elem_func_real(x**y) +! CHECK: %[[VAL_0:.*]] = fir.alloca f64 +! CHECK: fir.do_loop +! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 +! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 +! CHECK: %[[VAL_27:.*]] = fir.call @__fd_pow_1(%[[VAL_25]], %[[VAL_26]]) : (f64, f64) -> f64 +! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref +! CHECK: %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_cmplx_part() { +subroutine check_cmplx_part() + print *, elem_func_real(AIMAG(z1 + z2)) +! CHECK: %[[VAL_0:.*]] = fir.alloca f64 +! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref> +! CHECK: fir.do_loop +! CHECK: %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.complex<8>>, index) -> !fir.complex<8> +! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] : !fir.complex<8> +! CHECK: %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (!fir.complex<8>) -> f64 +! CHECK: fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() { +subroutine check_parentheses() + print *, elem_func_real((x)) +! CHECK: %[[VAL_0:.*]] = fir.alloca f64 +! CHECK: fir.do_loop +! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 +! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : f64 +! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref +! CHECK: fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 +end subroutine + +! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses_logical() { +subroutine check_parentheses_logical() + print *, elem_func_logical((a)) +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8> +! CHECK: fir.do_loop +! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8> +! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.logical<8> +! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref> +! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) : (!fir.ref>) -> i32 +end subroutine + +subroutine check_parentheses_derived(a) + type t + integer :: i + end type + interface + integer elemental function elem_func_derived(x) + import :: t + type(t), intent(in) :: x + end function + end interface + type(t), pointer :: a(:) + print *, elem_func_derived((a)) +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}> +! CHECK: fir.do_loop +! CHECK: %[[VAL_21:.*]] = fir.array_access %{{.}}, %{{.*}} +! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.ref> +! CHECK: %[[FIELD:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}> +! CHECK: %[[FROM:.*]] = fir.coordinate_of %[[VAL_22]], %[[FIELD]] : (!fir.ref>, !fir.field) -> !fir.ref +! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], %[[FIELD]] : (!fir.ref>, !fir.field) -> !fir.ref +! CHECK: %[[VAL:.*]] = fir.load %[[FROM]] : !fir.ref +! CHECK: fir.store %[[VAL]] to %[[TO]] : !fir.ref +! CHECK: %25 = fir.call @_QPelem_func_derived(%[[VAL_0]]) : (!fir.ref>) -> i32 +end subroutine +end module diff --git a/flang/test/Lower/array-elemental-calls.f90 b/flang/test/Lower/array-elemental-calls.f90 index 3319c7a92f75e..115941681d6d0 100644 --- a/flang/test/Lower/array-elemental-calls.f90 +++ b/flang/test/Lower/array-elemental-calls.f90 @@ -3,104 +3,104 @@ module scalar_in_elem - contains - elemental integer function elem_by_ref(a,b) result(r) - integer, intent(in) :: a - real, intent(in) :: b - r = a + b +contains +elemental integer function elem_by_ref(a,b) result(r) + integer, intent(in) :: a + real, intent(in) :: b + r = a + b +end function +elemental integer function elem_by_valueref(a,b) result(r) + integer, value :: a + real, value :: b + r = a + b +end function + +! CHECK-LABEL: func @_QMscalar_in_elemPtest_elem_by_ref( +! CHECK-SAME: %[[arg0:.*]]: !fir.ref>{{.*}}, %[[arg1:.*]]: !fir.ref>{{.*}}) { +subroutine test_elem_by_ref(i, j) + integer :: i(100), j(100) + ! CHECK: %[[tmp:.*]] = fir.alloca f32 + ! CHECK: %[[cst:.*]] = arith.constant 4.200000e+01 : f32 + ! CHECK: fir.store %[[cst]] to %[[tmp]] : !fir.ref + + ! CHECK: fir.do_loop + ! CHECK: %[[j:.*]] = fir.array_coor %[[arg1]](%{{.*}}) %{{.*}} : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + ! CHECK: fir.call @_QMscalar_in_elemPelem_by_ref(%[[j]], %[[tmp]]) : (!fir.ref, !fir.ref) -> i32 + ! CHECK: fir.result + i = elem_by_ref(j, 42.) +end + +! CHECK-LABEL: func @_QMscalar_in_elemPtest_elem_by_valueref( +! CHECK-SAME: %[[arg0:.*]]: !fir.ref>{{.*}}, %[[arg1:.*]]: !fir.ref>{{.*}}) { +subroutine test_elem_by_valueref(i, j) + integer :: i(100), j(100) + ! CHECK-DAG: %[[tmpA:.*]] = fir.alloca i32 {adapt.valuebyref} + ! CHECK-DAG: %[[tmpB:.*]] = fir.alloca f32 {adapt.valuebyref} + ! CHECK: %[[jload:.*]] = fir.array_load %[[arg1]] + ! CHECK: %[[cst:.*]] = arith.constant 4.200000e+01 : f32 + ! CHECK: fir.store %[[cst]] to %[[tmpB]] : !fir.ref + + ! CHECK: fir.do_loop + ! CHECK: %[[j:.*]] = fir.array_fetch %[[jload]], %{{.*}} : (!fir.array<100xi32>, index) -> i32 + ! CHECK: fir.store %[[j]] to %[[tmpA]] : !fir.ref + ! CHECK: fir.call @_QMscalar_in_elemPelem_by_valueref(%[[tmpA]], %[[tmpB]]) : (!fir.ref, !fir.ref) -> i32 + ! CHECK: fir.result + i = elem_by_valueref(j, 42.) +end +end module + + +! Test that impure elemental functions cause ordered loops to be emitted +subroutine test_loop_order(i, j) + integer :: i(:), j(:) + interface + elemental integer function pure_func(j) + integer, intent(in) :: j end function - elemental integer function elem_by_valueref(a,b) result(r) - integer, value :: a - real, value :: b - r = a + b + elemental impure integer function impure_func(j) + integer, intent(in) :: j end function - - ! CHECK-LABEL: func @_QMscalar_in_elemPtest_elem_by_ref( - ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>{{.*}}, %[[arg1:.*]]: !fir.ref>{{.*}}) { - subroutine test_elem_by_ref(i, j) - integer :: i(100), j(100) - ! CHECK: %[[tmp:.*]] = fir.alloca f32 - ! CHECK: %[[cst:.*]] = arith.constant 4.200000e+01 : f32 - ! CHECK: fir.store %[[cst]] to %[[tmp]] : !fir.ref - - ! CHECK: fir.do_loop - ! CHECK: %[[j:.*]] = fir.array_coor %[[arg1]](%{{.*}}) %{{.*}} : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref - ! CHECK: fir.call @_QMscalar_in_elemPelem_by_ref(%[[j]], %[[tmp]]) : (!fir.ref, !fir.ref) -> i32 - ! CHECK: fir.result - i = elem_by_ref(j, 42.) - end - - ! CHECK-LABEL: func @_QMscalar_in_elemPtest_elem_by_valueref( - ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>{{.*}}, %[[arg1:.*]]: !fir.ref>{{.*}}) { - subroutine test_elem_by_valueref(i, j) - integer :: i(100), j(100) - ! CHECK-DAG: %[[tmpA:.*]] = fir.alloca i32 {adapt.valuebyref} - ! CHECK-DAG: %[[tmpB:.*]] = fir.alloca f32 {adapt.valuebyref} - ! CHECK: %[[jload:.*]] = fir.array_load %[[arg1]] - ! CHECK: %[[cst:.*]] = arith.constant 4.200000e+01 : f32 - ! CHECK: fir.store %[[cst]] to %[[tmpB]] : !fir.ref - - ! CHECK: fir.do_loop - ! CHECK: %[[j:.*]] = fir.array_fetch %[[jload]], %{{.*}} : (!fir.array<100xi32>, index) -> i32 - ! CHECK: fir.store %[[j]] to %[[tmpA]] : !fir.ref - ! CHECK: fir.call @_QMscalar_in_elemPelem_by_valueref(%[[tmpA]], %[[tmpB]]) : (!fir.ref, !fir.ref) -> i32 - ! CHECK: fir.result - i = elem_by_valueref(j, 42.) - end - end module - - - ! Test that impure elemental functions cause ordered loops to be emitted - subroutine test_loop_order(i, j) - integer :: i(:), j(:) - interface - elemental integer function pure_func(j) - integer, intent(in) :: j - end function - elemental impure integer function impure_func(j) - integer, intent(in) :: j - end function - end interface - - i = 42 + pure_func(j) - i = 42 + impure_func(j) - end subroutine - - ! CHECK-LABEL: func @_QPtest_loop_order( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}, %[[VAL_1:.*]]: !fir.box>{{.*}}) { - ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_4:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_5:.*]] = arith.constant 42 : i32 - ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_8:.*]] = arith.subi %[[VAL_3]]#1, %[[VAL_6]] : index - ! CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_7]] to %[[VAL_8]] step %[[VAL_6]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_4]]) -> (!fir.array) { - ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_10]], %[[VAL_12]] : index - ! CHECK: %[[VAL_14:.*]] = fir.array_coor %[[VAL_1]] %[[VAL_13]] : (!fir.box>, index) -> !fir.ref - ! CHECK: %[[VAL_15:.*]] = fir.call @_QPpure_func(%[[VAL_14]]) : (!fir.ref) -> i32 - ! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_5]], %[[VAL_15]] : i32 - ! CHECK: %[[VAL_17:.*]] = fir.array_update %[[VAL_11]], %[[VAL_16]], %[[VAL_10]] : (!fir.array, i32, index) -> !fir.array - ! CHECK: fir.result %[[VAL_17]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_4]], %[[VAL_18:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> - ! CHECK: %[[VAL_19:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_21:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_22:.*]] = arith.constant 42 : i32 - ! CHECK: %[[VAL_23:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_24:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_25:.*]] = arith.subi %[[VAL_20]]#1, %[[VAL_23]] : index - ! CHECK: %[[VAL_26:.*]] = fir.do_loop %[[VAL_27:.*]] = %[[VAL_24]] to %[[VAL_25]] step %[[VAL_23]] iter_args(%[[VAL_28:.*]] = %[[VAL_21]]) -> (!fir.array) { - ! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_27]], %[[VAL_29]] : index - ! CHECK: %[[VAL_31:.*]] = fir.array_coor %[[VAL_1]] %[[VAL_30]] : (!fir.box>, index) -> !fir.ref - ! CHECK: %[[VAL_32:.*]] = fir.call @_QPimpure_func(%[[VAL_31]]) : (!fir.ref) -> i32 - ! CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_22]], %[[VAL_32]] : i32 - ! CHECK: %[[VAL_34:.*]] = fir.array_update %[[VAL_28]], %[[VAL_33]], %[[VAL_27]] : (!fir.array, i32, index) -> !fir.array - ! CHECK: fir.result %[[VAL_34]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_21]], %[[VAL_35:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> - ! CHECK: return - ! CHECK: } + end interface + + i = 42 + pure_func(j) + i = 42 + impure_func(j) +end subroutine + +! CHECK-LABEL: func @_QPtest_loop_order( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}, %[[VAL_1:.*]]: !fir.box>{{.*}}) { +! CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_4:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_5:.*]] = arith.constant 42 : i32 +! CHECK: %[[VAL_6:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_8:.*]] = arith.subi %[[VAL_3]]#1, %[[VAL_6]] : index +! CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_7]] to %[[VAL_8]] step %[[VAL_6]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_4]]) -> (!fir.array) { +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_10]], %[[VAL_12]] : index +! CHECK: %[[VAL_14:.*]] = fir.array_coor %[[VAL_1]] %[[VAL_13]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_15:.*]] = fir.call @_QPpure_func(%[[VAL_14]]) : (!fir.ref) -> i32 +! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_5]], %[[VAL_15]] : i32 +! CHECK: %[[VAL_17:.*]] = fir.array_update %[[VAL_11]], %[[VAL_16]], %[[VAL_10]] : (!fir.array, i32, index) -> !fir.array +! CHECK: fir.result %[[VAL_17]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_4]], %[[VAL_18:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> +! CHECK: %[[VAL_19:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_21:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_22:.*]] = arith.constant 42 : i32 +! CHECK: %[[VAL_23:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_24:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_25:.*]] = arith.subi %[[VAL_20]]#1, %[[VAL_23]] : index +! CHECK: %[[VAL_26:.*]] = fir.do_loop %[[VAL_27:.*]] = %[[VAL_24]] to %[[VAL_25]] step %[[VAL_23]] iter_args(%[[VAL_28:.*]] = %[[VAL_21]]) -> (!fir.array) { +! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_27]], %[[VAL_29]] : index +! CHECK: %[[VAL_31:.*]] = fir.array_coor %[[VAL_1]] %[[VAL_30]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_32:.*]] = fir.call @_QPimpure_func(%[[VAL_31]]) : (!fir.ref) -> i32 +! CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_22]], %[[VAL_32]] : i32 +! CHECK: %[[VAL_34:.*]] = fir.array_update %[[VAL_28]], %[[VAL_33]], %[[VAL_27]] : (!fir.array, i32, index) -> !fir.array +! CHECK: fir.result %[[VAL_34]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_21]], %[[VAL_35:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> +! CHECK: return +! CHECK: } diff --git a/flang/test/Lower/array-expression.f90 b/flang/test/Lower/array-expression.f90 index 2012c822c1fa4..d268301b09648 100644 --- a/flang/test/Lower/array-expression.f90 +++ b/flang/test/Lower/array-expression.f90 @@ -2,1161 +2,1161 @@ ! CHECK-LABEL: func @_QPtest1 subroutine test1(a,b,c,n) - integer :: n - real, intent(out) :: a(n) - real, intent(in) :: b(n), c(n) - ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% - ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% - ! CHECK-DAG: %[[C:.*]] = fir.array_load %arg2(% - ! CHECK: %[[T:.*]] = fir.do_loop - ! CHECK-DAG: %[[Bi:.*]] = fir.array_fetch %[[B]] - ! CHECK-DAG: %[[Ci:.*]] = fir.array_fetch %[[C]] - ! CHECK: %[[rv:.*]] = arith.addf %[[Bi]], %[[Ci]] - ! CHECK: fir.array_update %{{.*}}, %[[rv]], % - a = b + c - ! CHECK: fir.array_merge_store %[[A]], %[[T]] to %arg0 - end subroutine test1 - - ! CHECK-LABEL: func @_QPtest1b - subroutine test1b(a,b,c,d,n) - integer :: n - real, intent(out) :: a(n) - real, intent(in) :: b(n), c(n), d(n) - ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% - ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% - ! CHECK-DAG: %[[C:.*]] = fir.array_load %arg2(% - ! CHECK-DAG: %[[D:.*]] = fir.array_load %arg3(% - ! CHECK: %[[T:.*]] = fir.do_loop - ! CHECK-DAG: %[[Bi:.*]] = fir.array_fetch %[[B]] - ! CHECK-DAG: %[[Ci:.*]] = fir.array_fetch %[[C]] - ! CHECK: %[[rv1:.*]] = arith.addf %[[Bi]], %[[Ci]] - ! CHECK: %[[Di:.*]] = fir.array_fetch %[[D]] - ! CHECK: %[[rv:.*]] = arith.addf %[[rv1]], %[[Di]] - ! CHECK: fir.array_update %{{.*}}, %[[rv]], % - a = b + c + d - ! CHECK: fir.array_merge_store %[[A]], %[[T]] to %arg0 - end subroutine test1b - - ! CHECK-LABEL: func @_QPtest2( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}, %[[VAL_1:.*]]: !fir.box>{{.*}}, %[[VAL_2:.*]]: !fir.box>{{.*}}) { - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_5:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_6:.*]] = fir.array_load %[[VAL_1]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_7:.*]] = fir.array_load %[[VAL_2]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_10:.*]] = arith.subi %[[VAL_4]]#1, %[[VAL_8]] : index - ! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_9]] to %[[VAL_10]] step %[[VAL_8]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_5]]) -> (!fir.array) { - ! CHECK: %[[VAL_14:.*]] = fir.array_fetch %[[VAL_6]], %[[VAL_12]] : (!fir.array, index) -> f32 - ! CHECK: %[[VAL_15:.*]] = fir.array_fetch %[[VAL_7]], %[[VAL_12]] : (!fir.array, index) -> f32 - ! CHECK: %[[VAL_16:.*]] = arith.addf %[[VAL_14]], %[[VAL_15]] : f32 - ! CHECK: %[[VAL_17:.*]] = fir.array_update %[[VAL_13]], %[[VAL_16]], %[[VAL_12]] : (!fir.array, f32, index) -> !fir.array - ! CHECK: fir.result %[[VAL_17]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_5]], %[[VAL_18:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> - ! CHECK: return - ! CHECK: } - subroutine test2(a,b,c) - real, intent(out) :: a(:) - real, intent(in) :: b(:), c(:) - a = b + c - end subroutine test2 - - ! CHECK-LABEL: func @_QPtest3 - subroutine test3(a,b,c,n) - integer :: n - real, intent(out) :: a(n) - real, intent(in) :: b(n), c - ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% - ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% - ! CHECK-DAG: %[[C:.*]] = fir.load %arg2 - ! CHECK: %[[T:.*]] = fir.do_loop - ! CHECK: %[[Bi:.*]] = fir.array_fetch %[[B]] - ! CHECK: %[[rv:.*]] = arith.addf %[[Bi]], %[[C]] - ! CHECK: %[[Ti:.*]] = fir.array_update %{{.*}}, %[[rv]], % - ! CHECK: fir.result %[[Ti]] - a = b + c - ! CHECK: fir.array_merge_store %[[A]], %[[T]] to %arg0 - end subroutine test3 - - ! CHECK-LABEL: func @_QPtest4 - subroutine test4(a,b,c) - ! TODO: this declaration fails in CallInterface lowering - ! real, allocatable, intent(out) :: a(:) - real :: a(100) ! FIXME: fake it for now - real, intent(in) :: b(:), c - ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% - ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1 - ! CHECK: fir.do_loop - ! CHECK: fir.array_fetch %[[B]], % - ! CHECK: fir.array_update - a = b + c - ! CHECK: fir.array_merge_store %[[A]], %{{.*}} to %arg0 - end subroutine test4 - - ! CHECK-LABEL: func @_QPtest5 - subroutine test5(a,b,c) - ! TODO: this declaration fails in CallInterface lowering - ! real, allocatable, intent(out) :: a(:) - ! real, pointer, intent(in) :: b(:) - real :: a(100), b(100) ! FIXME: fake it for now - real, intent(in) :: c - ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% - ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% - ! CHECK: fir.do_loop - ! CHECK: fir.array_fetch %[[B]], % - ! CHECK: fir.array_update - a = b + c - ! CHECK: fir.array_merge_store %[[A]], %{{.*}} to %arg0 - end subroutine test5 - - ! CHECK-LABEL: func @_QPtest6( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref{{.*}}, %[[VAL_4:.*]]: !fir.ref{{.*}}) { - ! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> i64 - ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> index - ! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_4]] : !fir.ref - ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i32) -> i64 - ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i64) -> index - ! CHECK: %[[VAL_11:.*]] = arith.constant 3 : i64 - ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index - ! CHECK: %[[VAL_13:.*]] = arith.constant 4 : i64 - ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> index - ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 - ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index - ! CHECK: %[[VAL_18:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_17]], %[[VAL_12]] : index - ! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_19]], %[[VAL_14]] : index - ! CHECK: %[[VAL_21:.*]] = arith.divsi %[[VAL_20]], %[[VAL_14]] : index - ! CHECK: %[[VAL_22:.*]] = arith.cmpi sgt, %[[VAL_21]], %[[VAL_18]] : index - ! CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_21]], %[[VAL_18]] : index - ! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_25:.*]] = fir.slice %[[VAL_12]], %[[VAL_17]], %[[VAL_14]] : (index, index, index) -> !fir.slice<1> - ! CHECK: %[[VAL_26:.*]] = fir.array_load %[[VAL_0]](%[[VAL_24]]) {{\[}}%[[VAL_25]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.array - ! CHECK: %[[VAL_27:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_28:.*]] = fir.array_load %[[VAL_1]](%[[VAL_27]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array - ! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_30:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_31:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_32:.*]] = arith.subi %[[VAL_23]], %[[VAL_30]] : index - ! CHECK: %[[VAL_33:.*]] = fir.do_loop %[[VAL_34:.*]] = %[[VAL_31]] to %[[VAL_32]] step %[[VAL_30]] unordered iter_args(%[[VAL_35:.*]] = %[[VAL_26]]) -> (!fir.array) { - ! CHECK: %[[VAL_36:.*]] = fir.array_fetch %[[VAL_28]], %[[VAL_34]] : (!fir.array, index) -> f32 - ! CHECK: %[[VAL_37:.*]] = arith.addf %[[VAL_36]], %[[VAL_29]] : f32 - ! CHECK: %[[VAL_38:.*]] = fir.array_update %[[VAL_35]], %[[VAL_37]], %[[VAL_34]] : (!fir.array, f32, index) -> !fir.array - ! CHECK: fir.result %[[VAL_38]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_26]], %[[VAL_39:.*]] to %[[VAL_0]]{{\[}}%[[VAL_25]]] : !fir.array, !fir.array, !fir.ref>, !fir.slice<1> - ! CHECK: return - ! CHECK: } - - subroutine test6(a,b,c,n,m) - integer :: n, m - real, intent(out) :: a(n) - real, intent(in) :: b(m), c - a(3:n:4) = b + c - end subroutine test6 - - ! CHECK-LABEL: func @_QPtest6a( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { - ! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_3:.*]] = arith.constant 50 : index - ! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_6:.*]] = fir.array_load %[[VAL_1]](%[[VAL_5]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<10xf32> - ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_8:.*]] = arith.constant 4 : i64 - ! CHECK: %[[VAL_9:.*]] = fir.undefined index - ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (i64) -> index - ! CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_10]], %[[VAL_7]] : index - ! CHECK: %[[VAL_12:.*]] = arith.constant 41 : i64 - ! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index - ! CHECK: %[[VAL_14:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index - ! CHECK: %[[VAL_16:.*]] = arith.constant 50 : i64 - ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index - ! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_19:.*]] = fir.slice %[[VAL_8]], %[[VAL_9]], %[[VAL_9]], %[[VAL_13]], %[[VAL_17]], %[[VAL_15]] : (i64, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_0]](%[[VAL_18]]) {{\[}}%[[VAL_19]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.array<10x50xf32> - ! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_22:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_4]], %[[VAL_21]] : index - ! CHECK: %[[VAL_24:.*]] = fir.do_loop %[[VAL_25:.*]] = %[[VAL_22]] to %[[VAL_23]] step %[[VAL_21]] unordered iter_args(%[[VAL_26:.*]] = %[[VAL_6]]) -> (!fir.array<10xf32>) { - ! CHECK: %[[VAL_27:.*]] = fir.array_fetch %[[VAL_20]], %[[VAL_11]], %[[VAL_25]] : (!fir.array<10x50xf32>, index, index) -> f32 - ! CHECK: %[[VAL_28:.*]] = fir.array_update %[[VAL_26]], %[[VAL_27]], %[[VAL_25]] : (!fir.array<10xf32>, f32, index) -> !fir.array<10xf32> - ! CHECK: fir.result %[[VAL_28]] : !fir.array<10xf32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_6]], %[[VAL_29:.*]] to %[[VAL_1]] : !fir.array<10xf32>, !fir.array<10xf32>, !fir.ref> - ! CHECK: return - ! CHECK: } - - subroutine test6a(a,b) - ! copy part of 1 row to b. a's projection has rank 1. - real :: a(10,50) - real :: b(10) - b = a(4,41:50) - end subroutine test6a - - ! CHECK-LABEL: func @_QPtest6b( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { - ! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_3:.*]] = arith.constant 50 : index - ! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_6:.*]] = arith.constant 4 : i64 - ! CHECK: %[[VAL_7:.*]] = fir.undefined index - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (i64) -> index - ! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_5]] : index - ! CHECK: %[[VAL_10:.*]] = arith.constant 41 : i64 - ! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index - ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index - ! CHECK: %[[VAL_14:.*]] = arith.constant 50 : i64 - ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index - ! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]], %[[VAL_11]] : index - ! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_17]], %[[VAL_13]] : index - ! CHECK: %[[VAL_19:.*]] = arith.divsi %[[VAL_18]], %[[VAL_13]] : index - ! CHECK: %[[VAL_20:.*]] = arith.cmpi sgt, %[[VAL_19]], %[[VAL_16]] : index - ! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_20]], %[[VAL_19]], %[[VAL_16]] : index - ! CHECK: %[[VAL_22:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_23:.*]] = fir.slice %[[VAL_6]], %[[VAL_7]], %[[VAL_7]], %[[VAL_11]], %[[VAL_15]], %[[VAL_13]] : (i64, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: %[[VAL_24:.*]] = fir.array_load %[[VAL_0]](%[[VAL_22]]) {{\[}}%[[VAL_23]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.array<10x50xf32> - ! CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_26:.*]] = fir.array_load %[[VAL_1]](%[[VAL_25]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<10xf32> - ! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_21]], %[[VAL_27]] : index - ! CHECK: %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_28]] to %[[VAL_29]] step %[[VAL_27]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_24]]) -> (!fir.array<10x50xf32>) { - ! CHECK: %[[VAL_33:.*]] = fir.array_fetch %[[VAL_26]], %[[VAL_31]] : (!fir.array<10xf32>, index) -> f32 - ! CHECK: %[[VAL_34:.*]] = fir.array_update %[[VAL_32]], %[[VAL_33]], %[[VAL_9]], %[[VAL_31]] : (!fir.array<10x50xf32>, f32, index, index) -> !fir.array<10x50xf32> - ! CHECK: fir.result %[[VAL_34]] : !fir.array<10x50xf32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_24]], %[[VAL_35:.*]] to %[[VAL_0]]{{\[}}%[[VAL_23]]] : !fir.array<10x50xf32>, !fir.array<10x50xf32>, !fir.ref>, !fir.slice<2> - ! CHECK: return - ! CHECK: } - - subroutine test6b(a,b) - ! copy b to columns 41 to 50 of row 4 of a - real :: a(10,50) - real :: b(10) - a(4,41:50) = b - end subroutine test6b - - ! CHECK-LABEL: func @_QPtest7( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { - ! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> i64 - ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> index - ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64 - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> index - ! CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_10:.*]] = fir.array_load %[[VAL_0]](%[[VAL_9]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array - ! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_12:.*]] = fir.array_load %[[VAL_0]](%[[VAL_11]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array - ! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_14:.*]] = fir.array_load %[[VAL_1]](%[[VAL_13]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array - ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_5]], %[[VAL_15]] : index - ! CHECK: %[[VAL_18:.*]] = fir.do_loop %[[VAL_19:.*]] = %[[VAL_16]] to %[[VAL_17]] step %[[VAL_15]] unordered iter_args(%[[VAL_20:.*]] = %[[VAL_10]]) -> (!fir.array) { - ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %[[VAL_12]], %[[VAL_19]] : (!fir.array, index) -> f32 - ! CHECK: %[[VAL_22:.*]] = fir.array_fetch %[[VAL_14]], %[[VAL_19]] : (!fir.array, index) -> f32 - ! CHECK: %[[VAL_23:.*]] = arith.addf %[[VAL_21]], %[[VAL_22]] : f32 - ! CHECK: %[[VAL_24:.*]] = fir.array_update %[[VAL_20]], %[[VAL_23]], %[[VAL_19]] : (!fir.array, f32, index) -> !fir.array - ! CHECK: fir.result %[[VAL_24]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_10]], %[[VAL_25:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.ref> - ! CHECK: return - ! CHECK: } - - ! This is NOT a conflict. `a` appears on both the lhs and rhs here, but there - ! are no loop-carried dependences and no copy is needed. - subroutine test7(a,b,n) - integer :: n - real, intent(inout) :: a(n) - real, intent(in) :: b(n) - a = a + b - end subroutine test7 - - ! CHECK-LABEL: func @_QPtest8( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { - ! CHECK: %[[VAL_2:.*]] = arith.constant 100 : index - ! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_4:.*]] = fir.array_load %[[VAL_0]](%[[VAL_3]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xi32> - ! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_7:.*]] = arith.subi %[[VAL_5]], %[[VAL_6]] : i64 - ! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_7]] : (!fir.ref>, i64) -> !fir.ref - ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref - ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_11:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_2]], %[[VAL_10]] : index - ! CHECK: %[[VAL_13:.*]] = fir.do_loop %[[VAL_14:.*]] = %[[VAL_11]] to %[[VAL_12]] step %[[VAL_10]] unordered iter_args(%[[VAL_15:.*]] = %[[VAL_4]]) -> (!fir.array<100xi32>) { - ! CHECK: %[[VAL_16:.*]] = fir.array_update %[[VAL_15]], %[[VAL_9]], %[[VAL_14]] : (!fir.array<100xi32>, i32, index) -> !fir.array<100xi32> - ! CHECK: fir.result %[[VAL_16]] : !fir.array<100xi32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_4]], %[[VAL_17:.*]] to %[[VAL_0]] : !fir.array<100xi32>, !fir.array<100xi32>, !fir.ref> - ! CHECK: return - ! CHECK: } - - subroutine test8(a,b) - integer :: a(100), b(100) - a = b(1) - end subroutine test8 - - subroutine test10(a,b,c,d) - interface - ! Function takea an array and yields an array - function foo(a) result(res) - real :: a(:) ! FIXME: must be before res or semantics fails - ! as `size(a,1)` fails to resolve to the argument - real, dimension(size(a,1)) :: res - end function foo - end interface - interface - ! Function takes an array and yields a scalar - real function bar(a) - real :: a(:) - end function bar - end interface - real :: a(:), b(:), c(:), d(:) - ! a = b + foo(c + foo(d + bar(a))) - end subroutine test10 - - ! CHECK-LABEL: func @_QPtest11( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref>{{.*}}, %[[VAL_3:.*]]: !fir.ref>{{.*}}) { - ! CHECK: %[[VAL_4:.*]] = arith.constant 100 : index - ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : index - ! CHECK: %[[VAL_6:.*]] = arith.constant 100 : index - ! CHECK: %[[VAL_7:.*]] = arith.constant 100 : index - ! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_0]](%[[VAL_8]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_1]](%[[VAL_10]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK: %[[VAL_12:.*]] = arith.constant 100 : index - ! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_2]](%[[VAL_14]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_3]](%[[VAL_16]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<100xf32> - ! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_18]](%[[VAL_19]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_22:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_12]], %[[VAL_21]] : index - ! CHECK: %[[VAL_24:.*]] = fir.do_loop %[[VAL_25:.*]] = %[[VAL_22]] to %[[VAL_23]] step %[[VAL_21]] unordered iter_args(%[[VAL_26:.*]] = %[[VAL_20]]) -> (!fir.array<100xf32>) { - ! CHECK: %[[VAL_27:.*]] = fir.array_fetch %[[VAL_15]], %[[VAL_25]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK: %[[VAL_28:.*]] = fir.array_fetch %[[VAL_17]], %[[VAL_25]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK: %[[VAL_29:.*]] = arith.addf %[[VAL_27]], %[[VAL_28]] : f32 - ! CHECK: %[[VAL_30:.*]] = fir.array_update %[[VAL_26]], %[[VAL_29]], %[[VAL_25]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> - ! CHECK: fir.result %[[VAL_30]] : !fir.array<100xf32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_20]], %[[VAL_31:.*]] to %[[VAL_18]] : !fir.array<100xf32>, !fir.array<100xf32>, !fir.heap> - ! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_18]] : (!fir.heap>) -> !fir.ref> - ! CHECK: %[[VAL_33:.*]] = fir.call @_QPbar(%[[VAL_32]]) : (!fir.ref>) -> f32 - ! CHECK: %[[VAL_34:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_35:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_4]], %[[VAL_34]] : index - ! CHECK: %[[VAL_37:.*]] = fir.do_loop %[[VAL_38:.*]] = %[[VAL_35]] to %[[VAL_36]] step %[[VAL_34]] unordered iter_args(%[[VAL_39:.*]] = %[[VAL_9]]) -> (!fir.array<100xf32>) { - ! CHECK: %[[VAL_40:.*]] = fir.array_fetch %[[VAL_11]], %[[VAL_38]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK: %[[VAL_41:.*]] = arith.addf %[[VAL_40]], %[[VAL_33]] : f32 - ! CHECK: %[[VAL_42:.*]] = fir.array_update %[[VAL_39]], %[[VAL_41]], %[[VAL_38]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> - ! CHECK: fir.result %[[VAL_42]] : !fir.array<100xf32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_43:.*]] to %[[VAL_0]] : !fir.array<100xf32>, !fir.array<100xf32>, !fir.ref> - ! CHECK: fir.freemem %[[VAL_18]] - ! CHECK: return - ! CHECK: } - - subroutine test11(a,b,c,d) - real, external :: bar - real :: a(100), b(100), c(100), d(100) - a = b + bar(c + d) - end subroutine test11 - - ! CHECK-LABEL: func @_QPtest12 - subroutine test12(a,b,c,d,n,m) - integer :: n, m - ! CHECK: %[[n:.*]] = fir.load %arg4 - ! CHECK: %[[m:.*]] = fir.load %arg5 - ! CHECK: %[[sha:.*]] = fir.shape % - ! CHECK: %[[A:.*]] = fir.array_load %arg0(%[[sha]]) - ! CHECK: %[[shb:.*]] = fir.shape % - ! CHECK: %[[B:.*]] = fir.array_load %arg1(%[[shb]]) - ! CHECK: %[[C:.*]] = fir.array_load %arg2(% - ! CHECK: %[[D:.*]] = fir.array_load %arg3(% - ! CHECK: %[[tmp:.*]] = fir.allocmem !fir.array, %{{.*}} {{{.*}}uniq_name = ".array.expr"} - ! CHECK: %[[T:.*]] = fir.array_load %[[tmp]](% - real, external :: bar - real :: a(n), b(n), c(m), d(m) - ! CHECK: %[[LOOP:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %[[T]]) - ! CHECK-DAG: fir.array_fetch %[[C]] - ! CHECK-DAG: fir.array_fetch %[[D]] - ! CHECK: fir.array_merge_store %[[T]], %[[LOOP]] - ! CHECK: %[[CALL:.*]] = fir.call @_QPbar - ! CHECK: %[[LOOP2:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %[[A]]) - ! CHECK: fir.array_fetch %[[B]] - ! CHECK: fir.array_merge_store %[[A]], %[[LOOP2]] to %arg0 - a = b + bar(c + d) - ! CHECK: fir.freemem %[[tmp]] - end subroutine test12 - - ! CHECK-LABEL: func @_QPtest13 - subroutine test13(a,b,c,d,n,m,i) - real :: a(n), b(m) - complex :: c(n), d(m) - ! CHECK: %[[A_shape:.*]] = fir.shape % - ! CHECK: %[[A:.*]] = fir.array_load %arg0(%[[A_shape]]) - ! CHECK: %[[B_shape:.*]] = fir.shape % - ! CHECK: %[[B_slice:.*]] = fir.slice % - ! CHECK: %[[B:.*]] = fir.array_load %arg1(%[[B_shape]]) [%[[B_slice]]] - ! CHECK: %[[C_shape:.*]] = fir.shape % - ! CHECK: %[[C_slice:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} path % - ! CHECK: %[[C:.*]] = fir.array_load %arg2(%[[C_shape]]) [%[[C_slice]]] - ! CHECK: %[[D_shape:.*]] = fir.shape % - ! CHECK: %[[D_slice:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} path % - ! CHECK: %[[D:.*]] = fir.array_load %arg3(%[[D_shape]]) [%[[D_slice]]] - ! CHECK: = arith.constant -6.2598534E+18 : f32 - ! CHECK: %[[A_result:.*]] = fir.do_loop %{{.*}} = %{{.*}} iter_args(%[[A_in:.*]] = %[[A]]) -> - ! CHECK: fir.array_fetch %[[B]], - ! CHECK: fir.array_fetch %[[C]], - ! CHECK: fir.array_fetch %[[D]], - ! CHECK: fir.array_update %[[A_in]], - a = b(i:i+2*n-2:2) + c%im - d(i:i+2*n-2:2)%re + x'deadbeef' - ! CHECK: fir.array_merge_store %[[A]], %[[A_result]] to %arg0 - end subroutine test13 - - ! Test elemental call to function f - ! CHECK-LABEL: func @_QPtest14( - ! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) - subroutine test14(a,b) - ! CHECK: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - interface - real elemental function f1(i) - real, intent(in) :: i - end function f1 - end interface - real :: a(100), b(100) - ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { - ! CHECK: %[[ishift:.*]] = arith.addi %[[i]], %c1{{.*}} : index - ! CHECK: %[[tmp:.*]] = fir.array_coor %[[a]](%{{.*}}) %[[ishift]] : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref - ! CHECK: %[[fres:.*]] = fir.call @_QPf1(%[[tmp]]) : (!fir.ref) -> f32 - ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> - ! CHECK: fir.result %[[res]] : !fir.array<100xf32> - ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] - b = f1(a) - end subroutine test14 - - ! Test elemental intrinsic function (abs) - ! CHECK-LABEL: func @_QPtest15( - ! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) - subroutine test15(a,b) - ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - real :: a(100), b(100) - ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { - ! CHECK: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK: %[[fres:.*]] = fir.call @llvm.fabs.f32(%[[val]]) : (f32) -> f32 - ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> - ! CHECK: fir.result %[[res]] : !fir.array<100xf32> - ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] - b = abs(a) - end subroutine test15 - - ! Test elemental call to function f2 with VALUE attribute - ! CHECK-LABEL: func @_QPtest16( - ! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) - subroutine test16(a,b) - ! CHECK: %[[tmp:.*]] = fir.alloca f32 {adapt.valuebyref - ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - interface - real elemental function f2(i) - real, VALUE :: i - end function f2 - end interface - real :: a(100), b(100) - ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { - ! CHECK: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK: fir.store %[[val]] to %[[tmp]] - ! CHECK: %[[fres:.*]] = fir.call @_QPf2(%[[tmp]]) : (!fir.ref) -> f32 - ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> - ! CHECK: fir.result %[[res]] : !fir.array<100xf32> - ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] - b = f2(a) - end subroutine test16 - - ! Test elemental impure call to function f3. - ! - ! CHECK-LABEL: func @_QPtest17( - ! CHECK-SAME: %[[a:[^:]+]]: !fir.ref>{{.*}}, %[[b:[^:]+]]: !fir.ref>{{.*}}, %[[c:.*]]: !fir.ref>{{.*}}) - subroutine test17(a,b,c) - ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> - ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shapeshift<1>) -> !fir.array<100xf32> - interface - real elemental impure function f3(i,j,k) - real, intent(inout) :: i, j, k - end function f3 - end interface - real :: a(100), b(2:101), c(3:102) - ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { - ! CHECK-DAG: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK-DAG: %[[ic:.*]] = arith.addi %[[i]], %c3{{.*}} : index - ! CHECK-DAG: %[[ccoor:.*]] = fir.array_coor %[[c]](%{{.*}}) %[[ic]] : (!fir.ref>, !fir.shapeshift<1>, index) -> !fir.ref - ! CHECK-DAG: %[[ib:.*]] = arith.addi %[[i]], %c2{{.*}} : index - ! CHECK-DAG: %[[bcoor:.*]] = fir.array_coor %[[b]](%{{.*}}) %[[ib]] : (!fir.ref>, !fir.shapeshift<1>, index) -> !fir.ref - ! CHECK-DAG: %[[ia:.*]] = arith.addi %[[i]], %c1{{.*}} : index - ! CHECK-DAG: %[[acoor:.*]] = fir.array_coor %[[a]](%{{.*}}) %[[ia]] : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref - ! CHECK: %[[fres:.*]] = fir.call @_QPf3(%[[ccoor]], %[[bcoor]], %[[acoor]]) : (!fir.ref, !fir.ref, !fir.ref) -> f32 - ! CHECK: %[[fadd:.*]] = arith.addf %[[val]], %[[fres]] : f32 - ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fadd]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> - - ! See 10.1.4.p2 note 1. The expression below is illegal if `f3` defines the - ! argument `a` for this statement. Since, this cannot be proven statically by - ! the compiler, the constraint is left to the user. The compiler may give a - ! warning that `k` is neither VALUE nor INTENT(IN) and the actual argument, - ! `a`, appears elsewhere in the same statement. - b = a + f3(c, b, a) - - ! CHECK: fir.result %[[res]] : !fir.array<100xf32> - ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] - end subroutine test17 - - ! CHECK-LABEL: func @_QPtest18() { - ! CHECK: %[[VAL_0:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_1:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.array<10x10xi32> {bindc_name = "array", fir.target, uniq_name = "_QFtest18Earray"} - ! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest18Ei"} - ! CHECK: %[[VAL_4:.*]] = fir.alloca !fir.box>> {bindc_name = "row_i", uniq_name = "_QFtest18Erow_i"} - ! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.ptr> - ! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> - ! CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref>>> - ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> i64 - ! CHECK: %[[VAL_12:.*]] = fir.undefined index - ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> index - ! CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_9]], %[[VAL_1]] : index - ! CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_15]], %[[VAL_9]] : index - ! CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_0]], %[[VAL_1]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_18:.*]] = fir.slice %[[VAL_11]], %[[VAL_12]], %[[VAL_12]], %[[VAL_9]], %[[VAL_16]], %[[VAL_14]] : (i64, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_2]](%[[VAL_17]]) {{\[}}%[[VAL_18]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.box> - ! CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>) -> !fir.box>> - ! CHECK: fir.store %[[VAL_20]] to %[[VAL_4]] : !fir.ref>>> - ! CHECK: return - ! CHECK: } - - subroutine test18 - integer, target :: array(10,10) - integer, pointer :: row_i(:) - row_i => array(i, :) - end subroutine test18 - - ! CHECK-LABEL: func @_QPtest_column_and_row_order( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}) { - ! CHECK: %[[VAL_1:.*]] = arith.constant 2 : index - ! CHECK: %[[VAL_2:.*]] = arith.constant 3 : index - ! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_4:.*]] = fir.array_load %[[VAL_0]](%[[VAL_3]]) : (!fir.ref>, !fir.shape<2>) -> !fir.array<2x3xf32> - ! CHECK: %[[VAL_5:.*]] = arith.constant 42 : i32 - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> f32 - ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_1]], %[[VAL_7]] : index - ! CHECK: %[[VAL_10:.*]] = arith.subi %[[VAL_2]], %[[VAL_7]] : index - ! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_8]] to %[[VAL_10]] step %[[VAL_7]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_4]]) -> (!fir.array<2x3xf32>) { - ! CHECK: %[[VAL_14:.*]] = fir.do_loop %[[VAL_15:.*]] = %[[VAL_8]] to %[[VAL_9]] step %[[VAL_7]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_13]]) -> (!fir.array<2x3xf32>) { - ! CHECK: %[[VAL_17:.*]] = fir.array_update %[[VAL_16]], %[[VAL_6]], %[[VAL_15]], %[[VAL_12]] : (!fir.array<2x3xf32>, f32, index, index) -> !fir.array<2x3xf32> - ! CHECK: fir.result %[[VAL_17]] : !fir.array<2x3xf32> - ! CHECK: } - ! CHECK: fir.result %[[VAL_18:.*]] : !fir.array<2x3xf32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_4]], %[[VAL_19:.*]] to %[[VAL_0]] : !fir.array<2x3xf32>, !fir.array<2x3xf32>, !fir.ref> - ! CHECK: return - ! CHECK: } - - subroutine test_column_and_row_order(x) - real :: x(2,3) - x = 42 - end subroutine - - ! CHECK-LABEL: func @_QPtest_assigning_to_assumed_shape_slices( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}) { - ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_2:.*]] = arith.constant 2 : i64 - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i64) -> index - ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_1]], %[[VAL_5]]#1 : index - ! CHECK: %[[VAL_7:.*]] = arith.subi %[[VAL_6]], %[[VAL_1]] : index - ! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_1]] : index - ! CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_9]], %[[VAL_3]] : index - ! CHECK: %[[VAL_11:.*]] = arith.divsi %[[VAL_10]], %[[VAL_3]] : index - ! CHECK: %[[VAL_12:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_8]] : index - ! CHECK: %[[VAL_13:.*]] = arith.select %[[VAL_12]], %[[VAL_11]], %[[VAL_8]] : index - ! CHECK: %[[VAL_14:.*]] = fir.slice %[[VAL_1]], %[[VAL_7]], %[[VAL_3]] : (index, index, index) -> !fir.slice<1> - ! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_0]] {{\[}}%[[VAL_14]]] : (!fir.box>, !fir.slice<1>) -> !fir.array - ! CHECK: %[[VAL_16:.*]] = arith.constant 42 : i32 - ! CHECK: %[[VAL_17:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_18:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_13]], %[[VAL_17]] : index - ! CHECK: %[[VAL_20:.*]] = fir.do_loop %[[VAL_21:.*]] = %[[VAL_18]] to %[[VAL_19]] step %[[VAL_17]] unordered iter_args(%[[VAL_22:.*]] = %[[VAL_15]]) -> (!fir.array) { - ! CHECK: %[[VAL_23:.*]] = fir.array_update %[[VAL_22]], %[[VAL_16]], %[[VAL_21]] : (!fir.array, i32, index) -> !fir.array - ! CHECK: fir.result %[[VAL_23]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_24:.*]] to %[[VAL_0]]{{\[}}%[[VAL_14]]] : !fir.array, !fir.array, !fir.box>, !fir.slice<1> - ! CHECK: return - ! CHECK: } - - subroutine test_assigning_to_assumed_shape_slices(x) - integer :: x(:) - x(::2) = 42 - end subroutine - - ! CHECK-LABEL: func @_QPtest19a( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { - ! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_7:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_3]](%[[VAL_8]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<10x!fir.char<1,10>> - ! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_6]](%[[VAL_10]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<10x!fir.char<1,10>> - ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_4]], %[[VAL_12]] : index - ! CHECK: %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_13]] to %[[VAL_14]] step %[[VAL_12]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_9]]) -> (!fir.array<10x!fir.char<1,10>>) { - ! CHECK: %[[VAL_18:.*]] = fir.array_access %[[VAL_11]], %[[VAL_16]] : (!fir.array<10x!fir.char<1,10>>, index) -> !fir.ref> - ! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_17]], %[[VAL_16]] : (!fir.array<10x!fir.char<1,10>>, index) -> !fir.ref> - ! CHECK: %[[VAL_20:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_21:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (index) -> i64 - ! CHECK: %[[VAL_23:.*]] = arith.muli %[[VAL_21]], %[[VAL_22]] : i64 - ! CHECK: %[[VAL_24:.*]] = arith.constant false - ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_25]], %[[VAL_26]], %[[VAL_23]], %[[VAL_24]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_27:.*]] = fir.array_amend %[[VAL_17]], %[[VAL_19]] : (!fir.array<10x!fir.char<1,10>>, !fir.ref>) -> !fir.array<10x!fir.char<1,10>> - ! CHECK: fir.result %[[VAL_27]] : !fir.array<10x!fir.char<1,10>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_28:.*]] to %[[VAL_3]] : !fir.array<10x!fir.char<1,10>>, !fir.array<10x!fir.char<1,10>>, !fir.ref>> - ! CHECK: return - ! CHECK: } - - subroutine test19a(a,b) - character(LEN=10) a(10) - character(LEN=10) b(10) - a = b - end subroutine test19a - - ! CHECK-LABEL: func @_QPtest19b( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<2>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<2>{{.*}}) { - ! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<2>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_4:.*]] = arith.constant 20 : index - ! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<2>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_6:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_8:.*]] = arith.constant 20 : index - ! CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_10:.*]] = fir.array_load %[[VAL_3]](%[[VAL_9]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<20x!fir.char<2,8>> - ! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_12:.*]] = fir.array_load %[[VAL_7]](%[[VAL_11]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<20x!fir.char<2,10>> - ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_14:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_4]], %[[VAL_13]] : index - ! CHECK: %[[VAL_16:.*]] = fir.do_loop %[[VAL_17:.*]] = %[[VAL_14]] to %[[VAL_15]] step %[[VAL_13]] unordered iter_args(%[[VAL_18:.*]] = %[[VAL_10]]) -> (!fir.array<20x!fir.char<2,8>>) { - ! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_12]], %[[VAL_17]] : (!fir.array<20x!fir.char<2,10>>, index) -> !fir.ref> - ! CHECK: %[[VAL_20:.*]] = fir.array_access %[[VAL_18]], %[[VAL_17]] : (!fir.array<20x!fir.char<2,8>>, index) -> !fir.ref> - ! CHECK: %[[VAL_21:.*]] = arith.constant 8 : index - ! CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_21]], %[[VAL_6]] : index - ! CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_21]], %[[VAL_6]] : index - ! CHECK: %[[VAL_24:.*]] = arith.constant 2 : i64 - ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_23]] : (index) -> i64 - ! CHECK: %[[VAL_26:.*]] = arith.muli %[[VAL_24]], %[[VAL_25]] : i64 - ! CHECK: %[[VAL_27:.*]] = arith.constant false - ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_28]], %[[VAL_29]], %[[VAL_26]], %[[VAL_27]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_30:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_31:.*]] = arith.subi %[[VAL_21]], %[[VAL_30]] : index - ! CHECK: %[[VAL_32:.*]] = arith.constant 32 : i16 - ! CHECK: %[[VAL_33:.*]] = fir.undefined !fir.char<2> - ! CHECK: %[[VAL_34:.*]] = fir.insert_value %[[VAL_33]], %[[VAL_32]], [0 : index] : (!fir.char<2>, i16) -> !fir.char<2> - ! CHECK: %[[VAL_35:.*]] = arith.constant 1 : index - ! CHECK: fir.do_loop %[[VAL_36:.*]] = %[[VAL_23]] to %[[VAL_31]] step %[[VAL_35]] { - ! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_38:.*]] = fir.coordinate_of %[[VAL_37]], %[[VAL_36]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_34]] to %[[VAL_38]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_39:.*]] = fir.array_amend %[[VAL_18]], %[[VAL_20]] : (!fir.array<20x!fir.char<2,8>>, !fir.ref>) -> !fir.array<20x!fir.char<2,8>> - ! CHECK: fir.result %[[VAL_39]] : !fir.array<20x!fir.char<2,8>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_10]], %[[VAL_40:.*]] to %[[VAL_3]] : !fir.array<20x!fir.char<2,8>>, !fir.array<20x!fir.char<2,8>>, !fir.ref>> - ! CHECK: return - ! CHECK: } - - subroutine test19b(a,b) - character(KIND=2, LEN=8) a(20) - character(KIND=2, LEN=10) b(20) - a = b - end subroutine test19b - - ! CHECK-LABEL: func @_QPtest19c( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<4>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<4>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { - ! CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<4>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_6:.*]] = arith.constant 30 : index - ! CHECK: %[[VAL_7:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<4>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : i32 - ! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : i32 - ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_13:.*]] = arith.constant 30 : index - ! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_12]](%[[VAL_14]]) typeparams %[[VAL_11]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<30x!fir.char<4,?>> - ! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_5]](%[[VAL_16]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<30x!fir.char<4,10>> - ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_19:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_13]], %[[VAL_18]] : index - ! CHECK: %[[VAL_21:.*]] = fir.do_loop %[[VAL_22:.*]] = %[[VAL_19]] to %[[VAL_20]] step %[[VAL_18]] unordered iter_args(%[[VAL_23:.*]] = %[[VAL_15]]) -> (!fir.array<30x!fir.char<4,?>>) { - ! CHECK: %[[VAL_24:.*]] = fir.array_access %[[VAL_17]], %[[VAL_22]] : (!fir.array<30x!fir.char<4,10>>, index) -> !fir.ref> - ! CHECK: %[[VAL_25:.*]] = fir.array_access %[[VAL_23]], %[[VAL_22]] typeparams %[[VAL_11]] : (!fir.array<30x!fir.char<4,?>>, index, i32) -> !fir.ref> - ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_11]] : (i32) -> index - ! CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_26]], %[[VAL_4]] : index - ! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_26]], %[[VAL_4]] : index - ! CHECK: %[[VAL_29:.*]] = arith.constant 4 : i64 - ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (index) -> i64 - ! CHECK: %[[VAL_31:.*]] = arith.muli %[[VAL_29]], %[[VAL_30]] : i64 - ! CHECK: %[[VAL_32:.*]] = arith.constant false - ! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_25]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_24]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_33]], %[[VAL_34]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_35:.*]] = arith.constant 1 : i32 - ! CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_11]], %[[VAL_35]] : i32 - ! CHECK: %[[VAL_37:.*]] = arith.constant 32 : i32 - ! CHECK: %[[VAL_38:.*]] = fir.undefined !fir.char<4> - ! CHECK: %[[VAL_39:.*]] = fir.insert_value %[[VAL_38]], %[[VAL_37]], [0 : index] : (!fir.char<4>, i32) -> !fir.char<4> - ! CHECK: %[[VAL_40:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_36]] : (i32) -> index - ! CHECK: fir.do_loop %[[VAL_42:.*]] = %[[VAL_28]] to %[[VAL_41]] step %[[VAL_40]] { - ! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_25]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_44:.*]] = fir.coordinate_of %[[VAL_43]], %[[VAL_42]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_39]] to %[[VAL_44]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_45:.*]] = fir.array_amend %[[VAL_23]], %[[VAL_25]] : (!fir.array<30x!fir.char<4,?>>, !fir.ref>) -> !fir.array<30x!fir.char<4,?>> - ! CHECK: fir.result %[[VAL_45]] : !fir.array<30x!fir.char<4,?>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_46:.*]] to %[[VAL_12]] typeparams %[[VAL_11]] : !fir.array<30x!fir.char<4,?>>, !fir.array<30x!fir.char<4,?>>, !fir.ref>>, i32 - ! CHECK: return - ! CHECK: } - - subroutine test19c(a,b,i) - character(KIND=4, LEN=i) a(30) - character(KIND=4, LEN=10) b(30) - a = b - end subroutine test19c - - ! CHECK-LABEL: func @_QPtest19d( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref{{.*}}) { - ! CHECK: %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : i32 - ! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : i32 - ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_10:.*]] = arith.constant 40 : index - ! CHECK: %[[VAL_11:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_13:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_12]], %[[VAL_13]] : i32 - ! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_14]], %[[VAL_12]], %[[VAL_13]] : i32 - ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_11]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_17:.*]] = arith.constant 40 : index - ! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_19:.*]] = fir.array_load %[[VAL_9]](%[[VAL_18]]) typeparams %[[VAL_8]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<40x!fir.char<1,?>> - ! CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_17]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_21:.*]] = fir.array_load %[[VAL_16]](%[[VAL_20]]) typeparams %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<40x!fir.char<1,?>> - ! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_23:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_10]], %[[VAL_22]] : index - ! CHECK: %[[VAL_25:.*]] = fir.do_loop %[[VAL_26:.*]] = %[[VAL_23]] to %[[VAL_24]] step %[[VAL_22]] unordered iter_args(%[[VAL_27:.*]] = %[[VAL_19]]) -> (!fir.array<40x!fir.char<1,?>>) { - ! CHECK: %[[VAL_28:.*]] = fir.array_access %[[VAL_21]], %[[VAL_26]] typeparams %[[VAL_15]] : (!fir.array<40x!fir.char<1,?>>, index, i32) -> !fir.ref> - ! CHECK: %[[VAL_29:.*]] = fir.array_access %[[VAL_27]], %[[VAL_26]] typeparams %[[VAL_8]] : (!fir.array<40x!fir.char<1,?>>, index, i32) -> !fir.ref> - ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_8]] : (i32) -> index - ! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_15]] : (i32) -> index - ! CHECK: %[[VAL_32:.*]] = arith.cmpi slt, %[[VAL_30]], %[[VAL_31]] : index - ! CHECK: %[[VAL_33:.*]] = arith.select %[[VAL_32]], %[[VAL_30]], %[[VAL_31]] : index - ! CHECK: %[[VAL_34:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_33]] : (index) -> i64 - ! CHECK: %[[VAL_36:.*]] = arith.muli %[[VAL_34]], %[[VAL_35]] : i64 - ! CHECK: %[[VAL_37:.*]] = arith.constant false - ! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_28]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_38]], %[[VAL_39]], %[[VAL_36]], %[[VAL_37]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_40:.*]] = arith.constant 1 : i32 - ! CHECK: %[[VAL_41:.*]] = arith.subi %[[VAL_8]], %[[VAL_40]] : i32 - ! CHECK: %[[VAL_42:.*]] = arith.constant 32 : i8 - ! CHECK: %[[VAL_43:.*]] = fir.undefined !fir.char<1> - ! CHECK: %[[VAL_44:.*]] = fir.insert_value %[[VAL_43]], %[[VAL_42]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> - ! CHECK: %[[VAL_45:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_41]] : (i32) -> index - ! CHECK: fir.do_loop %[[VAL_47:.*]] = %[[VAL_33]] to %[[VAL_46]] step %[[VAL_45]] { - ! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_49:.*]] = fir.coordinate_of %[[VAL_48]], %[[VAL_47]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_44]] to %[[VAL_49]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_50:.*]] = fir.array_amend %[[VAL_27]], %[[VAL_29]] : (!fir.array<40x!fir.char<1,?>>, !fir.ref>) -> !fir.array<40x!fir.char<1,?>> - ! CHECK: fir.result %[[VAL_50]] : !fir.array<40x!fir.char<1,?>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_19]], %[[VAL_51:.*]] to %[[VAL_9]] typeparams %[[VAL_8]] : !fir.array<40x!fir.char<1,?>>, !fir.array<40x!fir.char<1,?>>, !fir.ref>>, i32 - ! CHECK: return - ! CHECK: } - - subroutine test19d(a,b,i,j) - character(i) a(40) - character(j) b(40) - a = b - end subroutine test19d - - ! CHECK-LABEL: func @_QPtest19e( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { - ! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_4:.*]] = arith.constant 50 : index - ! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_7:.*]] = arith.constant 50 : index - ! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_3]](%[[VAL_8]]) typeparams %[[VAL_2]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<50x!fir.char<1,?>> - ! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_6]](%[[VAL_10]]) typeparams %[[VAL_5]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<50x!fir.char<1,?>> - ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_4]], %[[VAL_12]] : index - ! CHECK: %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_13]] to %[[VAL_14]] step %[[VAL_12]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_9]]) -> (!fir.array<50x!fir.char<1,?>>) { - ! CHECK: %[[VAL_18:.*]] = fir.array_access %[[VAL_11]], %[[VAL_16]] typeparams %[[VAL_5]]#1 : (!fir.array<50x!fir.char<1,?>>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_17]], %[[VAL_16]] typeparams %[[VAL_2]]#1 : (!fir.array<50x!fir.char<1,?>>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_2]]#1, %[[VAL_5]]#1 : index - ! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_20]], %[[VAL_2]]#1, %[[VAL_5]]#1 : index - ! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (index) -> i64 - ! CHECK: %[[VAL_24:.*]] = arith.muli %[[VAL_22]], %[[VAL_23]] : i64 - ! CHECK: %[[VAL_25:.*]] = arith.constant false - ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_26]], %[[VAL_27]], %[[VAL_24]], %[[VAL_25]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_28:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_2]]#1, %[[VAL_28]] : index - ! CHECK: %[[VAL_30:.*]] = arith.constant 32 : i8 - ! CHECK: %[[VAL_31:.*]] = fir.undefined !fir.char<1> - ! CHECK: %[[VAL_32:.*]] = fir.insert_value %[[VAL_31]], %[[VAL_30]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> - ! CHECK: %[[VAL_33:.*]] = arith.constant 1 : index - ! CHECK: fir.do_loop %[[VAL_34:.*]] = %[[VAL_21]] to %[[VAL_29]] step %[[VAL_33]] { - ! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_36:.*]] = fir.coordinate_of %[[VAL_35]], %[[VAL_34]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_32]] to %[[VAL_36]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_37:.*]] = fir.array_amend %[[VAL_17]], %[[VAL_19]] : (!fir.array<50x!fir.char<1,?>>, !fir.ref>) -> !fir.array<50x!fir.char<1,?>> - ! CHECK: fir.result %[[VAL_37]] : !fir.array<50x!fir.char<1,?>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_38:.*]] to %[[VAL_3]] typeparams %[[VAL_2]]#1 : !fir.array<50x!fir.char<1,?>>, !fir.array<50x!fir.char<1,?>>, !fir.ref>>, index - ! CHECK: return - ! CHECK: } - - subroutine test19e(a,b) - character(*) a(50) - character(*) b(50) - a = b - end subroutine test19e - - ! CHECK-LABEL: func @_QPtest19f( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { - ! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_4:.*]] = arith.constant 60 : index - ! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_7:.*]] = arith.constant 60 : index - ! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_3]](%[[VAL_8]]) typeparams %[[VAL_2]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<60x!fir.char<1,?>> - ! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QQcl.70726566697820) : !fir.ref> - ! CHECK: %[[VAL_11:.*]] = arith.constant 7 : index - ! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_13:.*]] = fir.array_load %[[VAL_6]](%[[VAL_12]]) typeparams %[[VAL_5]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<60x!fir.char<1,?>> - ! CHECK: %[[VAL_14:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_4]], %[[VAL_14]] : index - ! CHECK: %[[VAL_17:.*]] = fir.do_loop %[[VAL_18:.*]] = %[[VAL_15]] to %[[VAL_16]] step %[[VAL_14]] unordered iter_args(%[[VAL_19:.*]] = %[[VAL_9]]) -> (!fir.array<60x!fir.char<1,?>>) { - ! CHECK: %[[VAL_20:.*]] = fir.array_access %[[VAL_13]], %[[VAL_18]] typeparams %[[VAL_5]]#1 : (!fir.array<60x!fir.char<1,?>>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_11]], %[[VAL_5]]#1 : index - ! CHECK: %[[VAL_22:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_21]] : index) {bindc_name = ".chrtmp"} - ! CHECK: %[[VAL_23:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_11]] : (index) -> i64 - ! CHECK: %[[VAL_25:.*]] = arith.muli %[[VAL_23]], %[[VAL_24]] : i64 - ! CHECK: %[[VAL_26:.*]] = arith.constant false - ! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_27]], %[[VAL_28]], %[[VAL_25]], %[[VAL_26]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_21]], %[[VAL_29]] : index - ! CHECK: fir.do_loop %[[VAL_31:.*]] = %[[VAL_11]] to %[[VAL_30]] step %[[VAL_29]] { - ! CHECK: %[[VAL_32:.*]] = arith.subi %[[VAL_31]], %[[VAL_11]] : index - ! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_34:.*]] = fir.coordinate_of %[[VAL_33]], %[[VAL_32]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: %[[VAL_35:.*]] = fir.load %[[VAL_34]] : !fir.ref> - ! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_37:.*]] = fir.coordinate_of %[[VAL_36]], %[[VAL_31]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_35]] to %[[VAL_37]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_38:.*]] = fir.array_access %[[VAL_19]], %[[VAL_18]] typeparams %[[VAL_2]]#1 : (!fir.array<60x!fir.char<1,?>>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_39:.*]] = arith.cmpi slt, %[[VAL_2]]#1, %[[VAL_21]] : index - ! CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_39]], %[[VAL_2]]#1, %[[VAL_21]] : index - ! CHECK: %[[VAL_41:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_40]] : (index) -> i64 - ! CHECK: %[[VAL_43:.*]] = arith.muli %[[VAL_41]], %[[VAL_42]] : i64 - ! CHECK: %[[VAL_44:.*]] = arith.constant false - ! CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_38]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_45]], %[[VAL_46]], %[[VAL_43]], %[[VAL_44]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_47:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_48:.*]] = arith.subi %[[VAL_2]]#1, %[[VAL_47]] : index - ! CHECK: %[[VAL_49:.*]] = arith.constant 32 : i8 - ! CHECK: %[[VAL_50:.*]] = fir.undefined !fir.char<1> - ! CHECK: %[[VAL_51:.*]] = fir.insert_value %[[VAL_50]], %[[VAL_49]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> - ! CHECK: %[[VAL_52:.*]] = arith.constant 1 : index - ! CHECK: fir.do_loop %[[VAL_53:.*]] = %[[VAL_40]] to %[[VAL_48]] step %[[VAL_52]] { - ! CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_38]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_55:.*]] = fir.coordinate_of %[[VAL_54]], %[[VAL_53]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_51]] to %[[VAL_55]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_56:.*]] = fir.array_amend %[[VAL_19]], %[[VAL_38]] : (!fir.array<60x!fir.char<1,?>>, !fir.ref>) -> !fir.array<60x!fir.char<1,?>> - ! CHECK: fir.result %[[VAL_56]] : !fir.array<60x!fir.char<1,?>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_57:.*]] to %[[VAL_3]] typeparams %[[VAL_2]]#1 : !fir.array<60x!fir.char<1,?>>, !fir.array<60x!fir.char<1,?>>, !fir.ref>>, index - ! CHECK: return - ! CHECK: } - - subroutine test19f(a,b) - character(*) a(60) - character(*) b(60) - a = "prefix " // b - end subroutine test19f - - ! CHECK-LABEL: func @_QPtest19g( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<4>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<2>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { - ! CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<2>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_4:.*]] = arith.constant 13 : index - ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_6:.*]] = arith.constant 140 : index - ! CHECK: %[[VAL_7:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<4>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : i32 - ! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : i32 - ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_13:.*]] = arith.constant 70 : index - ! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_12]](%[[VAL_14]]) typeparams %[[VAL_11]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<70x!fir.char<4,?>> - ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index - ! CHECK: %[[VAL_18:.*]] = arith.constant 2 : i64 - ! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i64) -> index - ! CHECK: %[[VAL_20:.*]] = arith.constant 140 : i64 - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index - ! CHECK: %[[VAL_22:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_23:.*]] = fir.slice %[[VAL_17]], %[[VAL_21]], %[[VAL_19]] : (index, index, index) -> !fir.slice<1> - ! CHECK: %[[VAL_24:.*]] = fir.array_load %[[VAL_5]](%[[VAL_22]]) {{\[}}%[[VAL_23]]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<140x!fir.char<2,13>> - ! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> i64 - ! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_13]], %[[VAL_27]] : index - ! CHECK: %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_28]] to %[[VAL_29]] step %[[VAL_27]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_15]]) -> (!fir.array<70x!fir.char<4,?>>) { - ! CHECK: %[[VAL_33:.*]] = fir.array_access %[[VAL_24]], %[[VAL_31]] : (!fir.array<140x!fir.char<2,13>>, index) -> !fir.ref> - ! CHECK: %[[VAL_34:.*]] = fir.alloca !fir.char<4,?>(%[[VAL_4]] : index) - ! CHECK: %[[VAL_35:.*]] = arith.cmpi slt, %[[VAL_4]], %[[VAL_4]] : index - ! CHECK: %[[VAL_36:.*]] = arith.select %[[VAL_35]], %[[VAL_4]], %[[VAL_4]] : index - ! CHECK: fir.char_convert %[[VAL_33]] for %[[VAL_36]] to %[[VAL_34]] : !fir.ref>, index, !fir.ref> - ! CHECK: %[[VAL_37:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_4]], %[[VAL_37]] : index - ! CHECK: %[[VAL_39:.*]] = arith.constant 32 : i32 - ! CHECK: %[[VAL_40:.*]] = fir.undefined !fir.char<4> - ! CHECK: %[[VAL_41:.*]] = fir.insert_value %[[VAL_40]], %[[VAL_39]], [0 : index] : (!fir.char<4>, i32) -> !fir.char<4> - ! CHECK: %[[VAL_42:.*]] = arith.constant 1 : index - ! CHECK: fir.do_loop %[[VAL_43:.*]] = %[[VAL_36]] to %[[VAL_38]] step %[[VAL_42]] { - ! CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_45:.*]] = fir.coordinate_of %[[VAL_44]], %[[VAL_43]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_41]] to %[[VAL_45]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_46:.*]] = fir.array_access %[[VAL_32]], %[[VAL_31]] typeparams %[[VAL_11]] : (!fir.array<70x!fir.char<4,?>>, index, i32) -> !fir.ref> - ! CHECK: %[[VAL_47:.*]] = fir.convert %[[VAL_11]] : (i32) -> index - ! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_26]] : (i64) -> index - ! CHECK: %[[VAL_49:.*]] = arith.cmpi slt, %[[VAL_47]], %[[VAL_48]] : index - ! CHECK: %[[VAL_50:.*]] = arith.select %[[VAL_49]], %[[VAL_47]], %[[VAL_48]] : index - ! CHECK: %[[VAL_51:.*]] = arith.constant 4 : i64 - ! CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_50]] : (index) -> i64 - ! CHECK: %[[VAL_53:.*]] = arith.muli %[[VAL_51]], %[[VAL_52]] : i64 - ! CHECK: %[[VAL_54:.*]] = arith.constant false - ! CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_46]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_55]], %[[VAL_56]], %[[VAL_53]], %[[VAL_54]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_57:.*]] = arith.constant 1 : i32 - ! CHECK: %[[VAL_58:.*]] = arith.subi %[[VAL_11]], %[[VAL_57]] : i32 - ! CHECK: %[[VAL_59:.*]] = arith.constant 32 : i32 - ! CHECK: %[[VAL_60:.*]] = fir.undefined !fir.char<4> - ! CHECK: %[[VAL_61:.*]] = fir.insert_value %[[VAL_60]], %[[VAL_59]], [0 : index] : (!fir.char<4>, i32) -> !fir.char<4> - ! CHECK: %[[VAL_62:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_63:.*]] = fir.convert %[[VAL_58]] : (i32) -> index - ! CHECK: fir.do_loop %[[VAL_64:.*]] = %[[VAL_50]] to %[[VAL_63]] step %[[VAL_62]] { - ! CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_46]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_66:.*]] = fir.coordinate_of %[[VAL_65]], %[[VAL_64]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_61]] to %[[VAL_66]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_67:.*]] = fir.array_amend %[[VAL_32]], %[[VAL_46]] : (!fir.array<70x!fir.char<4,?>>, !fir.ref>) -> !fir.array<70x!fir.char<4,?>> - ! CHECK: fir.result %[[VAL_67]] : !fir.array<70x!fir.char<4,?>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_68:.*]] to %[[VAL_12]] typeparams %[[VAL_11]] : !fir.array<70x!fir.char<4,?>>, !fir.array<70x!fir.char<4,?>>, !fir.ref>>, i32 - ! CHECK: return - ! CHECK: } - - subroutine test19g(a,b,i) - character(kind=4,len=i) a(70) - character(kind=2,len=13) b(140) - a = b(1:140:2) - end subroutine test19g - - ! CHECK-LABEL: func @_QPtest19h( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref{{.*}}) { - ! CHECK: %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : i32 - ! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : i32 - ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_10:.*]] = arith.constant 70 : index - ! CHECK: %[[VAL_11:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i32) -> i64 - ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index - ! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_9]](%[[VAL_16]]) typeparams %[[VAL_8]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<70x!fir.char<1,?>> - ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i64) -> index - ! CHECK: %[[VAL_20:.*]] = arith.constant 2 : i64 - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index - ! CHECK: %[[VAL_22:.*]] = arith.constant 140 : i64 - ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index - ! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_25:.*]] = fir.slice %[[VAL_19]], %[[VAL_23]], %[[VAL_21]] : (index, index, index) -> !fir.slice<1> - ! CHECK: %[[VAL_26:.*]] = fir.array_load %[[VAL_12]](%[[VAL_24]]) {{\[}}%[[VAL_25]]] typeparams %[[VAL_11]]#1 : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.array> - ! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_10]], %[[VAL_27]] : index - ! CHECK: %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_28]] to %[[VAL_29]] step %[[VAL_27]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_17]]) -> (!fir.array<70x!fir.char<1,?>>) { - ! CHECK: %[[VAL_33:.*]] = fir.array_access %[[VAL_26]], %[[VAL_31]] typeparams %[[VAL_11]]#1 : (!fir.array>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_34:.*]] = fir.array_access %[[VAL_32]], %[[VAL_31]] typeparams %[[VAL_8]] : (!fir.array<70x!fir.char<1,?>>, index, i32) -> !fir.ref> - ! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_8]] : (i32) -> index - ! CHECK: %[[VAL_36:.*]] = arith.cmpi slt, %[[VAL_35]], %[[VAL_11]]#1 : index - ! CHECK: %[[VAL_37:.*]] = arith.select %[[VAL_36]], %[[VAL_35]], %[[VAL_11]]#1 : index - ! CHECK: %[[VAL_38:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (index) -> i64 - ! CHECK: %[[VAL_40:.*]] = arith.muli %[[VAL_38]], %[[VAL_39]] : i64 - ! CHECK: %[[VAL_41:.*]] = arith.constant false - ! CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref - ! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_42]], %[[VAL_43]], %[[VAL_40]], %[[VAL_41]]) : (!fir.ref, !fir.ref, i64, i1) -> () - ! CHECK: %[[VAL_44:.*]] = arith.constant 1 : i32 - ! CHECK: %[[VAL_45:.*]] = arith.subi %[[VAL_8]], %[[VAL_44]] : i32 - ! CHECK: %[[VAL_46:.*]] = arith.constant 32 : i8 - ! CHECK: %[[VAL_47:.*]] = fir.undefined !fir.char<1> - ! CHECK: %[[VAL_48:.*]] = fir.insert_value %[[VAL_47]], %[[VAL_46]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> - ! CHECK: %[[VAL_49:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_45]] : (i32) -> index - ! CHECK: fir.do_loop %[[VAL_51:.*]] = %[[VAL_37]] to %[[VAL_50]] step %[[VAL_49]] { - ! CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_53:.*]] = fir.coordinate_of %[[VAL_52]], %[[VAL_51]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: fir.store %[[VAL_48]] to %[[VAL_53]] : !fir.ref> - ! CHECK: } - ! CHECK: %[[VAL_54:.*]] = fir.array_amend %[[VAL_32]], %[[VAL_34]] : (!fir.array<70x!fir.char<1,?>>, !fir.ref>) -> !fir.array<70x!fir.char<1,?>> - ! CHECK: fir.result %[[VAL_54]] : !fir.array<70x!fir.char<1,?>> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_17]], %[[VAL_55:.*]] to %[[VAL_9]] typeparams %[[VAL_8]] : !fir.array<70x!fir.char<1,?>>, !fir.array<70x!fir.char<1,?>>, !fir.ref>>, i32 - ! CHECK: return - ! CHECK: } - - subroutine test19h(a,b,i,j) - character(i) a(70) - character(*) b(j) - a = b(1:140:2) - end subroutine test19h - - ! CHECK-LABEL: func @_QPtest_elemental_character_intrinsic( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { - ! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_7:.*]] = arith.constant 2 : index - ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_9:.*]] = arith.constant -1 : i32 - ! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_12:.*]] = arith.constant {{.*}} : i32 - ! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_9]], %[[VAL_11]], %[[VAL_12]]) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_15:.*]] = arith.constant 10 : index - ! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_17:.*]] = fir.shape_shift %[[VAL_7]], %[[VAL_8]] : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<10xi32> - ! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_18]](%[[VAL_19]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array<10xi32> - ! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_22:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_15]], %[[VAL_21]] : index - ! CHECK: %[[VAL_24:.*]] = fir.do_loop %[[VAL_25:.*]] = %[[VAL_22]] to %[[VAL_23]] step %[[VAL_21]] unordered iter_args(%[[VAL_26:.*]] = %[[VAL_20]]) -> (!fir.array<10xi32>) { - ! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_25]], %[[VAL_27]] : index - ! CHECK: %[[VAL_29:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_16]]) %[[VAL_28]] typeparams %[[VAL_2]]#1 : (!fir.ref>>, !fir.shape<1>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_25]], %[[VAL_7]] : index - ! CHECK: %[[VAL_31:.*]] = fir.array_coor %[[VAL_6]](%[[VAL_17]]) %[[VAL_30]] typeparams %[[VAL_5]]#1 : (!fir.ref>>, !fir.shapeshift<1>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_32:.*]] = arith.constant false - ! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_2]]#1 : (index) -> i64 - ! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_31]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_5]]#1 : (index) -> i64 - ! CHECK: %[[VAL_37:.*]] = fir.call @_FortranAScan1(%[[VAL_33]], %[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_32]]) : (!fir.ref, i64, !fir.ref, i64, i1) -> i64 - ! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (i64) -> i32 - ! CHECK: %[[VAL_39:.*]] = fir.array_update %[[VAL_26]], %[[VAL_38]], %[[VAL_25]] : (!fir.array<10xi32>, i32, index) -> !fir.array<10xi32> - ! CHECK: fir.result %[[VAL_39]] : !fir.array<10xi32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_20]], %[[VAL_40:.*]] to %[[VAL_18]] : !fir.array<10xi32>, !fir.array<10xi32>, !fir.heap> - ! CHECK: %[[VAL_41:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_42:.*]] = fir.embox %[[VAL_18]](%[[VAL_41]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_42]] : (!fir.box>) -> !fir.box - ! CHECK: %[[VAL_44:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_13]], %[[VAL_43]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_18]] - ! CHECK: %[[VAL_45:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_13]]) : (!fir.ref) -> i32 - ! CHECK: return - ! CHECK: } - - subroutine test_elemental_character_intrinsic(c1, c2) - character(*) :: c1(10), c2(2:11) - print *, scan(c1, c2) - end subroutine - - ! CHECK: func private @_QPbar( + integer :: n + real, intent(out) :: a(n) + real, intent(in) :: b(n), c(n) + ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% + ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% + ! CHECK-DAG: %[[C:.*]] = fir.array_load %arg2(% + ! CHECK: %[[T:.*]] = fir.do_loop + ! CHECK-DAG: %[[Bi:.*]] = fir.array_fetch %[[B]] + ! CHECK-DAG: %[[Ci:.*]] = fir.array_fetch %[[C]] + ! CHECK: %[[rv:.*]] = arith.addf %[[Bi]], %[[Ci]] + ! CHECK: fir.array_update %{{.*}}, %[[rv]], % + a = b + c + ! CHECK: fir.array_merge_store %[[A]], %[[T]] to %arg0 +end subroutine test1 + +! CHECK-LABEL: func @_QPtest1b +subroutine test1b(a,b,c,d,n) + integer :: n + real, intent(out) :: a(n) + real, intent(in) :: b(n), c(n), d(n) + ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% + ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% + ! CHECK-DAG: %[[C:.*]] = fir.array_load %arg2(% + ! CHECK-DAG: %[[D:.*]] = fir.array_load %arg3(% + ! CHECK: %[[T:.*]] = fir.do_loop + ! CHECK-DAG: %[[Bi:.*]] = fir.array_fetch %[[B]] + ! CHECK-DAG: %[[Ci:.*]] = fir.array_fetch %[[C]] + ! CHECK: %[[rv1:.*]] = arith.addf %[[Bi]], %[[Ci]] + ! CHECK: %[[Di:.*]] = fir.array_fetch %[[D]] + ! CHECK: %[[rv:.*]] = arith.addf %[[rv1]], %[[Di]] + ! CHECK: fir.array_update %{{.*}}, %[[rv]], % + a = b + c + d + ! CHECK: fir.array_merge_store %[[A]], %[[T]] to %arg0 +end subroutine test1b + +! CHECK-LABEL: func @_QPtest2( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}, %[[VAL_1:.*]]: !fir.box>{{.*}}, %[[VAL_2:.*]]: !fir.box>{{.*}}) { +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_5:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_6:.*]] = fir.array_load %[[VAL_1]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_7:.*]] = fir.array_load %[[VAL_2]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_10:.*]] = arith.subi %[[VAL_4]]#1, %[[VAL_8]] : index +! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_9]] to %[[VAL_10]] step %[[VAL_8]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_5]]) -> (!fir.array) { +! CHECK: %[[VAL_14:.*]] = fir.array_fetch %[[VAL_6]], %[[VAL_12]] : (!fir.array, index) -> f32 +! CHECK: %[[VAL_15:.*]] = fir.array_fetch %[[VAL_7]], %[[VAL_12]] : (!fir.array, index) -> f32 +! CHECK: %[[VAL_16:.*]] = arith.addf %[[VAL_14]], %[[VAL_15]] : f32 +! CHECK: %[[VAL_17:.*]] = fir.array_update %[[VAL_13]], %[[VAL_16]], %[[VAL_12]] : (!fir.array, f32, index) -> !fir.array +! CHECK: fir.result %[[VAL_17]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_5]], %[[VAL_18:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> +! CHECK: return +! CHECK: } +subroutine test2(a,b,c) + real, intent(out) :: a(:) + real, intent(in) :: b(:), c(:) + a = b + c +end subroutine test2 + +! CHECK-LABEL: func @_QPtest3 +subroutine test3(a,b,c,n) + integer :: n + real, intent(out) :: a(n) + real, intent(in) :: b(n), c + ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% + ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% + ! CHECK-DAG: %[[C:.*]] = fir.load %arg2 + ! CHECK: %[[T:.*]] = fir.do_loop + ! CHECK: %[[Bi:.*]] = fir.array_fetch %[[B]] + ! CHECK: %[[rv:.*]] = arith.addf %[[Bi]], %[[C]] + ! CHECK: %[[Ti:.*]] = fir.array_update %{{.*}}, %[[rv]], % + ! CHECK: fir.result %[[Ti]] + a = b + c + ! CHECK: fir.array_merge_store %[[A]], %[[T]] to %arg0 +end subroutine test3 + +! CHECK-LABEL: func @_QPtest4 +subroutine test4(a,b,c) +! TODO: this declaration fails in CallInterface lowering +! real, allocatable, intent(out) :: a(:) + real :: a(100) ! FIXME: fake it for now + real, intent(in) :: b(:), c + ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% + ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1 + ! CHECK: fir.do_loop + ! CHECK: fir.array_fetch %[[B]], % + ! CHECK: fir.array_update + a = b + c + ! CHECK: fir.array_merge_store %[[A]], %{{.*}} to %arg0 +end subroutine test4 + +! CHECK-LABEL: func @_QPtest5 +subroutine test5(a,b,c) +! TODO: this declaration fails in CallInterface lowering +! real, allocatable, intent(out) :: a(:) +! real, pointer, intent(in) :: b(:) + real :: a(100), b(100) ! FIXME: fake it for now + real, intent(in) :: c + ! CHECK-DAG: %[[A:.*]] = fir.array_load %arg0(% + ! CHECK-DAG: %[[B:.*]] = fir.array_load %arg1(% + ! CHECK: fir.do_loop + ! CHECK: fir.array_fetch %[[B]], % + ! CHECK: fir.array_update + a = b + c + ! CHECK: fir.array_merge_store %[[A]], %{{.*}} to %arg0 +end subroutine test5 + +! CHECK-LABEL: func @_QPtest6( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref{{.*}}, %[[VAL_4:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> i64 +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> index +! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_4]] : !fir.ref +! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i32) -> i64 +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i64) -> index +! CHECK: %[[VAL_11:.*]] = arith.constant 3 : i64 +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index +! CHECK: %[[VAL_13:.*]] = arith.constant 4 : i64 +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> index +! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 +! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index +! CHECK: %[[VAL_18:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_17]], %[[VAL_12]] : index +! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_19]], %[[VAL_14]] : index +! CHECK: %[[VAL_21:.*]] = arith.divsi %[[VAL_20]], %[[VAL_14]] : index +! CHECK: %[[VAL_22:.*]] = arith.cmpi sgt, %[[VAL_21]], %[[VAL_18]] : index +! CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_21]], %[[VAL_18]] : index +! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_25:.*]] = fir.slice %[[VAL_12]], %[[VAL_17]], %[[VAL_14]] : (index, index, index) -> !fir.slice<1> +! CHECK: %[[VAL_26:.*]] = fir.array_load %[[VAL_0]](%[[VAL_24]]) {{\[}}%[[VAL_25]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.array +! CHECK: %[[VAL_27:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_28:.*]] = fir.array_load %[[VAL_1]](%[[VAL_27]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array +! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_30:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_31:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_32:.*]] = arith.subi %[[VAL_23]], %[[VAL_30]] : index +! CHECK: %[[VAL_33:.*]] = fir.do_loop %[[VAL_34:.*]] = %[[VAL_31]] to %[[VAL_32]] step %[[VAL_30]] unordered iter_args(%[[VAL_35:.*]] = %[[VAL_26]]) -> (!fir.array) { +! CHECK: %[[VAL_36:.*]] = fir.array_fetch %[[VAL_28]], %[[VAL_34]] : (!fir.array, index) -> f32 +! CHECK: %[[VAL_37:.*]] = arith.addf %[[VAL_36]], %[[VAL_29]] : f32 +! CHECK: %[[VAL_38:.*]] = fir.array_update %[[VAL_35]], %[[VAL_37]], %[[VAL_34]] : (!fir.array, f32, index) -> !fir.array +! CHECK: fir.result %[[VAL_38]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_26]], %[[VAL_39:.*]] to %[[VAL_0]]{{\[}}%[[VAL_25]]] : !fir.array, !fir.array, !fir.ref>, !fir.slice<1> +! CHECK: return +! CHECK: } + +subroutine test6(a,b,c,n,m) + integer :: n, m + real, intent(out) :: a(n) + real, intent(in) :: b(m), c + a(3:n:4) = b + c +end subroutine test6 + +! CHECK-LABEL: func @_QPtest6a( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { +! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_3:.*]] = arith.constant 50 : index +! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_6:.*]] = fir.array_load %[[VAL_1]](%[[VAL_5]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<10xf32> +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_8:.*]] = arith.constant 4 : i64 +! CHECK: %[[VAL_9:.*]] = fir.undefined index +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (i64) -> index +! CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_10]], %[[VAL_7]] : index +! CHECK: %[[VAL_12:.*]] = arith.constant 41 : i64 +! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index +! CHECK: %[[VAL_14:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index +! CHECK: %[[VAL_16:.*]] = arith.constant 50 : i64 +! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index +! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_19:.*]] = fir.slice %[[VAL_8]], %[[VAL_9]], %[[VAL_9]], %[[VAL_13]], %[[VAL_17]], %[[VAL_15]] : (i64, index, index, index, index, index) -> !fir.slice<2> +! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_0]](%[[VAL_18]]) {{\[}}%[[VAL_19]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.array<10x50xf32> +! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_22:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_4]], %[[VAL_21]] : index +! CHECK: %[[VAL_24:.*]] = fir.do_loop %[[VAL_25:.*]] = %[[VAL_22]] to %[[VAL_23]] step %[[VAL_21]] unordered iter_args(%[[VAL_26:.*]] = %[[VAL_6]]) -> (!fir.array<10xf32>) { +! CHECK: %[[VAL_27:.*]] = fir.array_fetch %[[VAL_20]], %[[VAL_11]], %[[VAL_25]] : (!fir.array<10x50xf32>, index, index) -> f32 +! CHECK: %[[VAL_28:.*]] = fir.array_update %[[VAL_26]], %[[VAL_27]], %[[VAL_25]] : (!fir.array<10xf32>, f32, index) -> !fir.array<10xf32> +! CHECK: fir.result %[[VAL_28]] : !fir.array<10xf32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_6]], %[[VAL_29:.*]] to %[[VAL_1]] : !fir.array<10xf32>, !fir.array<10xf32>, !fir.ref> +! CHECK: return +! CHECK: } + +subroutine test6a(a,b) + ! copy part of 1 row to b. a's projection has rank 1. + real :: a(10,50) + real :: b(10) + b = a(4,41:50) +end subroutine test6a + +! CHECK-LABEL: func @_QPtest6b( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { +! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_3:.*]] = arith.constant 50 : index +! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_6:.*]] = arith.constant 4 : i64 +! CHECK: %[[VAL_7:.*]] = fir.undefined index +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (i64) -> index +! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_5]] : index +! CHECK: %[[VAL_10:.*]] = arith.constant 41 : i64 +! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index +! CHECK: %[[VAL_14:.*]] = arith.constant 50 : i64 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index +! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]], %[[VAL_11]] : index +! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_17]], %[[VAL_13]] : index +! CHECK: %[[VAL_19:.*]] = arith.divsi %[[VAL_18]], %[[VAL_13]] : index +! CHECK: %[[VAL_20:.*]] = arith.cmpi sgt, %[[VAL_19]], %[[VAL_16]] : index +! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_20]], %[[VAL_19]], %[[VAL_16]] : index +! CHECK: %[[VAL_22:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_23:.*]] = fir.slice %[[VAL_6]], %[[VAL_7]], %[[VAL_7]], %[[VAL_11]], %[[VAL_15]], %[[VAL_13]] : (i64, index, index, index, index, index) -> !fir.slice<2> +! CHECK: %[[VAL_24:.*]] = fir.array_load %[[VAL_0]](%[[VAL_22]]) {{\[}}%[[VAL_23]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.array<10x50xf32> +! CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_26:.*]] = fir.array_load %[[VAL_1]](%[[VAL_25]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<10xf32> +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_21]], %[[VAL_27]] : index +! CHECK: %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_28]] to %[[VAL_29]] step %[[VAL_27]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_24]]) -> (!fir.array<10x50xf32>) { +! CHECK: %[[VAL_33:.*]] = fir.array_fetch %[[VAL_26]], %[[VAL_31]] : (!fir.array<10xf32>, index) -> f32 +! CHECK: %[[VAL_34:.*]] = fir.array_update %[[VAL_32]], %[[VAL_33]], %[[VAL_9]], %[[VAL_31]] : (!fir.array<10x50xf32>, f32, index, index) -> !fir.array<10x50xf32> +! CHECK: fir.result %[[VAL_34]] : !fir.array<10x50xf32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_24]], %[[VAL_35:.*]] to %[[VAL_0]]{{\[}}%[[VAL_23]]] : !fir.array<10x50xf32>, !fir.array<10x50xf32>, !fir.ref>, !fir.slice<2> +! CHECK: return +! CHECK: } + +subroutine test6b(a,b) + ! copy b to columns 41 to 50 of row 4 of a + real :: a(10,50) + real :: b(10) + a(4,41:50) = b +end subroutine test6b + +! CHECK-LABEL: func @_QPtest7( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> i64 +! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> index +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64 +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> index +! CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_10:.*]] = fir.array_load %[[VAL_0]](%[[VAL_9]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array +! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_12:.*]] = fir.array_load %[[VAL_0]](%[[VAL_11]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array +! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_14:.*]] = fir.array_load %[[VAL_1]](%[[VAL_13]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array +! CHECK: %[[VAL_15:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_5]], %[[VAL_15]] : index +! CHECK: %[[VAL_18:.*]] = fir.do_loop %[[VAL_19:.*]] = %[[VAL_16]] to %[[VAL_17]] step %[[VAL_15]] unordered iter_args(%[[VAL_20:.*]] = %[[VAL_10]]) -> (!fir.array) { +! CHECK: %[[VAL_21:.*]] = fir.array_fetch %[[VAL_12]], %[[VAL_19]] : (!fir.array, index) -> f32 +! CHECK: %[[VAL_22:.*]] = fir.array_fetch %[[VAL_14]], %[[VAL_19]] : (!fir.array, index) -> f32 +! CHECK: %[[VAL_23:.*]] = arith.addf %[[VAL_21]], %[[VAL_22]] : f32 +! CHECK: %[[VAL_24:.*]] = fir.array_update %[[VAL_20]], %[[VAL_23]], %[[VAL_19]] : (!fir.array, f32, index) -> !fir.array +! CHECK: fir.result %[[VAL_24]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_10]], %[[VAL_25:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.ref> +! CHECK: return +! CHECK: } + +! This is NOT a conflict. `a` appears on both the lhs and rhs here, but there +! are no loop-carried dependences and no copy is needed. +subroutine test7(a,b,n) + integer :: n + real, intent(inout) :: a(n) + real, intent(in) :: b(n) + a = a + b +end subroutine test7 + +! CHECK-LABEL: func @_QPtest8( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}) { +! CHECK: %[[VAL_2:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_4:.*]] = fir.array_load %[[VAL_0]](%[[VAL_3]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xi32> +! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_7:.*]] = arith.subi %[[VAL_5]], %[[VAL_6]] : i64 +! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_7]] : (!fir.ref>, i64) -> !fir.ref +! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref +! CHECK: %[[VAL_10:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_11:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_2]], %[[VAL_10]] : index +! CHECK: %[[VAL_13:.*]] = fir.do_loop %[[VAL_14:.*]] = %[[VAL_11]] to %[[VAL_12]] step %[[VAL_10]] unordered iter_args(%[[VAL_15:.*]] = %[[VAL_4]]) -> (!fir.array<100xi32>) { +! CHECK: %[[VAL_16:.*]] = fir.array_update %[[VAL_15]], %[[VAL_9]], %[[VAL_14]] : (!fir.array<100xi32>, i32, index) -> !fir.array<100xi32> +! CHECK: fir.result %[[VAL_16]] : !fir.array<100xi32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_4]], %[[VAL_17:.*]] to %[[VAL_0]] : !fir.array<100xi32>, !fir.array<100xi32>, !fir.ref> +! CHECK: return +! CHECK: } + +subroutine test8(a,b) + integer :: a(100), b(100) + a = b(1) +end subroutine test8 + +subroutine test10(a,b,c,d) + interface + ! Function takea an array and yields an array + function foo(a) result(res) + real :: a(:) ! FIXME: must be before res or semantics fails + ! as `size(a,1)` fails to resolve to the argument + real, dimension(size(a,1)) :: res + end function foo + end interface + interface + ! Function takes an array and yields a scalar + real function bar(a) + real :: a(:) + end function bar + end interface + real :: a(:), b(:), c(:), d(:) +! a = b + foo(c + foo(d + bar(a))) +end subroutine test10 + +! CHECK-LABEL: func @_QPtest11( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref>{{.*}}, %[[VAL_2:.*]]: !fir.ref>{{.*}}, %[[VAL_3:.*]]: !fir.ref>{{.*}}) { +! CHECK: %[[VAL_4:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_5:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_6:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_7:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_0]](%[[VAL_8]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> +! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_1]](%[[VAL_10]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> +! CHECK: %[[VAL_12:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_2]](%[[VAL_14]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_3]](%[[VAL_16]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> +! CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<100xf32> +! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_18]](%[[VAL_19]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array<100xf32> +! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_22:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_12]], %[[VAL_21]] : index +! CHECK: %[[VAL_24:.*]] = fir.do_loop %[[VAL_25:.*]] = %[[VAL_22]] to %[[VAL_23]] step %[[VAL_21]] unordered iter_args(%[[VAL_26:.*]] = %[[VAL_20]]) -> (!fir.array<100xf32>) { +! CHECK: %[[VAL_27:.*]] = fir.array_fetch %[[VAL_15]], %[[VAL_25]] : (!fir.array<100xf32>, index) -> f32 +! CHECK: %[[VAL_28:.*]] = fir.array_fetch %[[VAL_17]], %[[VAL_25]] : (!fir.array<100xf32>, index) -> f32 +! CHECK: %[[VAL_29:.*]] = arith.addf %[[VAL_27]], %[[VAL_28]] : f32 +! CHECK: %[[VAL_30:.*]] = fir.array_update %[[VAL_26]], %[[VAL_29]], %[[VAL_25]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> +! CHECK: fir.result %[[VAL_30]] : !fir.array<100xf32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_20]], %[[VAL_31:.*]] to %[[VAL_18]] : !fir.array<100xf32>, !fir.array<100xf32>, !fir.heap> +! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_18]] : (!fir.heap>) -> !fir.ref> +! CHECK: %[[VAL_33:.*]] = fir.call @_QPbar(%[[VAL_32]]) : (!fir.ref>) -> f32 +! CHECK: %[[VAL_34:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_35:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_4]], %[[VAL_34]] : index +! CHECK: %[[VAL_37:.*]] = fir.do_loop %[[VAL_38:.*]] = %[[VAL_35]] to %[[VAL_36]] step %[[VAL_34]] unordered iter_args(%[[VAL_39:.*]] = %[[VAL_9]]) -> (!fir.array<100xf32>) { +! CHECK: %[[VAL_40:.*]] = fir.array_fetch %[[VAL_11]], %[[VAL_38]] : (!fir.array<100xf32>, index) -> f32 +! CHECK: %[[VAL_41:.*]] = arith.addf %[[VAL_40]], %[[VAL_33]] : f32 +! CHECK: %[[VAL_42:.*]] = fir.array_update %[[VAL_39]], %[[VAL_41]], %[[VAL_38]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> +! CHECK: fir.result %[[VAL_42]] : !fir.array<100xf32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_43:.*]] to %[[VAL_0]] : !fir.array<100xf32>, !fir.array<100xf32>, !fir.ref> +! CHECK: fir.freemem %[[VAL_18]] +! CHECK: return +! CHECK: } + +subroutine test11(a,b,c,d) + real, external :: bar + real :: a(100), b(100), c(100), d(100) + a = b + bar(c + d) +end subroutine test11 + +! CHECK-LABEL: func @_QPtest12 +subroutine test12(a,b,c,d,n,m) + integer :: n, m + ! CHECK: %[[n:.*]] = fir.load %arg4 + ! CHECK: %[[m:.*]] = fir.load %arg5 + ! CHECK: %[[sha:.*]] = fir.shape % + ! CHECK: %[[A:.*]] = fir.array_load %arg0(%[[sha]]) + ! CHECK: %[[shb:.*]] = fir.shape % + ! CHECK: %[[B:.*]] = fir.array_load %arg1(%[[shb]]) + ! CHECK: %[[C:.*]] = fir.array_load %arg2(% + ! CHECK: %[[D:.*]] = fir.array_load %arg3(% + ! CHECK: %[[tmp:.*]] = fir.allocmem !fir.array, %{{.*}} {{{.*}}uniq_name = ".array.expr"} + ! CHECK: %[[T:.*]] = fir.array_load %[[tmp]](% + real, external :: bar + real :: a(n), b(n), c(m), d(m) + ! CHECK: %[[LOOP:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %[[T]]) + ! CHECK-DAG: fir.array_fetch %[[C]] + ! CHECK-DAG: fir.array_fetch %[[D]] + ! CHECK: fir.array_merge_store %[[T]], %[[LOOP]] + ! CHECK: %[[CALL:.*]] = fir.call @_QPbar + ! CHECK: %[[LOOP2:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %[[A]]) + ! CHECK: fir.array_fetch %[[B]] + ! CHECK: fir.array_merge_store %[[A]], %[[LOOP2]] to %arg0 + a = b + bar(c + d) + ! CHECK: fir.freemem %[[tmp]] +end subroutine test12 + +! CHECK-LABEL: func @_QPtest13 +subroutine test13(a,b,c,d,n,m,i) + real :: a(n), b(m) + complex :: c(n), d(m) + ! CHECK: %[[A_shape:.*]] = fir.shape % + ! CHECK: %[[A:.*]] = fir.array_load %arg0(%[[A_shape]]) + ! CHECK: %[[B_shape:.*]] = fir.shape % + ! CHECK: %[[B_slice:.*]] = fir.slice % + ! CHECK: %[[B:.*]] = fir.array_load %arg1(%[[B_shape]]) [%[[B_slice]]] + ! CHECK: %[[C_shape:.*]] = fir.shape % + ! CHECK: %[[C_slice:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} path % + ! CHECK: %[[C:.*]] = fir.array_load %arg2(%[[C_shape]]) [%[[C_slice]]] + ! CHECK: %[[D_shape:.*]] = fir.shape % + ! CHECK: %[[D_slice:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} path % + ! CHECK: %[[D:.*]] = fir.array_load %arg3(%[[D_shape]]) [%[[D_slice]]] + ! CHECK: = arith.constant -6.2598534E+18 : f32 + ! CHECK: %[[A_result:.*]] = fir.do_loop %{{.*}} = %{{.*}} iter_args(%[[A_in:.*]] = %[[A]]) -> + ! CHECK: fir.array_fetch %[[B]], + ! CHECK: fir.array_fetch %[[C]], + ! CHECK: fir.array_fetch %[[D]], + ! CHECK: fir.array_update %[[A_in]], + a = b(i:i+2*n-2:2) + c%im - d(i:i+2*n-2:2)%re + x'deadbeef' + ! CHECK: fir.array_merge_store %[[A]], %[[A_result]] to %arg0 +end subroutine test13 + +! Test elemental call to function f +! CHECK-LABEL: func @_QPtest14( +! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) +subroutine test14(a,b) + ! CHECK: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> + interface + real elemental function f1(i) + real, intent(in) :: i + end function f1 + end interface + real :: a(100), b(100) + ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { + ! CHECK: %[[ishift:.*]] = arith.addi %[[i]], %c1{{.*}} : index + ! CHECK: %[[tmp:.*]] = fir.array_coor %[[a]](%{{.*}}) %[[ishift]] : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + ! CHECK: %[[fres:.*]] = fir.call @_QPf1(%[[tmp]]) : (!fir.ref) -> f32 + ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> + ! CHECK: fir.result %[[res]] : !fir.array<100xf32> + ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] + b = f1(a) +end subroutine test14 + +! Test elemental intrinsic function (abs) +! CHECK-LABEL: func @_QPtest15( +! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) +subroutine test15(a,b) + ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> + ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> + real :: a(100), b(100) + ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { + ! CHECK: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 + ! CHECK: %[[fres:.*]] = fir.call @llvm.fabs.f32(%[[val]]) : (f32) -> f32 + ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> + ! CHECK: fir.result %[[res]] : !fir.array<100xf32> + ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] + b = abs(a) +end subroutine test15 + +! Test elemental call to function f2 with VALUE attribute +! CHECK-LABEL: func @_QPtest16( +! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) +subroutine test16(a,b) + ! CHECK: %[[tmp:.*]] = fir.alloca f32 {adapt.valuebyref + ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> + ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> + interface + real elemental function f2(i) + real, VALUE :: i + end function f2 + end interface + real :: a(100), b(100) + ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { + ! CHECK: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 + ! CHECK: fir.store %[[val]] to %[[tmp]] + ! CHECK: %[[fres:.*]] = fir.call @_QPf2(%[[tmp]]) : (!fir.ref) -> f32 + ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> + ! CHECK: fir.result %[[res]] : !fir.array<100xf32> + ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] + b = f2(a) +end subroutine test16 + +! Test elemental impure call to function f3. +! +! CHECK-LABEL: func @_QPtest17( +! CHECK-SAME: %[[a:[^:]+]]: !fir.ref>{{.*}}, %[[b:[^:]+]]: !fir.ref>{{.*}}, %[[c:.*]]: !fir.ref>{{.*}}) +subroutine test17(a,b,c) + ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> + ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shapeshift<1>) -> !fir.array<100xf32> + interface + real elemental impure function f3(i,j,k) + real, intent(inout) :: i, j, k + end function f3 + end interface + real :: a(100), b(2:101), c(3:102) + ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { + ! CHECK-DAG: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 + ! CHECK-DAG: %[[ic:.*]] = arith.addi %[[i]], %c3{{.*}} : index + ! CHECK-DAG: %[[ccoor:.*]] = fir.array_coor %[[c]](%{{.*}}) %[[ic]] : (!fir.ref>, !fir.shapeshift<1>, index) -> !fir.ref + ! CHECK-DAG: %[[ib:.*]] = arith.addi %[[i]], %c2{{.*}} : index + ! CHECK-DAG: %[[bcoor:.*]] = fir.array_coor %[[b]](%{{.*}}) %[[ib]] : (!fir.ref>, !fir.shapeshift<1>, index) -> !fir.ref + ! CHECK-DAG: %[[ia:.*]] = arith.addi %[[i]], %c1{{.*}} : index + ! CHECK-DAG: %[[acoor:.*]] = fir.array_coor %[[a]](%{{.*}}) %[[ia]] : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + ! CHECK: %[[fres:.*]] = fir.call @_QPf3(%[[ccoor]], %[[bcoor]], %[[acoor]]) : (!fir.ref, !fir.ref, !fir.ref) -> f32 + ! CHECK: %[[fadd:.*]] = arith.addf %[[val]], %[[fres]] : f32 + ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fadd]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> + + ! See 10.1.4.p2 note 1. The expression below is illegal if `f3` defines the + ! argument `a` for this statement. Since, this cannot be proven statically by + ! the compiler, the constraint is left to the user. The compiler may give a + ! warning that `k` is neither VALUE nor INTENT(IN) and the actual argument, + ! `a`, appears elsewhere in the same statement. + b = a + f3(c, b, a) + + ! CHECK: fir.result %[[res]] : !fir.array<100xf32> + ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] +end subroutine test17 + +! CHECK-LABEL: func @_QPtest18() { +! CHECK: %[[VAL_0:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_1:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.array<10x10xi32> {bindc_name = "array", fir.target, uniq_name = "_QFtest18Earray"} +! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest18Ei"} +! CHECK: %[[VAL_4:.*]] = fir.alloca !fir.box>> {bindc_name = "row_i", uniq_name = "_QFtest18Erow_i"} +! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.ptr> +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> +! CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref>>> +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> i64 +! CHECK: %[[VAL_12:.*]] = fir.undefined index +! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> index +! CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_9]], %[[VAL_1]] : index +! CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_15]], %[[VAL_9]] : index +! CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_0]], %[[VAL_1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_18:.*]] = fir.slice %[[VAL_11]], %[[VAL_12]], %[[VAL_12]], %[[VAL_9]], %[[VAL_16]], %[[VAL_14]] : (i64, index, index, index, index, index) -> !fir.slice<2> +! CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_2]](%[[VAL_17]]) {{\[}}%[[VAL_18]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.box> +! CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>) -> !fir.box>> +! CHECK: fir.store %[[VAL_20]] to %[[VAL_4]] : !fir.ref>>> +! CHECK: return +! CHECK: } + +subroutine test18 + integer, target :: array(10,10) + integer, pointer :: row_i(:) + row_i => array(i, :) +end subroutine test18 + +! CHECK-LABEL: func @_QPtest_column_and_row_order( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}) { +! CHECK: %[[VAL_1:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_2:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_4:.*]] = fir.array_load %[[VAL_0]](%[[VAL_3]]) : (!fir.ref>, !fir.shape<2>) -> !fir.array<2x3xf32> +! CHECK: %[[VAL_5:.*]] = arith.constant 42 : i32 +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> f32 +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_1]], %[[VAL_7]] : index +! CHECK: %[[VAL_10:.*]] = arith.subi %[[VAL_2]], %[[VAL_7]] : index +! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_8]] to %[[VAL_10]] step %[[VAL_7]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_4]]) -> (!fir.array<2x3xf32>) { +! CHECK: %[[VAL_14:.*]] = fir.do_loop %[[VAL_15:.*]] = %[[VAL_8]] to %[[VAL_9]] step %[[VAL_7]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_13]]) -> (!fir.array<2x3xf32>) { +! CHECK: %[[VAL_17:.*]] = fir.array_update %[[VAL_16]], %[[VAL_6]], %[[VAL_15]], %[[VAL_12]] : (!fir.array<2x3xf32>, f32, index, index) -> !fir.array<2x3xf32> +! CHECK: fir.result %[[VAL_17]] : !fir.array<2x3xf32> +! CHECK: } +! CHECK: fir.result %[[VAL_18:.*]] : !fir.array<2x3xf32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_4]], %[[VAL_19:.*]] to %[[VAL_0]] : !fir.array<2x3xf32>, !fir.array<2x3xf32>, !fir.ref> +! CHECK: return +! CHECK: } + +subroutine test_column_and_row_order(x) + real :: x(2,3) + x = 42 +end subroutine + +! CHECK-LABEL: func @_QPtest_assigning_to_assumed_shape_slices( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}) { +! CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_2:.*]] = arith.constant 2 : i64 +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i64) -> index +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_1]], %[[VAL_5]]#1 : index +! CHECK: %[[VAL_7:.*]] = arith.subi %[[VAL_6]], %[[VAL_1]] : index +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_1]] : index +! CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_9]], %[[VAL_3]] : index +! CHECK: %[[VAL_11:.*]] = arith.divsi %[[VAL_10]], %[[VAL_3]] : index +! CHECK: %[[VAL_12:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_8]] : index +! CHECK: %[[VAL_13:.*]] = arith.select %[[VAL_12]], %[[VAL_11]], %[[VAL_8]] : index +! CHECK: %[[VAL_14:.*]] = fir.slice %[[VAL_1]], %[[VAL_7]], %[[VAL_3]] : (index, index, index) -> !fir.slice<1> +! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_0]] {{\[}}%[[VAL_14]]] : (!fir.box>, !fir.slice<1>) -> !fir.array +! CHECK: %[[VAL_16:.*]] = arith.constant 42 : i32 +! CHECK: %[[VAL_17:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_18:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_13]], %[[VAL_17]] : index +! CHECK: %[[VAL_20:.*]] = fir.do_loop %[[VAL_21:.*]] = %[[VAL_18]] to %[[VAL_19]] step %[[VAL_17]] unordered iter_args(%[[VAL_22:.*]] = %[[VAL_15]]) -> (!fir.array) { +! CHECK: %[[VAL_23:.*]] = fir.array_update %[[VAL_22]], %[[VAL_16]], %[[VAL_21]] : (!fir.array, i32, index) -> !fir.array +! CHECK: fir.result %[[VAL_23]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_24:.*]] to %[[VAL_0]]{{\[}}%[[VAL_14]]] : !fir.array, !fir.array, !fir.box>, !fir.slice<1> +! CHECK: return +! CHECK: } + +subroutine test_assigning_to_assumed_shape_slices(x) + integer :: x(:) + x(::2) = 42 +end subroutine + +! CHECK-LABEL: func @_QPtest19a( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { +! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_7:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_3]](%[[VAL_8]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<10x!fir.char<1,10>> +! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_6]](%[[VAL_10]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<10x!fir.char<1,10>> +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_4]], %[[VAL_12]] : index +! CHECK: %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_13]] to %[[VAL_14]] step %[[VAL_12]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_9]]) -> (!fir.array<10x!fir.char<1,10>>) { +! CHECK: %[[VAL_18:.*]] = fir.array_access %[[VAL_11]], %[[VAL_16]] : (!fir.array<10x!fir.char<1,10>>, index) -> !fir.ref> +! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_17]], %[[VAL_16]] : (!fir.array<10x!fir.char<1,10>>, index) -> !fir.ref> +! CHECK: %[[VAL_20:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_21:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (index) -> i64 +! CHECK: %[[VAL_23:.*]] = arith.muli %[[VAL_21]], %[[VAL_22]] : i64 +! CHECK: %[[VAL_24:.*]] = arith.constant false +! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_25]], %[[VAL_26]], %[[VAL_23]], %[[VAL_24]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_27:.*]] = fir.array_amend %[[VAL_17]], %[[VAL_19]] : (!fir.array<10x!fir.char<1,10>>, !fir.ref>) -> !fir.array<10x!fir.char<1,10>> +! CHECK: fir.result %[[VAL_27]] : !fir.array<10x!fir.char<1,10>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_28:.*]] to %[[VAL_3]] : !fir.array<10x!fir.char<1,10>>, !fir.array<10x!fir.char<1,10>>, !fir.ref>> +! CHECK: return +! CHECK: } + +subroutine test19a(a,b) + character(LEN=10) a(10) + character(LEN=10) b(10) + a = b +end subroutine test19a + +! CHECK-LABEL: func @_QPtest19b( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<2>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<2>{{.*}}) { +! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<2>) -> (!fir.ref>, index) +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_4:.*]] = arith.constant 20 : index +! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<2>) -> (!fir.ref>, index) +! CHECK: %[[VAL_6:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_8:.*]] = arith.constant 20 : index +! CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_10:.*]] = fir.array_load %[[VAL_3]](%[[VAL_9]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<20x!fir.char<2,8>> +! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_12:.*]] = fir.array_load %[[VAL_7]](%[[VAL_11]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<20x!fir.char<2,10>> +! CHECK: %[[VAL_13:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_14:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_4]], %[[VAL_13]] : index +! CHECK: %[[VAL_16:.*]] = fir.do_loop %[[VAL_17:.*]] = %[[VAL_14]] to %[[VAL_15]] step %[[VAL_13]] unordered iter_args(%[[VAL_18:.*]] = %[[VAL_10]]) -> (!fir.array<20x!fir.char<2,8>>) { +! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_12]], %[[VAL_17]] : (!fir.array<20x!fir.char<2,10>>, index) -> !fir.ref> +! CHECK: %[[VAL_20:.*]] = fir.array_access %[[VAL_18]], %[[VAL_17]] : (!fir.array<20x!fir.char<2,8>>, index) -> !fir.ref> +! CHECK: %[[VAL_21:.*]] = arith.constant 8 : index +! CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_21]], %[[VAL_6]] : index +! CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_21]], %[[VAL_6]] : index +! CHECK: %[[VAL_24:.*]] = arith.constant 2 : i64 +! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_23]] : (index) -> i64 +! CHECK: %[[VAL_26:.*]] = arith.muli %[[VAL_24]], %[[VAL_25]] : i64 +! CHECK: %[[VAL_27:.*]] = arith.constant false +! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_28]], %[[VAL_29]], %[[VAL_26]], %[[VAL_27]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_30:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_31:.*]] = arith.subi %[[VAL_21]], %[[VAL_30]] : index +! CHECK: %[[VAL_32:.*]] = arith.constant 32 : i16 +! CHECK: %[[VAL_33:.*]] = fir.undefined !fir.char<2> +! CHECK: %[[VAL_34:.*]] = fir.insert_value %[[VAL_33]], %[[VAL_32]], [0 : index] : (!fir.char<2>, i16) -> !fir.char<2> +! CHECK: %[[VAL_35:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_36:.*]] = %[[VAL_23]] to %[[VAL_31]] step %[[VAL_35]] { +! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_38:.*]] = fir.coordinate_of %[[VAL_37]], %[[VAL_36]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_34]] to %[[VAL_38]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_39:.*]] = fir.array_amend %[[VAL_18]], %[[VAL_20]] : (!fir.array<20x!fir.char<2,8>>, !fir.ref>) -> !fir.array<20x!fir.char<2,8>> +! CHECK: fir.result %[[VAL_39]] : !fir.array<20x!fir.char<2,8>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_10]], %[[VAL_40:.*]] to %[[VAL_3]] : !fir.array<20x!fir.char<2,8>>, !fir.array<20x!fir.char<2,8>>, !fir.ref>> +! CHECK: return +! CHECK: } + +subroutine test19b(a,b) + character(KIND=2, LEN=8) a(20) + character(KIND=2, LEN=10) b(20) + a = b +end subroutine test19b + +! CHECK-LABEL: func @_QPtest19c( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<4>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<4>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<4>) -> (!fir.ref>, index) +! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_6:.*]] = arith.constant 30 : index +! CHECK: %[[VAL_7:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<4>) -> (!fir.ref>, index) +! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_9:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : i32 +! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : i32 +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_13:.*]] = arith.constant 30 : index +! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_12]](%[[VAL_14]]) typeparams %[[VAL_11]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<30x!fir.char<4,?>> +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_5]](%[[VAL_16]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.array<30x!fir.char<4,10>> +! CHECK: %[[VAL_18:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_19:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_13]], %[[VAL_18]] : index +! CHECK: %[[VAL_21:.*]] = fir.do_loop %[[VAL_22:.*]] = %[[VAL_19]] to %[[VAL_20]] step %[[VAL_18]] unordered iter_args(%[[VAL_23:.*]] = %[[VAL_15]]) -> (!fir.array<30x!fir.char<4,?>>) { +! CHECK: %[[VAL_24:.*]] = fir.array_access %[[VAL_17]], %[[VAL_22]] : (!fir.array<30x!fir.char<4,10>>, index) -> !fir.ref> +! CHECK: %[[VAL_25:.*]] = fir.array_access %[[VAL_23]], %[[VAL_22]] typeparams %[[VAL_11]] : (!fir.array<30x!fir.char<4,?>>, index, i32) -> !fir.ref> +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_11]] : (i32) -> index +! CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_26]], %[[VAL_4]] : index +! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_26]], %[[VAL_4]] : index +! CHECK: %[[VAL_29:.*]] = arith.constant 4 : i64 +! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (index) -> i64 +! CHECK: %[[VAL_31:.*]] = arith.muli %[[VAL_29]], %[[VAL_30]] : i64 +! CHECK: %[[VAL_32:.*]] = arith.constant false +! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_25]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_24]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_33]], %[[VAL_34]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_35:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_11]], %[[VAL_35]] : i32 +! CHECK: %[[VAL_37:.*]] = arith.constant 32 : i32 +! CHECK: %[[VAL_38:.*]] = fir.undefined !fir.char<4> +! CHECK: %[[VAL_39:.*]] = fir.insert_value %[[VAL_38]], %[[VAL_37]], [0 : index] : (!fir.char<4>, i32) -> !fir.char<4> +! CHECK: %[[VAL_40:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_36]] : (i32) -> index +! CHECK: fir.do_loop %[[VAL_42:.*]] = %[[VAL_28]] to %[[VAL_41]] step %[[VAL_40]] { +! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_25]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_44:.*]] = fir.coordinate_of %[[VAL_43]], %[[VAL_42]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_39]] to %[[VAL_44]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_45:.*]] = fir.array_amend %[[VAL_23]], %[[VAL_25]] : (!fir.array<30x!fir.char<4,?>>, !fir.ref>) -> !fir.array<30x!fir.char<4,?>> +! CHECK: fir.result %[[VAL_45]] : !fir.array<30x!fir.char<4,?>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_46:.*]] to %[[VAL_12]] typeparams %[[VAL_11]] : !fir.array<30x!fir.char<4,?>>, !fir.array<30x!fir.char<4,?>>, !fir.ref>>, i32 +! CHECK: return +! CHECK: } + +subroutine test19c(a,b,i) + character(KIND=4, LEN=i) a(30) + character(KIND=4, LEN=10) b(30) + a = b +end subroutine test19c + +! CHECK-LABEL: func @_QPtest19d( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : i32 +! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : i32 +! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_10:.*]] = arith.constant 40 : index +! CHECK: %[[VAL_11:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_13:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_12]], %[[VAL_13]] : i32 +! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_14]], %[[VAL_12]], %[[VAL_13]] : i32 +! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_11]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_17:.*]] = arith.constant 40 : index +! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_19:.*]] = fir.array_load %[[VAL_9]](%[[VAL_18]]) typeparams %[[VAL_8]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<40x!fir.char<1,?>> +! CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_17]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_21:.*]] = fir.array_load %[[VAL_16]](%[[VAL_20]]) typeparams %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<40x!fir.char<1,?>> +! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_23:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_10]], %[[VAL_22]] : index +! CHECK: %[[VAL_25:.*]] = fir.do_loop %[[VAL_26:.*]] = %[[VAL_23]] to %[[VAL_24]] step %[[VAL_22]] unordered iter_args(%[[VAL_27:.*]] = %[[VAL_19]]) -> (!fir.array<40x!fir.char<1,?>>) { +! CHECK: %[[VAL_28:.*]] = fir.array_access %[[VAL_21]], %[[VAL_26]] typeparams %[[VAL_15]] : (!fir.array<40x!fir.char<1,?>>, index, i32) -> !fir.ref> +! CHECK: %[[VAL_29:.*]] = fir.array_access %[[VAL_27]], %[[VAL_26]] typeparams %[[VAL_8]] : (!fir.array<40x!fir.char<1,?>>, index, i32) -> !fir.ref> +! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_8]] : (i32) -> index +! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_15]] : (i32) -> index +! CHECK: %[[VAL_32:.*]] = arith.cmpi slt, %[[VAL_30]], %[[VAL_31]] : index +! CHECK: %[[VAL_33:.*]] = arith.select %[[VAL_32]], %[[VAL_30]], %[[VAL_31]] : index +! CHECK: %[[VAL_34:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_33]] : (index) -> i64 +! CHECK: %[[VAL_36:.*]] = arith.muli %[[VAL_34]], %[[VAL_35]] : i64 +! CHECK: %[[VAL_37:.*]] = arith.constant false +! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_28]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_38]], %[[VAL_39]], %[[VAL_36]], %[[VAL_37]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_40:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_41:.*]] = arith.subi %[[VAL_8]], %[[VAL_40]] : i32 +! CHECK: %[[VAL_42:.*]] = arith.constant 32 : i8 +! CHECK: %[[VAL_43:.*]] = fir.undefined !fir.char<1> +! CHECK: %[[VAL_44:.*]] = fir.insert_value %[[VAL_43]], %[[VAL_42]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> +! CHECK: %[[VAL_45:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_41]] : (i32) -> index +! CHECK: fir.do_loop %[[VAL_47:.*]] = %[[VAL_33]] to %[[VAL_46]] step %[[VAL_45]] { +! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_49:.*]] = fir.coordinate_of %[[VAL_48]], %[[VAL_47]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_44]] to %[[VAL_49]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_50:.*]] = fir.array_amend %[[VAL_27]], %[[VAL_29]] : (!fir.array<40x!fir.char<1,?>>, !fir.ref>) -> !fir.array<40x!fir.char<1,?>> +! CHECK: fir.result %[[VAL_50]] : !fir.array<40x!fir.char<1,?>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_19]], %[[VAL_51:.*]] to %[[VAL_9]] typeparams %[[VAL_8]] : !fir.array<40x!fir.char<1,?>>, !fir.array<40x!fir.char<1,?>>, !fir.ref>>, i32 +! CHECK: return +! CHECK: } + +subroutine test19d(a,b,i,j) + character(i) a(40) + character(j) b(40) + a = b +end subroutine test19d + +! CHECK-LABEL: func @_QPtest19e( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { +! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_4:.*]] = arith.constant 50 : index +! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_7:.*]] = arith.constant 50 : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_3]](%[[VAL_8]]) typeparams %[[VAL_2]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<50x!fir.char<1,?>> +! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_6]](%[[VAL_10]]) typeparams %[[VAL_5]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<50x!fir.char<1,?>> +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_4]], %[[VAL_12]] : index +! CHECK: %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_13]] to %[[VAL_14]] step %[[VAL_12]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_9]]) -> (!fir.array<50x!fir.char<1,?>>) { +! CHECK: %[[VAL_18:.*]] = fir.array_access %[[VAL_11]], %[[VAL_16]] typeparams %[[VAL_5]]#1 : (!fir.array<50x!fir.char<1,?>>, index, index) -> !fir.ref> +! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_17]], %[[VAL_16]] typeparams %[[VAL_2]]#1 : (!fir.array<50x!fir.char<1,?>>, index, index) -> !fir.ref> +! CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_2]]#1, %[[VAL_5]]#1 : index +! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_20]], %[[VAL_2]]#1, %[[VAL_5]]#1 : index +! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (index) -> i64 +! CHECK: %[[VAL_24:.*]] = arith.muli %[[VAL_22]], %[[VAL_23]] : i64 +! CHECK: %[[VAL_25:.*]] = arith.constant false +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_26]], %[[VAL_27]], %[[VAL_24]], %[[VAL_25]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_28:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_2]]#1, %[[VAL_28]] : index +! CHECK: %[[VAL_30:.*]] = arith.constant 32 : i8 +! CHECK: %[[VAL_31:.*]] = fir.undefined !fir.char<1> +! CHECK: %[[VAL_32:.*]] = fir.insert_value %[[VAL_31]], %[[VAL_30]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> +! CHECK: %[[VAL_33:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_34:.*]] = %[[VAL_21]] to %[[VAL_29]] step %[[VAL_33]] { +! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_36:.*]] = fir.coordinate_of %[[VAL_35]], %[[VAL_34]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_32]] to %[[VAL_36]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_37:.*]] = fir.array_amend %[[VAL_17]], %[[VAL_19]] : (!fir.array<50x!fir.char<1,?>>, !fir.ref>) -> !fir.array<50x!fir.char<1,?>> +! CHECK: fir.result %[[VAL_37]] : !fir.array<50x!fir.char<1,?>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_38:.*]] to %[[VAL_3]] typeparams %[[VAL_2]]#1 : !fir.array<50x!fir.char<1,?>>, !fir.array<50x!fir.char<1,?>>, !fir.ref>>, index +! CHECK: return +! CHECK: } + +subroutine test19e(a,b) + character(*) a(50) + character(*) b(50) + a = b +end subroutine test19e + +! CHECK-LABEL: func @_QPtest19f( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { +! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_4:.*]] = arith.constant 60 : index +! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_7:.*]] = arith.constant 60 : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_3]](%[[VAL_8]]) typeparams %[[VAL_2]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<60x!fir.char<1,?>> +! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QQcl.70726566697820) : !fir.ref> +! CHECK: %[[VAL_11:.*]] = arith.constant 7 : index +! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_13:.*]] = fir.array_load %[[VAL_6]](%[[VAL_12]]) typeparams %[[VAL_5]]#1 : (!fir.ref>>, !fir.shape<1>, index) -> !fir.array<60x!fir.char<1,?>> +! CHECK: %[[VAL_14:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_4]], %[[VAL_14]] : index +! CHECK: %[[VAL_17:.*]] = fir.do_loop %[[VAL_18:.*]] = %[[VAL_15]] to %[[VAL_16]] step %[[VAL_14]] unordered iter_args(%[[VAL_19:.*]] = %[[VAL_9]]) -> (!fir.array<60x!fir.char<1,?>>) { +! CHECK: %[[VAL_20:.*]] = fir.array_access %[[VAL_13]], %[[VAL_18]] typeparams %[[VAL_5]]#1 : (!fir.array<60x!fir.char<1,?>>, index, index) -> !fir.ref> +! CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_11]], %[[VAL_5]]#1 : index +! CHECK: %[[VAL_22:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_21]] : index) {bindc_name = ".chrtmp"} +! CHECK: %[[VAL_23:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_11]] : (index) -> i64 +! CHECK: %[[VAL_25:.*]] = arith.muli %[[VAL_23]], %[[VAL_24]] : i64 +! CHECK: %[[VAL_26:.*]] = arith.constant false +! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_27]], %[[VAL_28]], %[[VAL_25]], %[[VAL_26]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_21]], %[[VAL_29]] : index +! CHECK: fir.do_loop %[[VAL_31:.*]] = %[[VAL_11]] to %[[VAL_30]] step %[[VAL_29]] { +! CHECK: %[[VAL_32:.*]] = arith.subi %[[VAL_31]], %[[VAL_11]] : index +! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_34:.*]] = fir.coordinate_of %[[VAL_33]], %[[VAL_32]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: %[[VAL_35:.*]] = fir.load %[[VAL_34]] : !fir.ref> +! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_37:.*]] = fir.coordinate_of %[[VAL_36]], %[[VAL_31]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_35]] to %[[VAL_37]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_38:.*]] = fir.array_access %[[VAL_19]], %[[VAL_18]] typeparams %[[VAL_2]]#1 : (!fir.array<60x!fir.char<1,?>>, index, index) -> !fir.ref> +! CHECK: %[[VAL_39:.*]] = arith.cmpi slt, %[[VAL_2]]#1, %[[VAL_21]] : index +! CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_39]], %[[VAL_2]]#1, %[[VAL_21]] : index +! CHECK: %[[VAL_41:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_40]] : (index) -> i64 +! CHECK: %[[VAL_43:.*]] = arith.muli %[[VAL_41]], %[[VAL_42]] : i64 +! CHECK: %[[VAL_44:.*]] = arith.constant false +! CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_38]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_45]], %[[VAL_46]], %[[VAL_43]], %[[VAL_44]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_47:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_48:.*]] = arith.subi %[[VAL_2]]#1, %[[VAL_47]] : index +! CHECK: %[[VAL_49:.*]] = arith.constant 32 : i8 +! CHECK: %[[VAL_50:.*]] = fir.undefined !fir.char<1> +! CHECK: %[[VAL_51:.*]] = fir.insert_value %[[VAL_50]], %[[VAL_49]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> +! CHECK: %[[VAL_52:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_53:.*]] = %[[VAL_40]] to %[[VAL_48]] step %[[VAL_52]] { +! CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_38]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_55:.*]] = fir.coordinate_of %[[VAL_54]], %[[VAL_53]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_51]] to %[[VAL_55]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_56:.*]] = fir.array_amend %[[VAL_19]], %[[VAL_38]] : (!fir.array<60x!fir.char<1,?>>, !fir.ref>) -> !fir.array<60x!fir.char<1,?>> +! CHECK: fir.result %[[VAL_56]] : !fir.array<60x!fir.char<1,?>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_57:.*]] to %[[VAL_3]] typeparams %[[VAL_2]]#1 : !fir.array<60x!fir.char<1,?>>, !fir.array<60x!fir.char<1,?>>, !fir.ref>>, index +! CHECK: return +! CHECK: } + +subroutine test19f(a,b) + character(*) a(60) + character(*) b(60) + a = "prefix " // b +end subroutine test19f + +! CHECK-LABEL: func @_QPtest19g( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<4>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<2>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<2>) -> (!fir.ref>, index) +! CHECK: %[[VAL_4:.*]] = arith.constant 13 : index +! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_6:.*]] = arith.constant 140 : index +! CHECK: %[[VAL_7:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<4>) -> (!fir.ref>, index) +! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_9:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : i32 +! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : i32 +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_13:.*]] = arith.constant 70 : index +! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_12]](%[[VAL_14]]) typeparams %[[VAL_11]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<70x!fir.char<4,?>> +! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index +! CHECK: %[[VAL_18:.*]] = arith.constant 2 : i64 +! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i64) -> index +! CHECK: %[[VAL_20:.*]] = arith.constant 140 : i64 +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index +! CHECK: %[[VAL_22:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_23:.*]] = fir.slice %[[VAL_17]], %[[VAL_21]], %[[VAL_19]] : (index, index, index) -> !fir.slice<1> +! CHECK: %[[VAL_24:.*]] = fir.array_load %[[VAL_5]](%[[VAL_22]]) {{\[}}%[[VAL_23]]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<140x!fir.char<2,13>> +! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> i64 +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_13]], %[[VAL_27]] : index +! CHECK: %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_28]] to %[[VAL_29]] step %[[VAL_27]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_15]]) -> (!fir.array<70x!fir.char<4,?>>) { +! CHECK: %[[VAL_33:.*]] = fir.array_access %[[VAL_24]], %[[VAL_31]] : (!fir.array<140x!fir.char<2,13>>, index) -> !fir.ref> +! CHECK: %[[VAL_34:.*]] = fir.alloca !fir.char<4,?>(%[[VAL_4]] : index) +! CHECK: %[[VAL_35:.*]] = arith.cmpi slt, %[[VAL_4]], %[[VAL_4]] : index +! CHECK: %[[VAL_36:.*]] = arith.select %[[VAL_35]], %[[VAL_4]], %[[VAL_4]] : index +! CHECK: fir.char_convert %[[VAL_33]] for %[[VAL_36]] to %[[VAL_34]] : !fir.ref>, index, !fir.ref> +! CHECK: %[[VAL_37:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_4]], %[[VAL_37]] : index +! CHECK: %[[VAL_39:.*]] = arith.constant 32 : i32 +! CHECK: %[[VAL_40:.*]] = fir.undefined !fir.char<4> +! CHECK: %[[VAL_41:.*]] = fir.insert_value %[[VAL_40]], %[[VAL_39]], [0 : index] : (!fir.char<4>, i32) -> !fir.char<4> +! CHECK: %[[VAL_42:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_43:.*]] = %[[VAL_36]] to %[[VAL_38]] step %[[VAL_42]] { +! CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_45:.*]] = fir.coordinate_of %[[VAL_44]], %[[VAL_43]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_41]] to %[[VAL_45]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_46:.*]] = fir.array_access %[[VAL_32]], %[[VAL_31]] typeparams %[[VAL_11]] : (!fir.array<70x!fir.char<4,?>>, index, i32) -> !fir.ref> +! CHECK: %[[VAL_47:.*]] = fir.convert %[[VAL_11]] : (i32) -> index +! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_26]] : (i64) -> index +! CHECK: %[[VAL_49:.*]] = arith.cmpi slt, %[[VAL_47]], %[[VAL_48]] : index +! CHECK: %[[VAL_50:.*]] = arith.select %[[VAL_49]], %[[VAL_47]], %[[VAL_48]] : index +! CHECK: %[[VAL_51:.*]] = arith.constant 4 : i64 +! CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_50]] : (index) -> i64 +! CHECK: %[[VAL_53:.*]] = arith.muli %[[VAL_51]], %[[VAL_52]] : i64 +! CHECK: %[[VAL_54:.*]] = arith.constant false +! CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_46]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_55]], %[[VAL_56]], %[[VAL_53]], %[[VAL_54]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_57:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_58:.*]] = arith.subi %[[VAL_11]], %[[VAL_57]] : i32 +! CHECK: %[[VAL_59:.*]] = arith.constant 32 : i32 +! CHECK: %[[VAL_60:.*]] = fir.undefined !fir.char<4> +! CHECK: %[[VAL_61:.*]] = fir.insert_value %[[VAL_60]], %[[VAL_59]], [0 : index] : (!fir.char<4>, i32) -> !fir.char<4> +! CHECK: %[[VAL_62:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_63:.*]] = fir.convert %[[VAL_58]] : (i32) -> index +! CHECK: fir.do_loop %[[VAL_64:.*]] = %[[VAL_50]] to %[[VAL_63]] step %[[VAL_62]] { +! CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_46]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_66:.*]] = fir.coordinate_of %[[VAL_65]], %[[VAL_64]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_61]] to %[[VAL_66]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_67:.*]] = fir.array_amend %[[VAL_32]], %[[VAL_46]] : (!fir.array<70x!fir.char<4,?>>, !fir.ref>) -> !fir.array<70x!fir.char<4,?>> +! CHECK: fir.result %[[VAL_67]] : !fir.array<70x!fir.char<4,?>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_68:.*]] to %[[VAL_12]] typeparams %[[VAL_11]] : !fir.array<70x!fir.char<4,?>>, !fir.array<70x!fir.char<4,?>>, !fir.ref>>, i32 +! CHECK: return +! CHECK: } + +subroutine test19g(a,b,i) + character(kind=4,len=i) a(70) + character(kind=2,len=13) b(140) + a = b(1:140:2) +end subroutine test19g + +! CHECK-LABEL: func @_QPtest19h( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref{{.*}}) { +! CHECK: %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : i32 +! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : i32 +! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_10:.*]] = arith.constant 70 : index +! CHECK: %[[VAL_11:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i32) -> i64 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_9]](%[[VAL_16]]) typeparams %[[VAL_8]] : (!fir.ref>>, !fir.shape<1>, i32) -> !fir.array<70x!fir.char<1,?>> +! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i64) -> index +! CHECK: %[[VAL_20:.*]] = arith.constant 2 : i64 +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index +! CHECK: %[[VAL_22:.*]] = arith.constant 140 : i64 +! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index +! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_25:.*]] = fir.slice %[[VAL_19]], %[[VAL_23]], %[[VAL_21]] : (index, index, index) -> !fir.slice<1> +! CHECK: %[[VAL_26:.*]] = fir.array_load %[[VAL_12]](%[[VAL_24]]) {{\[}}%[[VAL_25]]] typeparams %[[VAL_11]]#1 : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.array> +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_10]], %[[VAL_27]] : index +! CHECK: %[[VAL_30:.*]] = fir.do_loop %[[VAL_31:.*]] = %[[VAL_28]] to %[[VAL_29]] step %[[VAL_27]] unordered iter_args(%[[VAL_32:.*]] = %[[VAL_17]]) -> (!fir.array<70x!fir.char<1,?>>) { +! CHECK: %[[VAL_33:.*]] = fir.array_access %[[VAL_26]], %[[VAL_31]] typeparams %[[VAL_11]]#1 : (!fir.array>, index, index) -> !fir.ref> +! CHECK: %[[VAL_34:.*]] = fir.array_access %[[VAL_32]], %[[VAL_31]] typeparams %[[VAL_8]] : (!fir.array<70x!fir.char<1,?>>, index, i32) -> !fir.ref> +! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_8]] : (i32) -> index +! CHECK: %[[VAL_36:.*]] = arith.cmpi slt, %[[VAL_35]], %[[VAL_11]]#1 : index +! CHECK: %[[VAL_37:.*]] = arith.select %[[VAL_36]], %[[VAL_35]], %[[VAL_11]]#1 : index +! CHECK: %[[VAL_38:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (index) -> i64 +! CHECK: %[[VAL_40:.*]] = arith.muli %[[VAL_38]], %[[VAL_39]] : i64 +! CHECK: %[[VAL_41:.*]] = arith.constant false +! CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[VAL_42]], %[[VAL_43]], %[[VAL_40]], %[[VAL_41]]) : (!fir.ref, !fir.ref, i64, i1) -> () +! CHECK: %[[VAL_44:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_45:.*]] = arith.subi %[[VAL_8]], %[[VAL_44]] : i32 +! CHECK: %[[VAL_46:.*]] = arith.constant 32 : i8 +! CHECK: %[[VAL_47:.*]] = fir.undefined !fir.char<1> +! CHECK: %[[VAL_48:.*]] = fir.insert_value %[[VAL_47]], %[[VAL_46]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1> +! CHECK: %[[VAL_49:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_45]] : (i32) -> index +! CHECK: fir.do_loop %[[VAL_51:.*]] = %[[VAL_37]] to %[[VAL_50]] step %[[VAL_49]] { +! CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_53:.*]] = fir.coordinate_of %[[VAL_52]], %[[VAL_51]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: fir.store %[[VAL_48]] to %[[VAL_53]] : !fir.ref> +! CHECK: } +! CHECK: %[[VAL_54:.*]] = fir.array_amend %[[VAL_32]], %[[VAL_34]] : (!fir.array<70x!fir.char<1,?>>, !fir.ref>) -> !fir.array<70x!fir.char<1,?>> +! CHECK: fir.result %[[VAL_54]] : !fir.array<70x!fir.char<1,?>> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_17]], %[[VAL_55:.*]] to %[[VAL_9]] typeparams %[[VAL_8]] : !fir.array<70x!fir.char<1,?>>, !fir.array<70x!fir.char<1,?>>, !fir.ref>>, i32 +! CHECK: return +! CHECK: } + +subroutine test19h(a,b,i,j) + character(i) a(70) + character(*) b(j) + a = b(1:140:2) +end subroutine test19h + +! CHECK-LABEL: func @_QPtest_elemental_character_intrinsic( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { +! CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_7:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_8:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_9:.*]] = arith.constant -1 : i32 +! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>) -> !fir.ref +! CHECK: %[[VAL_12:.*]] = arith.constant {{.*}} : i32 +! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_9]], %[[VAL_11]], %[[VAL_12]]) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_15:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_17:.*]] = fir.shape_shift %[[VAL_7]], %[[VAL_8]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<10xi32> +! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_20:.*]] = fir.array_load %[[VAL_18]](%[[VAL_19]]) : (!fir.heap>, !fir.shape<1>) -> !fir.array<10xi32> +! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_22:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_15]], %[[VAL_21]] : index +! CHECK: %[[VAL_24:.*]] = fir.do_loop %[[VAL_25:.*]] = %[[VAL_22]] to %[[VAL_23]] step %[[VAL_21]] unordered iter_args(%[[VAL_26:.*]] = %[[VAL_20]]) -> (!fir.array<10xi32>) { +! CHECK: %[[VAL_27:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_25]], %[[VAL_27]] : index +! CHECK: %[[VAL_29:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_16]]) %[[VAL_28]] typeparams %[[VAL_2]]#1 : (!fir.ref>>, !fir.shape<1>, index, index) -> !fir.ref> +! CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_25]], %[[VAL_7]] : index +! CHECK: %[[VAL_31:.*]] = fir.array_coor %[[VAL_6]](%[[VAL_17]]) %[[VAL_30]] typeparams %[[VAL_5]]#1 : (!fir.ref>>, !fir.shapeshift<1>, index, index) -> !fir.ref> +! CHECK: %[[VAL_32:.*]] = arith.constant false +! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_2]]#1 : (index) -> i64 +! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_31]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_5]]#1 : (index) -> i64 +! CHECK: %[[VAL_37:.*]] = fir.call @_FortranAScan1(%[[VAL_33]], %[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_32]]) : (!fir.ref, i64, !fir.ref, i64, i1) -> i64 +! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (i64) -> i32 +! CHECK: %[[VAL_39:.*]] = fir.array_update %[[VAL_26]], %[[VAL_38]], %[[VAL_25]] : (!fir.array<10xi32>, i32, index) -> !fir.array<10xi32> +! CHECK: fir.result %[[VAL_39]] : !fir.array<10xi32> +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_20]], %[[VAL_40:.*]] to %[[VAL_18]] : !fir.array<10xi32>, !fir.array<10xi32>, !fir.heap> +! CHECK: %[[VAL_41:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_42:.*]] = fir.embox %[[VAL_18]](%[[VAL_41]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_42]] : (!fir.box>) -> !fir.box +! CHECK: %[[VAL_44:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_13]], %[[VAL_43]]) : (!fir.ref, !fir.box) -> i1 +! CHECK: fir.freemem %[[VAL_18]] +! CHECK: %[[VAL_45:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_13]]) : (!fir.ref) -> i32 +! CHECK: return +! CHECK: } + +subroutine test_elemental_character_intrinsic(c1, c2) + character(*) :: c1(10), c2(2:11) + print *, scan(c1, c2) +end subroutine + +! CHECK: func private @_QPbar( diff --git a/flang/test/Lower/associate-construct.f90 b/flang/test/Lower/associate-construct.f90 index 78f71efc09d30..def5373f5e248 100644 --- a/flang/test/Lower/associate-construct.f90 +++ b/flang/test/Lower/associate-construct.f90 @@ -2,92 +2,92 @@ ! CHECK-LABEL: func @_QQmain program p - ! CHECK-DAG: [[I:%[0-9]+]] = fir.alloca i32 {{{.*}}uniq_name = "_QFEi"} - ! CHECK-DAG: [[N:%[0-9]+]] = fir.alloca i32 {{{.*}}uniq_name = "_QFEn"} - ! CHECK: [[T:%[0-9]+]] = fir.address_of(@_QFEt) : !fir.ref> - integer :: n, foo, t(3) - ! CHECK: [[N]] - ! CHECK-COUNT-3: fir.coordinate_of [[T]] - n = 100; t(1) = 111; t(2) = 222; t(3) = 333 + ! CHECK-DAG: [[I:%[0-9]+]] = fir.alloca i32 {{{.*}}uniq_name = "_QFEi"} + ! CHECK-DAG: [[N:%[0-9]+]] = fir.alloca i32 {{{.*}}uniq_name = "_QFEn"} + ! CHECK: [[T:%[0-9]+]] = fir.address_of(@_QFEt) : !fir.ref> + integer :: n, foo, t(3) + ! CHECK: [[N]] + ! CHECK-COUNT-3: fir.coordinate_of [[T]] + n = 100; t(1) = 111; t(2) = 222; t(3) = 333 + ! CHECK: fir.load [[N]] + ! CHECK: addi {{.*}} %c5 + ! CHECK: fir.store %{{[0-9]*}} to [[B:%[0-9]+]] + ! CHECK: [[C:%[0-9]+]] = fir.coordinate_of [[T]] + ! CHECK: fir.call @_QPfoo + ! CHECK: fir.store %{{[0-9]*}} to [[D:%[0-9]+]] + associate (a => n, b => n+5, c => t(2), d => foo(7)) ! CHECK: fir.load [[N]] - ! CHECK: addi {{.*}} %c5 - ! CHECK: fir.store %{{[0-9]*}} to [[B:%[0-9]+]] - ! CHECK: [[C:%[0-9]+]] = fir.coordinate_of [[T]] - ! CHECK: fir.call @_QPfoo - ! CHECK: fir.store %{{[0-9]*}} to [[D:%[0-9]+]] - associate (a => n, b => n+5, c => t(2), d => foo(7)) - ! CHECK: fir.load [[N]] - ! CHECK: addi %{{[0-9]*}}, %c1 - ! CHECK: fir.store %{{[0-9]*}} to [[N]] - a = a + 1 - ! CHECK: fir.load [[C]] - ! CHECK: addi %{{[0-9]*}}, %c1 - ! CHECK: fir.store %{{[0-9]*}} to [[C]] - c = c + 1 - ! CHECK: fir.load [[N]] - ! CHECK: addi %{{[0-9]*}}, %c1 - ! CHECK: fir.store %{{[0-9]*}} to [[N]] - n = n + 1 - ! CHECK: fir.load [[N]] - ! CHECK: fir.embox [[T]] - ! CHECK: fir.load [[N]] - ! CHECK: fir.load [[B]] - ! CHECK: fir.load [[C]] - ! CHECK: fir.load [[D]] - print*, n, t, a, b, c, d ! expect: 102 111 223 333 102 105 223 7 - end associate - - call nest - - associate (x=>i) - ! CHECK: [[IVAL:%[0-9]+]] = fir.load [[I]] : !fir.ref - ! CHECK: [[TWO:%.*]] = arith.constant 2 : i32 - ! CHECK: arith.cmpi eq, [[IVAL]], [[TWO]] : i32 - ! CHECK: ^bb - if (x==2) goto 9 - ! CHECK: [[IVAL:%[0-9]+]] = fir.load [[I]] : !fir.ref - ! CHECK: [[THREE:%.*]] = arith.constant 3 : i32 - ! CHECK: arith.cmpi eq, [[IVAL]], [[THREE]] : i32 - ! CHECK: ^bb - ! CHECK: fir.call @_FortranAStopStatementText - ! CHECK: fir.unreachable - ! CHECK: ^bb - if (x==3) stop 'Halt' - ! CHECK: fir.call @_FortranAioOutputAscii - print*, "ok" - 9 end associate - end - - ! CHECK-LABEL: func @_QPfoo - integer function foo(x) - integer x - integer, save :: i = 0 - i = i + x - foo = i - end function foo - - ! CHECK-LABEL: func @_QPnest( - subroutine nest - integer, parameter :: n = 10 - integer :: a(5), b(n) - associate (s => sequence(size(a))) - a = s - associate(t => sequence(n)) - b = t - ! CHECK: cond_br %{{.*}}, [[BB1:\^bb[0-9]]], [[BB2:\^bb[0-9]]] - ! CHECK: [[BB1]]: - ! CHECK: br [[BB3:\^bb[0-9]]] - ! CHECK: [[BB2]]: - if (a(1) > b(1)) goto 9 - end associate - a = a * a + ! CHECK: addi %{{[0-9]*}}, %c1 + ! CHECK: fir.store %{{[0-9]*}} to [[N]] + a = a + 1 + ! CHECK: fir.load [[C]] + ! CHECK: addi %{{[0-9]*}}, %c1 + ! CHECK: fir.store %{{[0-9]*}} to [[C]] + c = c + 1 + ! CHECK: fir.load [[N]] + ! CHECK: addi %{{[0-9]*}}, %c1 + ! CHECK: fir.store %{{[0-9]*}} to [[N]] + n = n + 1 + ! CHECK: fir.load [[N]] + ! CHECK: fir.embox [[T]] + ! CHECK: fir.load [[N]] + ! CHECK: fir.load [[B]] + ! CHECK: fir.load [[C]] + ! CHECK: fir.load [[D]] + print*, n, t, a, b, c, d ! expect: 102 111 223 333 102 105 223 7 + end associate + + call nest + + associate (x=>i) + ! CHECK: [[IVAL:%[0-9]+]] = fir.load [[I]] : !fir.ref + ! CHECK: [[TWO:%.*]] = arith.constant 2 : i32 + ! CHECK: arith.cmpi eq, [[IVAL]], [[TWO]] : i32 + ! CHECK: ^bb + if (x==2) goto 9 + ! CHECK: [[IVAL:%[0-9]+]] = fir.load [[I]] : !fir.ref + ! CHECK: [[THREE:%.*]] = arith.constant 3 : i32 + ! CHECK: arith.cmpi eq, [[IVAL]], [[THREE]] : i32 + ! CHECK: ^bb + ! CHECK: fir.call @_FortranAStopStatementText + ! CHECK: fir.unreachable + ! CHECK: ^bb + if (x==3) stop 'Halt' + ! CHECK: fir.call @_FortranAioOutputAscii + print*, "ok" + 9 end associate +end + +! CHECK-LABEL: func @_QPfoo +integer function foo(x) + integer x + integer, save :: i = 0 + i = i + x + foo = i +end function foo + +! CHECK-LABEL: func @_QPnest( +subroutine nest + integer, parameter :: n = 10 + integer :: a(5), b(n) + associate (s => sequence(size(a))) + a = s + associate(t => sequence(n)) + b = t + ! CHECK: cond_br %{{.*}}, [[BB1:\^bb[0-9]]], [[BB2:\^bb[0-9]]] + ! CHECK: [[BB1]]: + ! CHECK: br [[BB3:\^bb[0-9]]] + ! CHECK: [[BB2]]: + if (a(1) > b(1)) goto 9 end associate - ! CHECK: br [[BB3]] - ! CHECK: [[BB3]]: - 9 print *, sum(a), sum(b) ! expect: 55 55 - contains - function sequence(n) - integer sequence(n) - sequence = [(i,i=1,n)] - end function - end subroutine nest + a = a * a + end associate + ! CHECK: br [[BB3]] + ! CHECK: [[BB3]]: +9 print *, sum(a), sum(b) ! expect: 55 55 +contains + function sequence(n) + integer sequence(n) + sequence = [(i,i=1,n)] + end function +end subroutine nest diff --git a/flang/test/Lower/common-block.f90 b/flang/test/Lower/common-block.f90 index f01b2f61aced3..9a103eacc88ad 100644 --- a/flang/test/Lower/common-block.f90 +++ b/flang/test/Lower/common-block.f90 @@ -9,65 +9,65 @@ ! CHECK-LABEL: _QPs0 subroutine s0 - common // a0, b0 - - ! CHECK: call void @_QPs(float* bitcast ([8 x i8]* @_QB to float*), float* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_QB, i32 0, i64 4) to float*)) - call s(a0, b0) - end subroutine s0 - - ! CHECK-LABEL: _QPs1 - subroutine s1 - common /x/ a1, b1 - data a1 /1.0/, b1 /2.0/ - - ! CHECK: call void @_QPs(float* getelementptr inbounds ({ float, float }, { float, float }* @_QBx, i32 0, i32 0), float* bitcast (i8* getelementptr (i8, i8* bitcast ({ float, float }* @_QBx to i8*), i64 4) to float*)) - call s(a1, b1) - end subroutine s1 - - ! CHECK-LABEL: _QPs2 - subroutine s2 - common /y/ a2, b2, c2 - - ! CHECK: call void @_QPs(float* bitcast ([12 x i8]* @_QBy to float*), float* bitcast (i8* getelementptr inbounds ([12 x i8], [12 x i8]* @_QBy, i32 0, i64 4) to float*)) - call s(a2, b2) - end subroutine s2 - - ! Test that common initialized through aliases of common members are getting - ! the correct initializer. - ! CHECK-LABEL: _QPs3 - subroutine s3 - integer :: i = 42 - real :: x - complex :: c - real :: glue(2) - real :: y = 3. - equivalence (i, x), (glue(1), c), (glue(2), y) - ! x and c are not directly initialized, but overlapping aliases are. - common /z/ x, c - end subroutine s3 - - module mod_with_common - integer :: i, j - common /c_in_mod/ i, j - end module - ! CHECK-LABEL: _QPs4 - subroutine s4 - use mod_with_common - ! CHECK: load i32, i32* bitcast ([8 x i8]* @_QBc_in_mod to i32*) - print *, i - ! CHECK: load i32, i32* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_QBc_in_mod, i32 0, i64 4) to i32*) - print *, j - end subroutine s4 - - ! CHECK-LABEL: _QPs5 - subroutine s5 - real r(1:0) - common /rien/ r - end subroutine s5 - - ! CHECK-LABEL: _QPs6 - subroutine s6 - real r1(1:0), r2(1:0), x, y - common /with_empty_equiv/ x, r1, y - equivalence(r1, r2) - end subroutine s6 + common // a0, b0 + + ! CHECK: call void @_QPs(float* bitcast ([8 x i8]* @_QB to float*), float* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_QB, i32 0, i64 4) to float*)) + call s(a0, b0) +end subroutine s0 + +! CHECK-LABEL: _QPs1 +subroutine s1 + common /x/ a1, b1 + data a1 /1.0/, b1 /2.0/ + + ! CHECK: call void @_QPs(float* getelementptr inbounds ({ float, float }, { float, float }* @_QBx, i32 0, i32 0), float* bitcast (i8* getelementptr (i8, i8* bitcast ({ float, float }* @_QBx to i8*), i64 4) to float*)) + call s(a1, b1) +end subroutine s1 + +! CHECK-LABEL: _QPs2 +subroutine s2 + common /y/ a2, b2, c2 + + ! CHECK: call void @_QPs(float* bitcast ([12 x i8]* @_QBy to float*), float* bitcast (i8* getelementptr inbounds ([12 x i8], [12 x i8]* @_QBy, i32 0, i64 4) to float*)) + call s(a2, b2) +end subroutine s2 + +! Test that common initialized through aliases of common members are getting +! the correct initializer. +! CHECK-LABEL: _QPs3 +subroutine s3 + integer :: i = 42 + real :: x + complex :: c + real :: glue(2) + real :: y = 3. + equivalence (i, x), (glue(1), c), (glue(2), y) + ! x and c are not directly initialized, but overlapping aliases are. + common /z/ x, c +end subroutine s3 + +module mod_with_common + integer :: i, j + common /c_in_mod/ i, j +end module +! CHECK-LABEL: _QPs4 +subroutine s4 + use mod_with_common + ! CHECK: load i32, i32* bitcast ([8 x i8]* @_QBc_in_mod to i32*) + print *, i + ! CHECK: load i32, i32* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_QBc_in_mod, i32 0, i64 4) to i32*) + print *, j +end subroutine s4 + +! CHECK-LABEL: _QPs5 +subroutine s5 + real r(1:0) + common /rien/ r +end subroutine s5 + +! CHECK-LABEL: _QPs6 +subroutine s6 + real r1(1:0), r2(1:0), x, y + common /with_empty_equiv/ x, r1, y + equivalence(r1, r2) +end subroutine s6 diff --git a/flang/test/Lower/derived-pointer-components.f90 b/flang/test/Lower/derived-pointer-components.f90 index d16e543cf6116..a113e85bfc901 100644 --- a/flang/test/Lower/derived-pointer-components.f90 +++ b/flang/test/Lower/derived-pointer-components.f90 @@ -2,674 +2,674 @@ ! RUN: bbc -emit-fir %s -o - | FileCheck %s module pcomp - implicit none - type t + implicit none + type t + real :: x + integer :: i + end type + interface + subroutine takes_real_scalar(x) real :: x - integer :: i - end type - interface - subroutine takes_real_scalar(x) - real :: x - end subroutine - subroutine takes_char_scalar(x) - character(*) :: x - end subroutine - subroutine takes_derived_scalar(x) - import t - type(t) :: x - end subroutine - subroutine takes_real_array(x) - real :: x(:) - end subroutine - subroutine takes_char_array(x) - character(*) :: x(:) - end subroutine - subroutine takes_derived_array(x) - import t - type(t) :: x(:) - end subroutine - subroutine takes_real_scalar_pointer(x) - real, pointer :: x - end subroutine - subroutine takes_real_array_pointer(x) - real, pointer :: x(:) - end subroutine - subroutine takes_logical(x) - logical :: x - end subroutine - end interface - - type real_p0 - real, pointer :: p - end type - type real_p1 - real, pointer :: p(:) - end type - type cst_char_p0 - character(10), pointer :: p - end type - type cst_char_p1 - character(10), pointer :: p(:) - end type - type def_char_p0 - character(:), pointer :: p - end type - type def_char_p1 - character(:), pointer :: p(:) - end type - type derived_p0 - type(t), pointer :: p - end type - type derived_p1 - type(t), pointer :: p(:) - end type - - real, target :: real_target, real_array_target(100) - character(10), target :: char_target, char_array_target(100) - - contains - - ! ----------------------------------------------------------------------------- - ! Test pointer component references - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPref_scalar_real_p( - ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>}>>{{.*}}, %[[arg1:.*]]: !fir.ref>>}>>{{.*}}, %[[arg2:.*]]: !fir.ref>}>>>{{.*}}, %[[arg3:.*]]: !fir.ref>>}>>>{{.*}}) { - subroutine ref_scalar_real_p(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(real_p1) :: p1_0, p1_1(100) - - ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p0{p:!fir.box>}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], %[[fld]] : (!fir.ref>}>>, !fir.field) -> !fir.ref>> - ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>> - ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>) -> !fir.ptr - ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr) -> !fir.ref - ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) : (!fir.ref) -> () - call takes_real_scalar(p0_0%p) - - ! CHECK: %[[p0_1_coor:.*]] = fir.coordinate_of %[[arg2]], %{{.*}} : (!fir.ref>}>>>, i64) -> !fir.ref>}>> - ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p0{p:!fir.box>}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_1_coor]], %[[fld]] : (!fir.ref>}>>, !fir.field) -> !fir.ref>> - ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>> - ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>) -> !fir.ptr - ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr) -> !fir.ref - ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) : (!fir.ref) -> () - call takes_real_scalar(p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p1{p:!fir.box>>}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg1]], %[[fld]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> - ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>>> - ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[load]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64 - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[load]], %[[index]] : (!fir.box>>, i64) -> !fir.ref - ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) : (!fir.ref) -> () - call takes_real_scalar(p1_0%p(7)) - - ! CHECK: %[[p1_1_coor:.*]] = fir.coordinate_of %[[arg3]], %{{.*}} : (!fir.ref>>}>>>, i64) -> !fir.ref>>}>> - ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p1{p:!fir.box>>}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_1_coor]], %[[fld]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> - ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>>> - ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[load]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64 - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[load]], %[[index]] : (!fir.box>>, i64) -> !fir.ref - ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) : (!fir.ref) -> () - call takes_real_scalar(p1_1(5)%p(7)) - end subroutine - - ! CHECK-LABEL: func @_QMpcompPassign_scalar_real - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine assign_scalar_real_p(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(real_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] - ! CHECK: fir.store {{.*}} to %[[addr]] - p0_0%p = 1. - - ! CHECK: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] - ! CHECK: fir.store {{.*}} to %[[addr]] - p0_1(5)%p = 2. - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], {{.*}} - ! CHECK: fir.store {{.*}} to %[[addr]] - p1_0%p(7) = 3. - - ! CHECK: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], {{.*}} - ! CHECK: fir.store {{.*}} to %[[addr]] - p1_1(5)%p(7) = 4. - end subroutine - - ! CHECK-LABEL: func @_QMpcompPref_scalar_cst_char_p - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine ref_scalar_cst_char_p(p0_0, p1_0, p0_1, p1_1) - type(cst_char_p0) :: p0_0, p0_1(100) - type(cst_char_p1) :: p1_0, p1_1(100) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] - ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] - ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p0_1(5)%p) - - - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} - ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] - ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p1_0%p(7)) - - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} - ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] - ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p1_1(5)%p(7)) - - end subroutine - - ! CHECK-LABEL: func @_QMpcompPref_scalar_def_char_p - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine ref_scalar_def_char_p(p0_0, p1_0, p0_1, p1_1) - type(def_char_p0) :: p0_0, p0_1(100) - type(def_char_p1) :: p1_0, p1_1(100) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] - ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] - ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]] - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] - ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] - ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]] - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p0_1(5)%p) - - - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] - ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} - ! CHECK-DAG: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK-DAG: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK-DAG: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]] - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p1_0%p(7)) - - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] - ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} - ! CHECK-DAG: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK-DAG: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK-DAG: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] - ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]] - ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) - call takes_char_scalar(p1_1(5)%p(7)) - - end subroutine - - ! CHECK-LABEL: func @_QMpcompPref_scalar_derived - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine ref_scalar_derived(p0_0, p1_0, p0_1, p1_1) - type(derived_p0) :: p0_0, p0_1(100) - type(derived_p1) :: p1_0, p1_1(100) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[fldx:.*]] = fir.field_index x - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]] - ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) - call takes_real_scalar(p0_0%p%x) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[fldx:.*]] = fir.field_index x - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]] - ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) - call takes_real_scalar(p0_1(5)%p%x) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} - ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]] - ! CHECK: %[[fldx:.*]] = fir.field_index x - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]] - ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) - call takes_real_scalar(p1_0%p(7)%x) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} - ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 - ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]] - ! CHECK: %[[fldx:.*]] = fir.field_index x - ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]] - ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) - call takes_real_scalar(p1_1(5)%p(7)%x) - - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test passing pointer component references as pointers - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPpass_real_p - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine pass_real_p(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(real_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]]) - call takes_real_scalar_pointer(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]]) - call takes_real_scalar_pointer(p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]]) - call takes_real_array_pointer(p1_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]]) - call takes_real_array_pointer(p1_1(5)%p) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test usage in intrinsics where pointer aspect matters - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPassociated_p - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine associated_p(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(def_char_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: fir.box_addr %[[box]] - call takes_logical(associated(p0_0%p)) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: fir.box_addr %[[box]] - call takes_logical(associated(p0_1(5)%p)) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: fir.box_addr %[[box]] - call takes_logical(associated(p1_0%p)) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: %[[box:.*]] = fir.load %[[coor]] - ! CHECK: fir.box_addr %[[box]] - call takes_logical(associated(p1_1(5)%p)) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test pointer assignment of components - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPpassoc_real - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine passoc_real(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(real_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p0_0%p => real_target - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p0_1(5)%p => real_target - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p1_0%p => real_array_target - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p1_1(5)%p => real_array_target - end subroutine - - ! CHECK-LABEL: func @_QMpcompPpassoc_char - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine passoc_char(p0_0, p1_0, p0_1, p1_1) - type(cst_char_p0) :: p0_0, p0_1(100) - type(def_char_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p0_0%p => char_target - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p0_1(5)%p => char_target - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p1_0%p => char_array_target - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - p1_1(5)%p => char_array_target - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test nullify of components - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPnullify_test - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine nullify_test(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(def_char_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - nullify(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - nullify(p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - nullify(p1_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - nullify(p1_1(5)%p) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test allocation - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPallocate_real - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine allocate_real(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(real_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p1_0%p(100)) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p1_1(5)%p(100)) - end subroutine - - ! CHECK-LABEL: func @_QMpcompPallocate_cst_char - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine allocate_cst_char(p0_0, p1_0, p0_1, p1_1) - type(cst_char_p0) :: p0_0, p0_1(100) - type(cst_char_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p1_0%p(100)) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(p1_1(5)%p(100)) - end subroutine - - ! CHECK-LABEL: func @_QMpcompPallocate_def_char - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine allocate_def_char(p0_0, p1_0, p0_1, p1_1) - type(def_char_p0) :: p0_0, p0_1(100) - type(def_char_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(character(18)::p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(character(18)::p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(character(18)::p1_0%p(100)) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - allocate(character(18)::p1_1(5)%p(100)) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test deallocation - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPdeallocate_real - ! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) - subroutine deallocate_real(p0_0, p1_0, p0_1, p1_1) - type(real_p0) :: p0_0, p0_1(100) - type(real_p1) :: p1_0, p1_1(100) - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - deallocate(p0_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - deallocate(p0_1(5)%p) - - ! CHECK: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - deallocate(p1_0%p) - - ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} - ! CHECK-DAG: %[[fld:.*]] = fir.field_index p - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] - ! CHECK: fir.store {{.*}} to %[[coor]] - deallocate(p1_1(5)%p) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test a very long component - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMpcompPvery_long - ! CHECK-SAME: (%[[x:.*]]: {{.*}}) - subroutine very_long(x) - type t0 - real :: f - end type - type t1 - type(t0), allocatable :: e(:) - end type - type t2 - type(t1) :: d(10) - end type - type t3 - type(t2) :: c - end type - type t4 - type(t3), pointer :: b - end type - type t5 - type(t4) :: a - end type - type(t5) :: x(:, :, :, :, :) - - ! CHECK: %[[coor0:.*]] = fir.coordinate_of %[[x]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.}} - ! CHECK-DAG: %[[flda:.*]] = fir.field_index a - ! CHECK-DAG: %[[fldb:.*]] = fir.field_index b - ! CHECK: %[[coor1:.*]] = fir.coordinate_of %[[coor0]], %[[flda]], %[[fldb]] - ! CHECK: %[[b_box:.*]] = fir.load %[[coor1]] - ! CHECK-DAG: %[[fldc:.*]] = fir.field_index c - ! CHECK-DAG: %[[fldd:.*]] = fir.field_index d - ! CHECK: %[[coor2:.*]] = fir.coordinate_of %[[b_box]], %[[fldc]], %[[fldd]] - ! CHECK: %[[index:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64 - ! CHECK: %[[coor3:.*]] = fir.coordinate_of %[[coor2]], %[[index]] - ! CHECK: %[[flde:.*]] = fir.field_index e - ! CHECK: %[[coor4:.*]] = fir.coordinate_of %[[coor3]], %[[flde]] - ! CHECK: %[[e_box:.*]] = fir.load %[[coor4]] - ! CHECK: %[[edims:.*]]:3 = fir.box_dims %[[e_box]], %c0{{.*}} - ! CHECK: %[[lb:.*]] = fir.convert %[[edims]]#0 : (index) -> i64 - ! CHECK: %[[index2:.*]] = arith.subi %c7{{.*}}, %[[lb]] - ! CHECK: %[[coor5:.*]] = fir.coordinate_of %[[e_box]], %[[index2]] - ! CHECK: %[[fldf:.*]] = fir.field_index f - ! CHECK: %[[coor6:.*]] = fir.coordinate_of %[[coor5]], %[[fldf:.*]] - ! CHECK: fir.load %[[coor6]] : !fir.ref - print *, x(1,2,3,4,5)%a%b%c%d(6)%e(7)%f - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test a recursive derived type reference - ! ----------------------------------------------------------------------------- - - ! CHECK: func @_QMpcompPtest_recursive - ! CHECK-SAME: (%[[x:.*]]: {{.*}}) - subroutine test_recursive(x) - type t - integer :: i - type(t), pointer :: next - end type - type(t) :: x - - ! CHECK: %[[fldNext1:.*]] = fir.field_index next - ! CHECK: %[[next1:.*]] = fir.coordinate_of %[[x]], %[[fldNext1]] - ! CHECK: %[[nextBox1:.*]] = fir.load %[[next1]] - ! CHECK: %[[fldNext2:.*]] = fir.field_index next - ! CHECK: %[[next2:.*]] = fir.coordinate_of %[[nextBox1]], %[[fldNext2]] - ! CHECK: %[[nextBox2:.*]] = fir.load %[[next2]] - ! CHECK: %[[fldNext3:.*]] = fir.field_index next - ! CHECK: %[[next3:.*]] = fir.coordinate_of %[[nextBox2]], %[[fldNext3]] - ! CHECK: %[[nextBox3:.*]] = fir.load %[[next3]] - ! CHECK: %[[fldi:.*]] = fir.field_index i - ! CHECK: %[[i:.*]] = fir.coordinate_of %[[nextBox3]], %[[fldi]] - ! CHECK: %[[nextBox3:.*]] = fir.load %[[i]] : !fir.ref - print *, x%next%next%next%i - end subroutine - - end module + end subroutine + subroutine takes_char_scalar(x) + character(*) :: x + end subroutine + subroutine takes_derived_scalar(x) + import t + type(t) :: x + end subroutine + subroutine takes_real_array(x) + real :: x(:) + end subroutine + subroutine takes_char_array(x) + character(*) :: x(:) + end subroutine + subroutine takes_derived_array(x) + import t + type(t) :: x(:) + end subroutine + subroutine takes_real_scalar_pointer(x) + real, pointer :: x + end subroutine + subroutine takes_real_array_pointer(x) + real, pointer :: x(:) + end subroutine + subroutine takes_logical(x) + logical :: x + end subroutine + end interface + + type real_p0 + real, pointer :: p + end type + type real_p1 + real, pointer :: p(:) + end type + type cst_char_p0 + character(10), pointer :: p + end type + type cst_char_p1 + character(10), pointer :: p(:) + end type + type def_char_p0 + character(:), pointer :: p + end type + type def_char_p1 + character(:), pointer :: p(:) + end type + type derived_p0 + type(t), pointer :: p + end type + type derived_p1 + type(t), pointer :: p(:) + end type + + real, target :: real_target, real_array_target(100) + character(10), target :: char_target, char_array_target(100) + +contains + +! ----------------------------------------------------------------------------- +! Test pointer component references +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPref_scalar_real_p( +! CHECK-SAME: %[[arg0:.*]]: !fir.ref>}>>{{.*}}, %[[arg1:.*]]: !fir.ref>>}>>{{.*}}, %[[arg2:.*]]: !fir.ref>}>>>{{.*}}, %[[arg3:.*]]: !fir.ref>>}>>>{{.*}}) { +subroutine ref_scalar_real_p(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(real_p1) :: p1_0, p1_1(100) + + ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p0{p:!fir.box>}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], %[[fld]] : (!fir.ref>}>>, !fir.field) -> !fir.ref>> + ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>> + ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>) -> !fir.ptr + ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr) -> !fir.ref + ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) : (!fir.ref) -> () + call takes_real_scalar(p0_0%p) + + ! CHECK: %[[p0_1_coor:.*]] = fir.coordinate_of %[[arg2]], %{{.*}} : (!fir.ref>}>>>, i64) -> !fir.ref>}>> + ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p0{p:!fir.box>}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_1_coor]], %[[fld]] : (!fir.ref>}>>, !fir.field) -> !fir.ref>> + ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>> + ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>) -> !fir.ptr + ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr) -> !fir.ref + ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) : (!fir.ref) -> () + call takes_real_scalar(p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p1{p:!fir.box>>}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg1]], %[[fld]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> + ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>>> + ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[load]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64 + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[load]], %[[index]] : (!fir.box>>, i64) -> !fir.ref + ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) : (!fir.ref) -> () + call takes_real_scalar(p1_0%p(7)) + + ! CHECK: %[[p1_1_coor:.*]] = fir.coordinate_of %[[arg3]], %{{.*}} : (!fir.ref>>}>>>, i64) -> !fir.ref>>}>> + ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMpcompTreal_p1{p:!fir.box>>}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_1_coor]], %[[fld]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> + ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>>> + ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[load]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64 + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[load]], %[[index]] : (!fir.box>>, i64) -> !fir.ref + ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) : (!fir.ref) -> () + call takes_real_scalar(p1_1(5)%p(7)) +end subroutine + +! CHECK-LABEL: func @_QMpcompPassign_scalar_real +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine assign_scalar_real_p(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(real_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] + ! CHECK: fir.store {{.*}} to %[[addr]] + p0_0%p = 1. + + ! CHECK: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] + ! CHECK: fir.store {{.*}} to %[[addr]] + p0_1(5)%p = 2. + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], {{.*}} + ! CHECK: fir.store {{.*}} to %[[addr]] + p1_0%p(7) = 3. + + ! CHECK: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], {{.*}} + ! CHECK: fir.store {{.*}} to %[[addr]] + p1_1(5)%p(7) = 4. +end subroutine + +! CHECK-LABEL: func @_QMpcompPref_scalar_cst_char_p +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine ref_scalar_cst_char_p(p0_0, p1_0, p0_1, p1_1) + type(cst_char_p0) :: p0_0, p0_1(100) + type(cst_char_p1) :: p1_0, p1_1(100) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] + ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] + ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p0_1(5)%p) + + + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} + ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] + ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p1_0%p(7)) + + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} + ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] + ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p1_1(5)%p(7)) + +end subroutine + +! CHECK-LABEL: func @_QMpcompPref_scalar_def_char_p +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine ref_scalar_def_char_p(p0_0, p1_0, p0_1, p1_1) + type(def_char_p0) :: p0_0, p0_1(100) + type(def_char_p1) :: p1_0, p1_1(100) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] + ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] + ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]] + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] + ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] + ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]] + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p0_1(5)%p) + + + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] + ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} + ! CHECK-DAG: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK-DAG: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK-DAG: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]] + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p1_0%p(7)) + + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] + ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} + ! CHECK-DAG: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK-DAG: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK-DAG: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[index]] + ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]] + ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) + call takes_char_scalar(p1_1(5)%p(7)) + +end subroutine + +! CHECK-LABEL: func @_QMpcompPref_scalar_derived +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine ref_scalar_derived(p0_0, p1_0, p0_1, p1_1) + type(derived_p0) :: p0_0, p0_1(100) + type(derived_p1) :: p1_0, p1_1(100) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[fldx:.*]] = fir.field_index x + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]] + ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) + call takes_real_scalar(p0_0%p%x) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[fldx:.*]] = fir.field_index x + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]] + ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) + call takes_real_scalar(p0_1(5)%p%x) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} + ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]] + ! CHECK: %[[fldx:.*]] = fir.field_index x + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]] + ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) + call takes_real_scalar(p1_0%p(7)%x) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} + ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64 + ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]] + ! CHECK: %[[fldx:.*]] = fir.field_index x + ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]] + ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]]) + call takes_real_scalar(p1_1(5)%p(7)%x) + +end subroutine + +! ----------------------------------------------------------------------------- +! Test passing pointer component references as pointers +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPpass_real_p +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine pass_real_p(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(real_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]]) + call takes_real_scalar_pointer(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]]) + call takes_real_scalar_pointer(p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]]) + call takes_real_array_pointer(p1_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]]) + call takes_real_array_pointer(p1_1(5)%p) +end subroutine + +! ----------------------------------------------------------------------------- +! Test usage in intrinsics where pointer aspect matters +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPassociated_p +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine associated_p(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(def_char_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: fir.box_addr %[[box]] + call takes_logical(associated(p0_0%p)) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: fir.box_addr %[[box]] + call takes_logical(associated(p0_1(5)%p)) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: fir.box_addr %[[box]] + call takes_logical(associated(p1_0%p)) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: %[[box:.*]] = fir.load %[[coor]] + ! CHECK: fir.box_addr %[[box]] + call takes_logical(associated(p1_1(5)%p)) +end subroutine + +! ----------------------------------------------------------------------------- +! Test pointer assignment of components +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPpassoc_real +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine passoc_real(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(real_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p0_0%p => real_target + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p0_1(5)%p => real_target + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p1_0%p => real_array_target + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p1_1(5)%p => real_array_target +end subroutine + +! CHECK-LABEL: func @_QMpcompPpassoc_char +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine passoc_char(p0_0, p1_0, p0_1, p1_1) + type(cst_char_p0) :: p0_0, p0_1(100) + type(def_char_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p0_0%p => char_target + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p0_1(5)%p => char_target + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p1_0%p => char_array_target + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + p1_1(5)%p => char_array_target +end subroutine + +! ----------------------------------------------------------------------------- +! Test nullify of components +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPnullify_test +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine nullify_test(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(def_char_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + nullify(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + nullify(p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + nullify(p1_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + nullify(p1_1(5)%p) +end subroutine + +! ----------------------------------------------------------------------------- +! Test allocation +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPallocate_real +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine allocate_real(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(real_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p1_0%p(100)) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p1_1(5)%p(100)) +end subroutine + +! CHECK-LABEL: func @_QMpcompPallocate_cst_char +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine allocate_cst_char(p0_0, p1_0, p0_1, p1_1) + type(cst_char_p0) :: p0_0, p0_1(100) + type(cst_char_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p1_0%p(100)) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(p1_1(5)%p(100)) +end subroutine + +! CHECK-LABEL: func @_QMpcompPallocate_def_char +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine allocate_def_char(p0_0, p1_0, p0_1, p1_1) + type(def_char_p0) :: p0_0, p0_1(100) + type(def_char_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(character(18)::p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(character(18)::p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(character(18)::p1_0%p(100)) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + allocate(character(18)::p1_1(5)%p(100)) +end subroutine + +! ----------------------------------------------------------------------------- +! Test deallocation +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPdeallocate_real +! CHECK-SAME: (%[[p0_0:.*]]: {{.*}}, %[[p1_0:.*]]: {{.*}}, %[[p0_1:.*]]: {{.*}}, %[[p1_1:.*]]: {{.*}}) +subroutine deallocate_real(p0_0, p1_0, p0_1, p1_1) + type(real_p0) :: p0_0, p0_1(100) + type(real_p1) :: p1_0, p1_1(100) + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p0_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + deallocate(p0_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p0_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + deallocate(p0_1(5)%p) + + ! CHECK: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[p1_0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + deallocate(p1_0%p) + + ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[p1_1]], %{{.*}} + ! CHECK-DAG: %[[fld:.*]] = fir.field_index p + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]] + ! CHECK: fir.store {{.*}} to %[[coor]] + deallocate(p1_1(5)%p) +end subroutine + +! ----------------------------------------------------------------------------- +! Test a very long component +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMpcompPvery_long +! CHECK-SAME: (%[[x:.*]]: {{.*}}) +subroutine very_long(x) + type t0 + real :: f + end type + type t1 + type(t0), allocatable :: e(:) + end type + type t2 + type(t1) :: d(10) + end type + type t3 + type(t2) :: c + end type + type t4 + type(t3), pointer :: b + end type + type t5 + type(t4) :: a + end type + type(t5) :: x(:, :, :, :, :) + + ! CHECK: %[[coor0:.*]] = fir.coordinate_of %[[x]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.}} + ! CHECK-DAG: %[[flda:.*]] = fir.field_index a + ! CHECK-DAG: %[[fldb:.*]] = fir.field_index b + ! CHECK: %[[coor1:.*]] = fir.coordinate_of %[[coor0]], %[[flda]], %[[fldb]] + ! CHECK: %[[b_box:.*]] = fir.load %[[coor1]] + ! CHECK-DAG: %[[fldc:.*]] = fir.field_index c + ! CHECK-DAG: %[[fldd:.*]] = fir.field_index d + ! CHECK: %[[coor2:.*]] = fir.coordinate_of %[[b_box]], %[[fldc]], %[[fldd]] + ! CHECK: %[[index:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64 + ! CHECK: %[[coor3:.*]] = fir.coordinate_of %[[coor2]], %[[index]] + ! CHECK: %[[flde:.*]] = fir.field_index e + ! CHECK: %[[coor4:.*]] = fir.coordinate_of %[[coor3]], %[[flde]] + ! CHECK: %[[e_box:.*]] = fir.load %[[coor4]] + ! CHECK: %[[edims:.*]]:3 = fir.box_dims %[[e_box]], %c0{{.*}} + ! CHECK: %[[lb:.*]] = fir.convert %[[edims]]#0 : (index) -> i64 + ! CHECK: %[[index2:.*]] = arith.subi %c7{{.*}}, %[[lb]] + ! CHECK: %[[coor5:.*]] = fir.coordinate_of %[[e_box]], %[[index2]] + ! CHECK: %[[fldf:.*]] = fir.field_index f + ! CHECK: %[[coor6:.*]] = fir.coordinate_of %[[coor5]], %[[fldf:.*]] + ! CHECK: fir.load %[[coor6]] : !fir.ref + print *, x(1,2,3,4,5)%a%b%c%d(6)%e(7)%f +end subroutine + +! ----------------------------------------------------------------------------- +! Test a recursive derived type reference +! ----------------------------------------------------------------------------- + +! CHECK: func @_QMpcompPtest_recursive +! CHECK-SAME: (%[[x:.*]]: {{.*}}) +subroutine test_recursive(x) + type t + integer :: i + type(t), pointer :: next + end type + type(t) :: x + + ! CHECK: %[[fldNext1:.*]] = fir.field_index next + ! CHECK: %[[next1:.*]] = fir.coordinate_of %[[x]], %[[fldNext1]] + ! CHECK: %[[nextBox1:.*]] = fir.load %[[next1]] + ! CHECK: %[[fldNext2:.*]] = fir.field_index next + ! CHECK: %[[next2:.*]] = fir.coordinate_of %[[nextBox1]], %[[fldNext2]] + ! CHECK: %[[nextBox2:.*]] = fir.load %[[next2]] + ! CHECK: %[[fldNext3:.*]] = fir.field_index next + ! CHECK: %[[next3:.*]] = fir.coordinate_of %[[nextBox2]], %[[fldNext3]] + ! CHECK: %[[nextBox3:.*]] = fir.load %[[next3]] + ! CHECK: %[[fldi:.*]] = fir.field_index i + ! CHECK: %[[i:.*]] = fir.coordinate_of %[[nextBox3]], %[[fldi]] + ! CHECK: %[[nextBox3:.*]] = fir.load %[[i]] : !fir.ref + print *, x%next%next%next%i +end subroutine + +end module diff --git a/flang/test/Lower/derived-types-kind-params.f90 b/flang/test/Lower/derived-types-kind-params.f90 index c19df07f575ce..54cfdd1f5867f 100644 --- a/flang/test/Lower/derived-types-kind-params.f90 +++ b/flang/test/Lower/derived-types-kind-params.f90 @@ -2,55 +2,55 @@ ! RUN: bbc -emit-fir %s -o - | FileCheck %s module m - type t(k1, k2) - integer(4), kind :: k1 = 7 - integer(8), kind :: k2 - character(k1) :: c(k2) - end type - - type t2(k1, k2) - integer(4), kind :: k1 - integer(8), kind :: k2 - type(t(k1+3, k2+4)) :: at - end type - - type t3(k) - integer, kind :: k - type(t3(k)), pointer :: at3 - end type - - type t4(k) - integer, kind :: k - real(-k) :: i - end type - - contains - - ! ----------------------------------------------------------------------------- - ! Test mangling of derived type with kind parameters - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMmPfoo - ! CHECK-SAME: !fir.ref> - subroutine foo(at) - type(t(k2=12)) :: at - end subroutine - - ! CHECK-LABEL: func @_QMmPfoo2 - ! CHECK-SAME: !fir.ref>}>}>> - subroutine foo2(at2) - type(t2(12, 13)) :: at2 - end subroutine - - ! CHECK-LABEL: func @_QMmPfoo3 - ! CHECK-SAME: !fir.ref>>}>> - subroutine foo3(at3) - type(t3(7)) :: at3 - end subroutine - - ! CHECK-LABEL: func @_QMmPfoo4 - ! CHECK-SAME: !fir.ref> - subroutine foo4(at4) - type(t4(-4)) :: at4 - end subroutine - end module + type t(k1, k2) + integer(4), kind :: k1 = 7 + integer(8), kind :: k2 + character(k1) :: c(k2) + end type + + type t2(k1, k2) + integer(4), kind :: k1 + integer(8), kind :: k2 + type(t(k1+3, k2+4)) :: at + end type + + type t3(k) + integer, kind :: k + type(t3(k)), pointer :: at3 + end type + + type t4(k) + integer, kind :: k + real(-k) :: i + end type + +contains + +! ----------------------------------------------------------------------------- +! Test mangling of derived type with kind parameters +! ----------------------------------------------------------------------------- + + ! CHECK-LABEL: func @_QMmPfoo + ! CHECK-SAME: !fir.ref> + subroutine foo(at) + type(t(k2=12)) :: at + end subroutine + + ! CHECK-LABEL: func @_QMmPfoo2 + ! CHECK-SAME: !fir.ref>}>}>> + subroutine foo2(at2) + type(t2(12, 13)) :: at2 + end subroutine + + ! CHECK-LABEL: func @_QMmPfoo3 + ! CHECK-SAME: !fir.ref>>}>> + subroutine foo3(at3) + type(t3(7)) :: at3 + end subroutine + + ! CHECK-LABEL: func @_QMmPfoo4 + ! CHECK-SAME: !fir.ref> + subroutine foo4(at4) + type(t4(-4)) :: at4 + end subroutine +end module diff --git a/flang/test/Lower/derived-types.f90 b/flang/test/Lower/derived-types.f90 index 79db0ae78931d..21113876e4ac1 100644 --- a/flang/test/Lower/derived-types.f90 +++ b/flang/test/Lower/derived-types.f90 @@ -4,192 +4,192 @@ ! Note: only testing non parametrized derived type here. module d - type r - real :: x - end type - type r2 - real :: x_array(10, 20) - end type - type c - character(10) :: ch - end type - type c2 - character(10) :: ch_array(20, 30) - end type - contains - - ! ----------------------------------------------------------------------------- - ! Test simple derived type symbol lowering - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMdPderived_dummy( - ! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: !fir.ref>}>>{{.*}}) { - subroutine derived_dummy(some_r, some_c2) - type(r) :: some_r - type(c2) :: some_c2 - end subroutine - - ! CHECK-LABEL: func @_QMdPlocal_derived( - subroutine local_derived() - ! CHECK-DAG: fir.alloca !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}> - ! CHECK-DAG: fir.alloca !fir.type<_QMdTr{x:f32}> - type(r) :: some_r - type(c2) :: some_c2 - end subroutine - - ! CHECK-LABEL: func @_QMdPsaved_derived( - subroutine saved_derived() - ! CHECK-DAG: fir.address_of(@_QMdFsaved_derivedEsome_c2) : !fir.ref>}>> - ! CHECK-DAG: fir.address_of(@_QMdFsaved_derivedEsome_r) : !fir.ref> - type(r), save :: some_r - type(c2), save :: some_c2 - call use_symbols(some_r, some_c2) - end subroutine - - - ! ----------------------------------------------------------------------------- - ! Test simple derived type references - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMdPscalar_numeric_ref( - subroutine scalar_numeric_ref() - ! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}> - type(r) :: some_r - ! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}> - ! CHECK: fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref>, !fir.field) -> !fir.ref - call real_bar(some_r%x) - end subroutine - - ! CHECK-LABEL: func @_QMdPscalar_character_ref( - subroutine scalar_character_ref() - ! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTc{ch:!fir.char<1,10>}> - type(c) :: some_c - ! CHECK: %[[field:.*]] = fir.field_index ch, !fir.type<_QMdTc{ch:!fir.char<1,10>}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref}>>, !fir.field) -> !fir.ref> - ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : index - ! CHECK-DAG: %[[conv:.*]] = fir.convert %[[coor]] : (!fir.ref>) -> !fir.ref> - ! CHECK: fir.emboxchar %[[conv]], %c10 : (!fir.ref>, index) -> !fir.boxchar<1> - call char_bar(some_c%ch) - end subroutine - - ! FIXME: coordinate of generated for derived%array_comp(i) are not zero based as they - ! should be. - - ! CHECK-LABEL: func @_QMdParray_comp_elt_ref( - subroutine array_comp_elt_ref() - type(r2) :: some_r2 - ! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}> - ! CHECK: %[[field:.*]] = fir.field_index x_array, !fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref}>>, !fir.field) -> !fir.ref> - ! CHECK-DAG: %[[index1:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64 - ! CHECK-DAG: %[[index2:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64 - ! CHECK: fir.coordinate_of %[[coor]], %[[index1]], %[[index2]] : (!fir.ref>, i64, i64) -> !fir.ref - call real_bar(some_r2%x_array(5, 6)) - end subroutine - - - ! CHECK-LABEL: func @_QMdPchar_array_comp_elt_ref( - subroutine char_array_comp_elt_ref() - type(c2) :: some_c2 - ! CHECK: %[[coor:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref>}>>, !fir.field) -> !fir.ref>> - ! CHECK-DAG: %[[index1:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64 - ! CHECK-DAG: %[[index2:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64 - ! CHECK: fir.coordinate_of %[[coor]], %[[index1]], %[[index2]] : (!fir.ref>>, i64, i64) -> !fir.ref> - ! CHECK: fir.emboxchar %{{.*}}, %c10 : (!fir.ref>, index) -> !fir.boxchar<1> - call char_bar(some_c2%ch_array(5, 6)) - end subroutine - - ! CHECK: @_QMdParray_elt_comp_ref - subroutine array_elt_comp_ref() - type(r) :: some_r_array(100) - ! CHECK: %[[alloca:.*]] = fir.alloca !fir.array<100x!fir.type<_QMdTr{x:f32}>> - ! CHECK: %[[index:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64 - ! CHECK: %[[elt:.*]] = fir.coordinate_of %[[alloca]], %[[index]] : (!fir.ref>>, i64) -> !fir.ref> - ! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}> - ! CHECK: fir.coordinate_of %[[elt]], %[[field]] : (!fir.ref>, !fir.field) -> !fir.ref - call real_bar(some_r_array(5)%x) - end subroutine - - ! CHECK: @_QMdPchar_array_elt_comp_ref - subroutine char_array_elt_comp_ref() - type(c) :: some_c_array(100) - ! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref}>>>, i64) -> !fir.ref}>> - ! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref}>>, !fir.field) -> !fir.ref> - ! CHECK: fir.emboxchar %{{.*}}, %c10{{.*}} : (!fir.ref>, index) -> !fir.boxchar<1> - call char_bar(some_c_array(5)%ch) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test loading derived type components - ! ----------------------------------------------------------------------------- - - ! Most of the other tests only require lowering code to compute the address of - ! components. This one requires loading a component which tests other code paths - ! in lowering. - - ! CHECK-LABEL: func @_QMdPscalar_numeric_load( - ! CHECK-SAME: %[[arg0:.*]]: !fir.ref> - real function scalar_numeric_load(some_r) - type(r) :: some_r - ! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}> - ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], %[[field]] : (!fir.ref>, !fir.field) -> !fir.ref - ! CHECK: fir.load %[[coor]] - scalar_numeric_load = some_r%x - end function - - ! ----------------------------------------------------------------------------- - ! Test returned derived types (no length parameters) - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QMdPbar_return_derived() -> !fir.type<_QMdTr{x:f32}> - function bar_return_derived() - ! CHECK: %[[res:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}> - type(r) :: bar_return_derived - ! CHECK: %[[resLoad:.*]] = fir.load %[[res]] : !fir.ref> - ! CHECK: return %[[resLoad]] : !fir.type<_QMdTr{x:f32}> - end function - - ! CHECK-LABEL: func @_QMdPcall_bar_return_derived( - subroutine call_bar_return_derived() - ! CHECK: %[[tmp:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}> - ! CHECK: %[[call:.*]] = fir.call @_QMdPbar_return_derived() : () -> !fir.type<_QMdTr{x:f32}> - ! CHECK: fir.save_result %[[call]] to %[[tmp]] : !fir.type<_QMdTr{x:f32}>, !fir.ref> - ! CHECK: fir.call @_QPr_bar(%[[tmp]]) : (!fir.ref>) -> () - call r_bar(bar_return_derived()) - end subroutine - - end module - - ! ----------------------------------------------------------------------------- - ! Test derived type with pointer/allocatable components - ! ----------------------------------------------------------------------------- - - module d2 - type recursive_t - real :: x - type(recursive_t), pointer :: ptr - end type - contains - ! CHECK-LABEL: func @_QMd2Ptest_recursive_type( - ! CHECK-SAME: %{{.*}}: !fir.ref>>}>>{{.*}}) { - subroutine test_recursive_type(some_recursive) - type(recursive_t) :: some_recursive - end subroutine - end module - - ! ----------------------------------------------------------------------------- - ! Test global derived type symbol lowering - ! ----------------------------------------------------------------------------- - - module data_mod - use d - type(r) :: some_r - type(c2) :: some_c2 - end module - - ! Test globals - - ! CHECK-DAG: fir.global @_QMdata_modEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}> - ! CHECK-DAG: fir.global @_QMdata_modEsome_r : !fir.type<_QMdTr{x:f32}> - ! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}> - ! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_r : !fir.type<_QMdTr{x:f32}> + type r + real :: x + end type + type r2 + real :: x_array(10, 20) + end type + type c + character(10) :: ch + end type + type c2 + character(10) :: ch_array(20, 30) + end type +contains + +! ----------------------------------------------------------------------------- +! Test simple derived type symbol lowering +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMdPderived_dummy( +! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: !fir.ref>}>>{{.*}}) { +subroutine derived_dummy(some_r, some_c2) + type(r) :: some_r + type(c2) :: some_c2 +end subroutine + +! CHECK-LABEL: func @_QMdPlocal_derived( +subroutine local_derived() + ! CHECK-DAG: fir.alloca !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}> + ! CHECK-DAG: fir.alloca !fir.type<_QMdTr{x:f32}> + type(r) :: some_r + type(c2) :: some_c2 +end subroutine + +! CHECK-LABEL: func @_QMdPsaved_derived( +subroutine saved_derived() + ! CHECK-DAG: fir.address_of(@_QMdFsaved_derivedEsome_c2) : !fir.ref>}>> + ! CHECK-DAG: fir.address_of(@_QMdFsaved_derivedEsome_r) : !fir.ref> + type(r), save :: some_r + type(c2), save :: some_c2 + call use_symbols(some_r, some_c2) +end subroutine + + +! ----------------------------------------------------------------------------- +! Test simple derived type references +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMdPscalar_numeric_ref( +subroutine scalar_numeric_ref() + ! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}> + type(r) :: some_r + ! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}> + ! CHECK: fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref>, !fir.field) -> !fir.ref + call real_bar(some_r%x) +end subroutine + +! CHECK-LABEL: func @_QMdPscalar_character_ref( +subroutine scalar_character_ref() + ! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTc{ch:!fir.char<1,10>}> + type(c) :: some_c + ! CHECK: %[[field:.*]] = fir.field_index ch, !fir.type<_QMdTc{ch:!fir.char<1,10>}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref}>>, !fir.field) -> !fir.ref> + ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : index + ! CHECK-DAG: %[[conv:.*]] = fir.convert %[[coor]] : (!fir.ref>) -> !fir.ref> + ! CHECK: fir.emboxchar %[[conv]], %c10 : (!fir.ref>, index) -> !fir.boxchar<1> + call char_bar(some_c%ch) +end subroutine + +! FIXME: coordinate of generated for derived%array_comp(i) are not zero based as they +! should be. + +! CHECK-LABEL: func @_QMdParray_comp_elt_ref( +subroutine array_comp_elt_ref() + type(r2) :: some_r2 + ! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}> + ! CHECK: %[[field:.*]] = fir.field_index x_array, !fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref}>>, !fir.field) -> !fir.ref> + ! CHECK-DAG: %[[index1:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64 + ! CHECK-DAG: %[[index2:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64 + ! CHECK: fir.coordinate_of %[[coor]], %[[index1]], %[[index2]] : (!fir.ref>, i64, i64) -> !fir.ref + call real_bar(some_r2%x_array(5, 6)) +end subroutine + + +! CHECK-LABEL: func @_QMdPchar_array_comp_elt_ref( +subroutine char_array_comp_elt_ref() + type(c2) :: some_c2 + ! CHECK: %[[coor:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref>}>>, !fir.field) -> !fir.ref>> + ! CHECK-DAG: %[[index1:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64 + ! CHECK-DAG: %[[index2:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64 + ! CHECK: fir.coordinate_of %[[coor]], %[[index1]], %[[index2]] : (!fir.ref>>, i64, i64) -> !fir.ref> + ! CHECK: fir.emboxchar %{{.*}}, %c10 : (!fir.ref>, index) -> !fir.boxchar<1> + call char_bar(some_c2%ch_array(5, 6)) +end subroutine + +! CHECK: @_QMdParray_elt_comp_ref +subroutine array_elt_comp_ref() + type(r) :: some_r_array(100) + ! CHECK: %[[alloca:.*]] = fir.alloca !fir.array<100x!fir.type<_QMdTr{x:f32}>> + ! CHECK: %[[index:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64 + ! CHECK: %[[elt:.*]] = fir.coordinate_of %[[alloca]], %[[index]] : (!fir.ref>>, i64) -> !fir.ref> + ! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}> + ! CHECK: fir.coordinate_of %[[elt]], %[[field]] : (!fir.ref>, !fir.field) -> !fir.ref + call real_bar(some_r_array(5)%x) +end subroutine + +! CHECK: @_QMdPchar_array_elt_comp_ref +subroutine char_array_elt_comp_ref() + type(c) :: some_c_array(100) + ! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref}>>>, i64) -> !fir.ref}>> + ! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref}>>, !fir.field) -> !fir.ref> + ! CHECK: fir.emboxchar %{{.*}}, %c10{{.*}} : (!fir.ref>, index) -> !fir.boxchar<1> + call char_bar(some_c_array(5)%ch) +end subroutine + +! ----------------------------------------------------------------------------- +! Test loading derived type components +! ----------------------------------------------------------------------------- + +! Most of the other tests only require lowering code to compute the address of +! components. This one requires loading a component which tests other code paths +! in lowering. + +! CHECK-LABEL: func @_QMdPscalar_numeric_load( +! CHECK-SAME: %[[arg0:.*]]: !fir.ref> +real function scalar_numeric_load(some_r) + type(r) :: some_r + ! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}> + ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], %[[field]] : (!fir.ref>, !fir.field) -> !fir.ref + ! CHECK: fir.load %[[coor]] + scalar_numeric_load = some_r%x +end function + +! ----------------------------------------------------------------------------- +! Test returned derived types (no length parameters) +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QMdPbar_return_derived() -> !fir.type<_QMdTr{x:f32}> +function bar_return_derived() + ! CHECK: %[[res:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}> + type(r) :: bar_return_derived + ! CHECK: %[[resLoad:.*]] = fir.load %[[res]] : !fir.ref> + ! CHECK: return %[[resLoad]] : !fir.type<_QMdTr{x:f32}> +end function + +! CHECK-LABEL: func @_QMdPcall_bar_return_derived( +subroutine call_bar_return_derived() + ! CHECK: %[[tmp:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}> + ! CHECK: %[[call:.*]] = fir.call @_QMdPbar_return_derived() : () -> !fir.type<_QMdTr{x:f32}> + ! CHECK: fir.save_result %[[call]] to %[[tmp]] : !fir.type<_QMdTr{x:f32}>, !fir.ref> + ! CHECK: fir.call @_QPr_bar(%[[tmp]]) : (!fir.ref>) -> () + call r_bar(bar_return_derived()) +end subroutine + +end module + +! ----------------------------------------------------------------------------- +! Test derived type with pointer/allocatable components +! ----------------------------------------------------------------------------- + +module d2 + type recursive_t + real :: x + type(recursive_t), pointer :: ptr + end type +contains +! CHECK-LABEL: func @_QMd2Ptest_recursive_type( +! CHECK-SAME: %{{.*}}: !fir.ref>>}>>{{.*}}) { +subroutine test_recursive_type(some_recursive) + type(recursive_t) :: some_recursive +end subroutine +end module + +! ----------------------------------------------------------------------------- +! Test global derived type symbol lowering +! ----------------------------------------------------------------------------- + +module data_mod + use d + type(r) :: some_r + type(c2) :: some_c2 +end module + +! Test globals + +! CHECK-DAG: fir.global @_QMdata_modEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}> +! CHECK-DAG: fir.global @_QMdata_modEsome_r : !fir.type<_QMdTr{x:f32}> +! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}> +! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_r : !fir.type<_QMdTr{x:f32}> diff --git a/flang/test/Lower/dummy-argument-optional-2.f90 b/flang/test/Lower/dummy-argument-optional-2.f90 index fb55f2ce2ed37..addf05d7bb7dc 100644 --- a/flang/test/Lower/dummy-argument-optional-2.f90 +++ b/flang/test/Lower/dummy-argument-optional-2.f90 @@ -2,426 +2,425 @@ ! explicit shapes (see F2018 15.5.2.12). ! RUN: bbc -emit-fir %s -o - | FileCheck %s module optional_tests - implicit none - interface - subroutine takes_opt_scalar(i) - integer, optional :: i - end subroutine - subroutine takes_opt_scalar_char(c) - character(*), optional :: c - end subroutine - subroutine takes_opt_explicit_shape(x) - real, optional :: x(100) - end subroutine - subroutine takes_opt_explicit_shape_intentout(x) - real, optional, intent(out) :: x(100) - end subroutine - subroutine takes_opt_explicit_shape_intentin(x) - real, optional, intent(in) :: x(100) - end subroutine - subroutine takes_opt_explicit_shape_char(c) - character(*), optional :: c(100) - end subroutine - function returns_pointer() - real, pointer :: returns_pointer(:) - end function - end interface - contains - - ! ----------------------------------------------------------------------------- - ! Test passing scalar pointers and allocatables to an optional - ! ----------------------------------------------------------------------------- - ! Here, nothing optional specific is expected, the address is passed, and its - ! allocation/association status match the dummy presence status. - - ! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_scalar( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>{{.*}}) { - subroutine pass_pointer_scalar(i) - integer, pointer :: i - call takes_opt_scalar(i) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> - ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ptr - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr) -> !fir.ref - ! CHECK: fir.call @_QPtakes_opt_scalar(%[[VAL_3]]) : (!fir.ref) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_scalar( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>{{.*}}) { - subroutine pass_allocatable_scalar(i) - integer, allocatable :: i - call takes_opt_scalar(i) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> - ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.heap - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.heap) -> !fir.ref - ! CHECK: fir.call @_QPtakes_opt_scalar(%[[VAL_3]]) : (!fir.ref) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_scalar_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { - subroutine pass_pointer_scalar_char(c) - character(:), pointer :: c - call takes_opt_scalar_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>) -> index - ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> - ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>) -> !fir.ref> - ! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_scalar_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_scalar_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { - subroutine pass_allocatable_scalar_char(c) - character(:), allocatable :: c - call takes_opt_scalar_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>) -> index - ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.heap>) -> !fir.ref> - ! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_scalar_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test passing non contiguous pointers to explicit shape optional - ! ----------------------------------------------------------------------------- - ! The pointer descriptor can be unconditionally read, but the copy-in/copy-out - ! must be conditional on the pointer association status in order to get the - ! correct present/absent aspect. - - ! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_array( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { - subroutine pass_pointer_array(i) - real, pointer :: i(:) - call takes_opt_explicit_shape(i) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>) -> i64 - ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 - ! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64 - ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_5]] -> (!fir.heap>) { - ! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_10]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array, %[[VAL_11]]#1 {uniq_name = ".copyinout"} - ! CHECK: %[[VAL_20:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_20]] to %[[VAL_12]] : !fir.array, !fir.array, !fir.heap> - ! CHECK: fir.result %[[VAL_12]] : !fir.heap> - ! CHECK: } else { - ! CHECK: %[[VAL_26:.*]] = fir.zero_bits !fir.heap> - ! CHECK: fir.result %[[VAL_26]] : !fir.heap> - ! CHECK: } - ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_29]]) : (!fir.ref>) -> () - ! CHECK: fir.if %[[VAL_5]] { - ! CHECK: %[[VAL_40:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_40]] to %[[VAL_6]] : !fir.array, !fir.array, !fir.box>> - ! CHECK: fir.freemem %[[VAL_9]] - ! CHECK: } - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_array_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>{{.*}}) { - subroutine pass_pointer_array_char(c) - character(:), pointer :: c(:) - call takes_opt_explicit_shape_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>>) -> !fir.ptr>> - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>>) -> i64 - ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 - ! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64 - ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> - ! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_5]] -> (!fir.heap>>) { - ! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_10]] : (!fir.box>>>, index) -> (index, index, index) - ! CHECK: %[[VAL_12:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box>>>) -> index - ! CHECK: %[[VAL_13:.*]] = fir.allocmem !fir.array>(%[[VAL_12]] : index), %[[VAL_11]]#1 {uniq_name = ".copyinout"} - ! CHECK: %[[VAL_21:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_21]] to %[[VAL_13]] typeparams %[[VAL_12]] : !fir.array>, !fir.array>, !fir.heap>>, index - ! CHECK: fir.result %[[VAL_13]] : !fir.heap>> - ! CHECK: } else { - ! CHECK: %[[VAL_46:.*]] = fir.zero_bits !fir.heap>> - ! CHECK: fir.result %[[VAL_46]] : !fir.heap>> - ! CHECK: } - ! CHECK: %[[VAL_47:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box>>>) -> index - ! CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>>) -> !fir.ref> - ! CHECK: %[[VAL_52:.*]] = fir.emboxchar %[[VAL_50]], %[[VAL_47]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_52]]) : (!fir.boxchar<1>) -> () - ! CHECK: fir.if %[[VAL_5]] { - ! CHECK: %[[VAL_62:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_62]] to %[[VAL_6]] : !fir.array>, !fir.array>, !fir.box>>> - ! CHECK: fir.freemem %[[VAL_9]] - ! CHECK: } - ! CHECK: return - ! CHECK: } - end subroutine - - ! This case is bit special because the pointer is not a symbol but a function - ! result. Test that the copy-in/copy-out is the same as with normal pointers. - - ! CHECK-LABEL: func @_QMoptional_testsPforward_pointer_array() { - subroutine forward_pointer_array() - call takes_opt_explicit_shape(returns_pointer()) - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box>> {bindc_name = ".result"} - ! CHECK: %[[VAL_1:.*]] = fir.call @_QPreturns_pointer() : () -> !fir.box>> - ! CHECK: fir.save_result %[[VAL_1]] to %[[VAL_0]] : !fir.box>>, !fir.ref>>> - ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box>>) -> !fir.ptr> - ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>) -> i64 - ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64 - ! CHECK: %[[VAL_6:.*]] = arith.cmpi ne, %[[VAL_4]], %[[VAL_5]] : i64 - ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.heap>) { - ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array - ! CHECK: fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.result %[[VAL_10]] : !fir.heap> - ! CHECK: } else { - ! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> - ! CHECK: fir.result %[[VAL_11]] : !fir.heap> - ! CHECK: } - ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_14]]) : (!fir.ref>) -> () - ! CHECK: fir.if %[[VAL_6]] { - ! CHECK: fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.freemem %[[VAL_7]] - ! CHECK: } - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test passing assumed shape optional to explicit shape optional - ! ----------------------------------------------------------------------------- - ! The fix.box can only be read if the assumed shape is present, - ! and the copy-in/copy-out must also be conditional on the assumed - ! shape presence. - - ! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { - subroutine pass_opt_assumed_shape(x) - real, optional :: x(:) - call takes_opt_explicit_shape(x) - ! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 - ! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> - ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { - ! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array, %[[VAL_9]]#1 {uniq_name = ".copyinout"} - ! CHECK: %[[VAL_17:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_17]] to %[[VAL_10]] : !fir.array, !fir.array, !fir.heap> - ! CHECK: fir.result %[[VAL_10]] : !fir.heap> - ! CHECK: } else { - ! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap> - ! CHECK: fir.result %[[VAL_23]] : !fir.heap> - ! CHECK: } - ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_27:.*]] : (!fir.heap>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_26]]) : (!fir.ref>) -> () - ! CHECK: fir.if %[[VAL_1]] { - ! CHECK: %[[VAL_36:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_36]] to %[[VAL_6]] : !fir.array, !fir.array, !fir.box> - ! CHECK: fir.freemem %[[VAL_27]] - ! CHECK: } - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "c", fir.optional}) { - subroutine pass_opt_assumed_shape_char(c) - character(*), optional :: c(:) - call takes_opt_explicit_shape_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 - ! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref>> - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) typeparams %[[VAL_5]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.box>> - ! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_6]] : !fir.box>> - ! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>>) { - ! CHECK: %[[VAL_19:.*]] = fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_19]] to %[[VAL_12]] typeparams %[[VAL_11]] : !fir.array>, !fir.array>, !fir.heap>>, index - ! CHECK: fir.result %[[VAL_12]] : !fir.heap>> - ! CHECK: } else { - ! CHECK: %[[VAL_44:.*]] = fir.zero_bits !fir.heap>> - ! CHECK: fir.result %[[VAL_44]] : !fir.heap>> - ! CHECK: } - ! CHECK: %[[VAL_45:.*]] = fir.box_elesize %[[VAL_7]] : (!fir.box>>) -> index - ! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_49:.*]] : (!fir.heap>>) -> !fir.ref> - ! CHECK: %[[VAL_50:.*]] = fir.emboxchar %[[VAL_48]], %[[VAL_45]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_50]]) : (!fir.boxchar<1>) -> () - ! CHECK: fir.if %[[VAL_1]] { - ! CHECK: %[[VAL_59:.*]] = fir.do_loop {{.*}} { - ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_59]] to %[[VAL_7]] : !fir.array>, !fir.array>, !fir.box>> - ! CHECK: fir.freemem %[[VAL_49]] - ! CHECK: } - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test passing contiguous optional assumed shape to explicit shape optional - ! ----------------------------------------------------------------------------- - ! The fix.box can only be read if the assumed shape is present. - ! There should be no copy-in/copy-out - - ! CHECK-LABEL: func @_QMoptional_testsPpass_opt_contiguous_assumed_shape( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.contiguous, fir.optional}) { - subroutine pass_opt_contiguous_assumed_shape(x) - real, optional, contiguous :: x(:) - call takes_opt_explicit_shape(x) - ! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 - ! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> - ! CHECK: %[[VAL_7:.*]] = fir.box_addr %[[VAL_6]] : (!fir.box>) -> !fir.ref> - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_8]]) : (!fir.ref>) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_opt_contiguous_assumed_shape_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "c", fir.contiguous, fir.optional}) { - subroutine pass_opt_contiguous_assumed_shape_char(c) - character(*), optional, contiguous :: c(:) - call takes_opt_explicit_shape_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 - ! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref>> - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) typeparams %[[VAL_5]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.box>> - ! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_6]] : !fir.box>> - ! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>>) -> !fir.ref>> - ! CHECK: %[[VAL_9:.*]] = fir.box_elesize %[[VAL_7]] : (!fir.box>>) -> index - ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>>) -> !fir.ref> - ! CHECK: %[[VAL_11:.*]] = fir.emboxchar %[[VAL_10]], %[[VAL_9]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_11]]) : (!fir.boxchar<1>) -> () - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test passing allocatables and contiguous pointers to explicit shape optional - ! ----------------------------------------------------------------------------- - ! The fix.box can be read and its address directly passed. There should be no - ! copy-in/copy-out. - - ! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_array( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { - subroutine pass_allocatable_array(i) - real, allocatable :: i(:) - call takes_opt_explicit_shape(i) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.heap>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_3]]) : (!fir.ref>) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_array_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>{{.*}}) { - subroutine pass_allocatable_array_char(c) - character(:), allocatable :: c(:) - call takes_opt_explicit_shape_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>>) -> index - ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>>) -> !fir.heap>> - ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.heap>>) -> !fir.ref> - ! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_contiguous_pointer_array( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>> {fir.bindc_name = "i", fir.contiguous}) { - subroutine pass_contiguous_pointer_array(i) - real, pointer, contiguous :: i(:) - call takes_opt_explicit_shape(i) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_3]]) : (!fir.ref>) -> () - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_contiguous_pointer_array_char( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "c", fir.contiguous}) { - subroutine pass_contiguous_pointer_array_char(c) - character(:), pointer, contiguous :: c(:) - call takes_opt_explicit_shape_char(c) - ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> - ! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>>) -> index - ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>>) -> !fir.ptr>> - ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>>) -> !fir.ref> - ! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test passing assumed shape optional to explicit shape optional with intents - ! ----------------------------------------------------------------------------- - ! The fix.box can only be read if the assumed shape is present, - ! and the copy-in/copy-out must also be conditional on the assumed - ! shape presence. For intent(in), there should be no copy-out while for - ! intent(out), there should be no copy-in. - - ! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape_to_intentin( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { - subroutine pass_opt_assumed_shape_to_intentin(x) - real, optional :: x(:) - call takes_opt_explicit_shape_intentin(x) - ! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 - ! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> - ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { - ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array - ! CHECK: fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.result %[[VAL_10]] : !fir.heap> - ! CHECK: } else { - ! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap> - ! CHECK: fir.result %[[VAL_23]] : !fir.heap> - ! CHECK: } - ! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentin(%[[VAL_24]]) : (!fir.ref>) -> () - ! CHECK: fir.if %[[VAL_1]] { - ! CHECK-NOT: fir.do_loop - ! CHECK: fir.freemem %[[VAL_7]] - ! CHECK: } - end subroutine - - ! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape_to_intentout( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { - subroutine pass_opt_assumed_shape_to_intentout(x) - real, optional :: x(:) - call takes_opt_explicit_shape_intentout(x) - ! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 - ! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> - ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> - ! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { - ! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array - ! CHECK-NOT: fir.do_loop - ! CHECK: fir.result %[[VAL_10]] : !fir.heap> - ! CHECK: } else { - ! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> - ! CHECK: fir.result %[[VAL_11]] : !fir.heap> - ! CHECK: } - ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> - ! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentout(%[[VAL_14]]) : (!fir.ref>) -> () - ! CHECK: fir.if %[[VAL_1]] { - ! CHECK: fir.do_loop {{.*}} { - ! CHECK: } - ! CHECK: fir.freemem %[[VAL_7]] - ! CHECK: } - end subroutine - end module - \ No newline at end of file +implicit none +interface +subroutine takes_opt_scalar(i) + integer, optional :: i +end subroutine +subroutine takes_opt_scalar_char(c) + character(*), optional :: c +end subroutine +subroutine takes_opt_explicit_shape(x) + real, optional :: x(100) +end subroutine +subroutine takes_opt_explicit_shape_intentout(x) + real, optional, intent(out) :: x(100) +end subroutine +subroutine takes_opt_explicit_shape_intentin(x) + real, optional, intent(in) :: x(100) +end subroutine +subroutine takes_opt_explicit_shape_char(c) + character(*), optional :: c(100) +end subroutine +function returns_pointer() + real, pointer :: returns_pointer(:) +end function +end interface +contains + +! ----------------------------------------------------------------------------- +! Test passing scalar pointers and allocatables to an optional +! ----------------------------------------------------------------------------- +! Here, nothing optional specific is expected, the address is passed, and its +! allocation/association status match the dummy presence status. + +! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_scalar( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>{{.*}}) { +subroutine pass_pointer_scalar(i) + integer, pointer :: i + call takes_opt_scalar(i) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ptr +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr) -> !fir.ref +! CHECK: fir.call @_QPtakes_opt_scalar(%[[VAL_3]]) : (!fir.ref) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_scalar( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>{{.*}}) { +subroutine pass_allocatable_scalar(i) + integer, allocatable :: i + call takes_opt_scalar(i) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.heap +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.heap) -> !fir.ref +! CHECK: fir.call @_QPtakes_opt_scalar(%[[VAL_3]]) : (!fir.ref) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_scalar_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { +subroutine pass_pointer_scalar_char(c) + character(:), pointer :: c + call takes_opt_scalar_char(c) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>) -> index +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>) -> !fir.ref> +! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_scalar_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_scalar_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { +subroutine pass_allocatable_scalar_char(c) + character(:), allocatable :: c + call takes_opt_scalar_char(c) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>) -> index +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.heap>) -> !fir.ref> +! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_scalar_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () +end subroutine + +! ----------------------------------------------------------------------------- +! Test passing non contiguous pointers to explicit shape optional +! ----------------------------------------------------------------------------- +! The pointer descriptor can be unconditionally read, but the copy-in/copy-out +! must be conditional on the pointer association status in order to get the +! correct present/absent aspect. + +! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_array( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { +subroutine pass_pointer_array(i) + real, pointer :: i(:) + call takes_opt_explicit_shape(i) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>) -> i64 +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 +! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64 +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_5]] -> (!fir.heap>) { +! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_10]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array, %[[VAL_11]]#1 {uniq_name = ".copyinout"} +! CHECK: %[[VAL_20:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_20]] to %[[VAL_12]] : !fir.array, !fir.array, !fir.heap> +! CHECK: fir.result %[[VAL_12]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_26:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.result %[[VAL_26]] : !fir.heap> +! CHECK: } +! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_29]]) : (!fir.ref>) -> () +! CHECK: fir.if %[[VAL_5]] { +! CHECK: %[[VAL_40:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_40]] to %[[VAL_6]] : !fir.array, !fir.array, !fir.box>> +! CHECK: fir.freemem %[[VAL_9]] +! CHECK: } +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_pointer_array_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>{{.*}}) { +subroutine pass_pointer_array_char(c) + character(:), pointer :: c(:) + call takes_opt_explicit_shape_char(c) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>>) -> !fir.ptr>> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>>) -> i64 +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 +! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64 +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> +! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_5]] -> (!fir.heap>>) { +! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_10]] : (!fir.box>>>, index) -> (index, index, index) +! CHECK: %[[VAL_12:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box>>>) -> index +! CHECK: %[[VAL_13:.*]] = fir.allocmem !fir.array>(%[[VAL_12]] : index), %[[VAL_11]]#1 {uniq_name = ".copyinout"} +! CHECK: %[[VAL_21:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_21]] to %[[VAL_13]] typeparams %[[VAL_12]] : !fir.array>, !fir.array>, !fir.heap>>, index +! CHECK: fir.result %[[VAL_13]] : !fir.heap>> +! CHECK: } else { +! CHECK: %[[VAL_46:.*]] = fir.zero_bits !fir.heap>> +! CHECK: fir.result %[[VAL_46]] : !fir.heap>> +! CHECK: } +! CHECK: %[[VAL_47:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box>>>) -> index +! CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_9]] : (!fir.heap>>) -> !fir.ref> +! CHECK: %[[VAL_52:.*]] = fir.emboxchar %[[VAL_50]], %[[VAL_47]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_52]]) : (!fir.boxchar<1>) -> () +! CHECK: fir.if %[[VAL_5]] { +! CHECK: %[[VAL_62:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_62]] to %[[VAL_6]] : !fir.array>, !fir.array>, !fir.box>>> +! CHECK: fir.freemem %[[VAL_9]] +! CHECK: } +! CHECK: return +! CHECK: } +end subroutine + +! This case is bit special because the pointer is not a symbol but a function +! result. Test that the copy-in/copy-out is the same as with normal pointers. + +! CHECK-LABEL: func @_QMoptional_testsPforward_pointer_array() { +subroutine forward_pointer_array() + call takes_opt_explicit_shape(returns_pointer()) +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box>> {bindc_name = ".result"} +! CHECK: %[[VAL_1:.*]] = fir.call @_QPreturns_pointer() : () -> !fir.box>> +! CHECK: fir.save_result %[[VAL_1]] to %[[VAL_0]] : !fir.box>>, !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>) -> i64 +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64 +! CHECK: %[[VAL_6:.*]] = arith.cmpi ne, %[[VAL_4]], %[[VAL_5]] : i64 +! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.heap>) { +! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array +! CHECK: fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.result %[[VAL_10]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.result %[[VAL_11]] : !fir.heap> +! CHECK: } +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_14]]) : (!fir.ref>) -> () +! CHECK: fir.if %[[VAL_6]] { +! CHECK: fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.freemem %[[VAL_7]] +! CHECK: } +end subroutine + +! ----------------------------------------------------------------------------- +! Test passing assumed shape optional to explicit shape optional +! ----------------------------------------------------------------------------- +! The fix.box can only be read if the assumed shape is present, +! and the copy-in/copy-out must also be conditional on the assumed +! shape presence. + +! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { +subroutine pass_opt_assumed_shape(x) + real, optional :: x(:) + call takes_opt_explicit_shape(x) +! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> +! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_6]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array, %[[VAL_9]]#1 {uniq_name = ".copyinout"} +! CHECK: %[[VAL_17:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_17]] to %[[VAL_10]] : !fir.array, !fir.array, !fir.heap> +! CHECK: fir.result %[[VAL_10]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.result %[[VAL_23]] : !fir.heap> +! CHECK: } +! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_27:.*]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_26]]) : (!fir.ref>) -> () +! CHECK: fir.if %[[VAL_1]] { +! CHECK: %[[VAL_36:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_36]] to %[[VAL_6]] : !fir.array, !fir.array, !fir.box> +! CHECK: fir.freemem %[[VAL_27]] +! CHECK: } +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "c", fir.optional}) { +subroutine pass_opt_assumed_shape_char(c) + character(*), optional :: c(:) + call takes_opt_explicit_shape_char(c) +! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref>> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) typeparams %[[VAL_5]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.box>> +! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_6]] : !fir.box>> +! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>>) { +! CHECK: %[[VAL_19:.*]] = fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_19]] to %[[VAL_12]] typeparams %[[VAL_11]] : !fir.array>, !fir.array>, !fir.heap>>, index +! CHECK: fir.result %[[VAL_12]] : !fir.heap>> +! CHECK: } else { +! CHECK: %[[VAL_44:.*]] = fir.zero_bits !fir.heap>> +! CHECK: fir.result %[[VAL_44]] : !fir.heap>> +! CHECK: } +! CHECK: %[[VAL_45:.*]] = fir.box_elesize %[[VAL_7]] : (!fir.box>>) -> index +! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_49:.*]] : (!fir.heap>>) -> !fir.ref> +! CHECK: %[[VAL_50:.*]] = fir.emboxchar %[[VAL_48]], %[[VAL_45]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_50]]) : (!fir.boxchar<1>) -> () +! CHECK: fir.if %[[VAL_1]] { +! CHECK: %[[VAL_59:.*]] = fir.do_loop {{.*}} { +! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_59]] to %[[VAL_7]] : !fir.array>, !fir.array>, !fir.box>> +! CHECK: fir.freemem %[[VAL_49]] +! CHECK: } +end subroutine + +! ----------------------------------------------------------------------------- +! Test passing contiguous optional assumed shape to explicit shape optional +! ----------------------------------------------------------------------------- +! The fix.box can only be read if the assumed shape is present. +! There should be no copy-in/copy-out + +! CHECK-LABEL: func @_QMoptional_testsPpass_opt_contiguous_assumed_shape( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.contiguous, fir.optional}) { +subroutine pass_opt_contiguous_assumed_shape(x) + real, optional, contiguous :: x(:) + call takes_opt_explicit_shape(x) +! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> +! CHECK: %[[VAL_7:.*]] = fir.box_addr %[[VAL_6]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_8]]) : (!fir.ref>) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_opt_contiguous_assumed_shape_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "c", fir.contiguous, fir.optional}) { +subroutine pass_opt_contiguous_assumed_shape_char(c) + character(*), optional, contiguous :: c(:) + call takes_opt_explicit_shape_char(c) +! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref>> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) typeparams %[[VAL_5]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.box>> +! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_6]] : !fir.box>> +! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>>) -> !fir.ref>> +! CHECK: %[[VAL_9:.*]] = fir.box_elesize %[[VAL_7]] : (!fir.box>>) -> index +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[VAL_11:.*]] = fir.emboxchar %[[VAL_10]], %[[VAL_9]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_11]]) : (!fir.boxchar<1>) -> () +end subroutine + +! ----------------------------------------------------------------------------- +! Test passing allocatables and contiguous pointers to explicit shape optional +! ----------------------------------------------------------------------------- +! The fix.box can be read and its address directly passed. There should be no +! copy-in/copy-out. + +! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_array( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>{{.*}}) { +subroutine pass_allocatable_array(i) + real, allocatable :: i(:) + call takes_opt_explicit_shape(i) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_3]]) : (!fir.ref>) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_allocatable_array_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>{{.*}}) { +subroutine pass_allocatable_array_char(c) + character(:), allocatable :: c(:) + call takes_opt_explicit_shape_char(c) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> +! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>>) -> index +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>>) -> !fir.heap>> +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.heap>>) -> !fir.ref> +! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_contiguous_pointer_array( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>> {fir.bindc_name = "i", fir.contiguous}) { +subroutine pass_contiguous_pointer_array(i) + real, pointer, contiguous :: i(:) + call takes_opt_explicit_shape(i) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_3]]) : (!fir.ref>) -> () +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_contiguous_pointer_array_char( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "c", fir.contiguous}) { +subroutine pass_contiguous_pointer_array_char(c) + character(:), pointer, contiguous :: c(:) + call takes_opt_explicit_shape_char(c) +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> +! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>>) -> index +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>>) -> !fir.ptr>> +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr>>) -> !fir.ref> +! CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %[[VAL_2]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_5]]) : (!fir.boxchar<1>) -> () +end subroutine + +! ----------------------------------------------------------------------------- +! Test passing assumed shape optional to explicit shape optional with intents +! ----------------------------------------------------------------------------- +! The fix.box can only be read if the assumed shape is present, +! and the copy-in/copy-out must also be conditional on the assumed +! shape presence. For intent(in), there should be no copy-out while for +! intent(out), there should be no copy-in. + +! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape_to_intentin( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { +subroutine pass_opt_assumed_shape_to_intentin(x) + real, optional :: x(:) + call takes_opt_explicit_shape_intentin(x) +! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> +! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { +! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array +! CHECK: fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.result %[[VAL_10]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.result %[[VAL_23]] : !fir.heap> +! CHECK: } +! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentin(%[[VAL_24]]) : (!fir.ref>) -> () +! CHECK: fir.if %[[VAL_1]] { +! CHECK-NOT: fir.do_loop +! CHECK: fir.freemem %[[VAL_7]] +! CHECK: } +end subroutine + +! CHECK-LABEL: func @_QMoptional_testsPpass_opt_assumed_shape_to_intentout( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { +subroutine pass_opt_assumed_shape_to_intentout(x) + real, optional :: x(:) + call takes_opt_explicit_shape_intentout(x) +! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_2]](%[[VAL_4]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_1]], %[[VAL_0]], %[[VAL_5]] : !fir.box> +! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_1]] -> (!fir.heap>) { +! CHECK: %[[VAL_10:.*]] = fir.allocmem !fir.array +! CHECK-NOT: fir.do_loop +! CHECK: fir.result %[[VAL_10]] : !fir.heap> +! CHECK: } else { +! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.result %[[VAL_11]] : !fir.heap> +! CHECK: } +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (!fir.heap>) -> !fir.ref> +! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentout(%[[VAL_14]]) : (!fir.ref>) -> () +! CHECK: fir.if %[[VAL_1]] { +! CHECK: fir.do_loop {{.*}} { +! CHECK: } +! CHECK: fir.freemem %[[VAL_7]] +! CHECK: } +end subroutine +end module diff --git a/flang/test/Lower/dummy-procedure-character.f90 b/flang/test/Lower/dummy-procedure-character.f90 index fbd9df2fbddc9..8eabf6df418bc 100644 --- a/flang/test/Lower/dummy-procedure-character.f90 +++ b/flang/test/Lower/dummy-procedure-character.f90 @@ -8,247 +8,247 @@ ! CHECK-LABEL: func @_QPcst_len subroutine cst_len() - interface - character(7) function bar1() - end function - end interface - call foo1(bar1) - ! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar1) : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: %[[VAL_1:.*]] = arith.constant 7 : i64 - ! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_1]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo1(%[[VAL_5]]) : (tuple ()>, i64>) -> () - end subroutine - - ! CHECK-LABEL: func @_QPcst_len_array - subroutine cst_len_array() - interface - function bar1_array() - character(7) :: bar1_array(10) - end function - end interface - ! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar1_array) : () -> !fir.array<10x!fir.char<1,7>> - ! CHECK: %[[VAL_1:.*]] = arith.constant 7 : i64 - ! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : (() -> !fir.array<10x!fir.char<1,7>>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_1]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo1b(%[[VAL_5]]) : (tuple ()>, i64>) -> () - call foo1b(bar1_array) - end subroutine - - ! CHECK-LABEL: func @_QPcst_len_2 - subroutine cst_len_2() - character(7) :: bar2 - external :: bar2 - ! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar2) : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: %[[VAL_1:.*]] = arith.constant 7 : i64 - ! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_1]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo2(%[[VAL_5]]) : (tuple ()>, i64>) -> () - call foo2(bar2) - end subroutine - - ! CHECK-LABEL: func @_QPdyn_len( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref{{.*}}) { - subroutine dyn_len(n) - integer :: n - character(n) :: bar3 - external :: bar3 - ! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QPbar3) : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i32) -> i64 - ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 - ! CHECK: %[[VAL_5:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[VAL_4]] : i64 - ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_5]], %[[VAL_3]], %[[VAL_4]] : i64 - ! CHECK: %[[VAL_7:.*]] = fir.emboxproc %[[VAL_1]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_8:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_9:.*]] = fir.insert_value %[[VAL_8]], %[[VAL_7]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_6]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo3(%[[VAL_10]]) : (tuple ()>, i64>) -> () - call foo3(bar3) - end subroutine - - ! CHECK-LABEL: func @_QPcannot_compute_len_yet - subroutine cannot_compute_len_yet() - interface - function bar4(n) - integer :: n - character(n) :: bar4 - end function - end interface - ! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar4) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> - ! CHECK: %[[VAL_1:.*]] = arith.constant -1 : index - ! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 - ! CHECK: %[[VAL_4:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_3]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo4(%[[VAL_6]]) : (tuple ()>, i64>) -> () - call foo4(bar4) - end subroutine - - ! CHECK-LABEL: func @_QPcannot_compute_len_yet_2 - subroutine cannot_compute_len_yet_2() - character(*) :: bar5 - external :: bar5 - ! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar5) : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: %[[VAL_1:.*]] = arith.constant -1 : index - ! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 - ! CHECK: %[[VAL_4:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_3]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo5(%[[VAL_6]]) : (tuple ()>, i64>) -> () - call foo5(bar5) - end subroutine - - ! CHECK-LABEL: func @_QPforward_incoming_length - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { - subroutine forward_incoming_length(bar6) - character(*) :: bar6 - external :: bar6 - ! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_2:.*]] = fir.extract_value %[[VAL_0]], [1 : index] : (tuple ()>, i64>) -> i64 - ! CHECK: %[[WAL_1:.*]] = fir.emboxproc %[[WAL_2]] : (() -> ()) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[WAL_1]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo6(%[[VAL_5]]) : (tuple ()>, i64>) -> () - call foo6(bar6) - end subroutine - - ! CHECK-LABEL: func @_QPoverride_incoming_length - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { - subroutine override_incoming_length(bar7) - character(7) :: bar7 - external :: bar7 - ! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_2:.*]] = arith.constant 7 : i64 - ! CHECK: %[[WAL_1:.*]] = fir.emboxproc %[[WAL_2]] : (() -> ()) -> !fir.boxproc<() -> ()> - ! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> - ! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[WAL_1]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> - ! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> - ! CHECK: fir.call @_QPfoo7(%[[VAL_5]]) : (tuple ()>, i64>) -> () - call foo7(bar7) - end subroutine - - ! ----------------------------------------------------------------------------- - ! Test calling character dummy function - ! ----------------------------------------------------------------------------- - - ! CHECK-LABEL: func @_QPcall_assumed_length - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { - subroutine call_assumed_length(bar8) - character(*) :: bar8 - external :: bar8 - ! CHECK: %[[VAL_3:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_2:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_4:.*]] = fir.extract_value %[[VAL_0]], [1 : index] : (tuple ()>, i64>) -> i64 - ! CHECK: %[[VAL_6:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_4]] : i64) {bindc_name = ".result"} - ! CHECK: %[[VAL_7:.*]] = fir.convert %[[WAL_2]] : (() -> ()) -> ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_4]] : (i64) -> index - ! CHECK: fir.call %[[VAL_7]](%[[VAL_6]], %[[VAL_8]], %{{.*}}) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> - call test(bar8(42)) - end subroutine - - ! CHECK-LABEL: func @_QPcall_explicit_length - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { - subroutine call_explicit_length(bar9) - character(7) :: bar9 - external :: bar9 - ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1,7> {bindc_name = ".result"} - ! CHECK: %[[VAL_4:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_5:.*]] = arith.constant 7 : i64 - ! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i64) -> index - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) - ! CHECK: fir.call %[[VAL_8]](%[[VAL_1]], %[[VAL_6]], %{{.*}}) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> - call test(bar9(42)) - end subroutine - - ! CHECK-LABEL: func @_QPcall_explicit_length_with_iface - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { - subroutine call_explicit_length_with_iface(bar10) - interface - function bar10(n) - integer(8) :: n - character(n) :: bar10 - end function - end interface - ! CHECK: %[[VAL_1:.*]] = fir.alloca i64 - ! CHECK: %[[VAL_2:.*]] = arith.constant 42 : i64 - ! CHECK: fir.store %[[VAL_2]] to %[[VAL_1]] : !fir.ref - ! CHECK: %[[VAL_3:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref - ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> index - ! CHECK: %[[VAL_6:.*]] = fir.call @llvm.stacksave() : () -> !fir.ref - ! CHECK: %[[VAL_7:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_5]] : index) {bindc_name = ".result"} - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) - ! CHECK: fir.call %[[VAL_8]](%[[VAL_7]], %[[VAL_5]], %[[VAL_1]]) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> - call test(bar10(42_8)) - end subroutine - - - ! CHECK-LABEL: func @_QPhost( - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> - subroutine host(f) - character*(*) :: f - external :: f - ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1:.*]], %{{.*}} : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> - ! CHECK: fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref ()>, i64>> - ! CHECK: fir.call @_QFhostPintern(%[[VAL_1]]) - call intern() - contains - ! CHECK-LABEL: func @_QFhostPintern( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref ()>, i64>>> {fir.host_assoc}) - subroutine intern() - ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> - ! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref ()>, i64>> - ! CHECK: %[[VAL_4:.*]] = fir.extract_value %[[VAL_3]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_5:.*]] = fir.extract_value %[[VAL_3]], [1 : index] : (tuple ()>, i64>) -> i64 - ! CHECK: %[[VAL_7:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_5]] : i64) {bindc_name = ".result"} - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index) -> !fir.boxchar<1>) - ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_5]] : (i64) -> index - ! CHECK: fir.call %[[VAL_8]](%[[VAL_7]], %[[VAL_9]]) : (!fir.ref>, index) -> !fir.boxchar<1> - call test(f()) - end subroutine + interface + character(7) function bar1() + end function + end interface + call foo1(bar1) +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar1) : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: %[[VAL_1:.*]] = arith.constant 7 : i64 +! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_1]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo1(%[[VAL_5]]) : (tuple ()>, i64>) -> () +end subroutine + +! CHECK-LABEL: func @_QPcst_len_array +subroutine cst_len_array() + interface + function bar1_array() + character(7) :: bar1_array(10) + end function + end interface +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar1_array) : () -> !fir.array<10x!fir.char<1,7>> +! CHECK: %[[VAL_1:.*]] = arith.constant 7 : i64 +! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : (() -> !fir.array<10x!fir.char<1,7>>) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_1]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo1b(%[[VAL_5]]) : (tuple ()>, i64>) -> () + call foo1b(bar1_array) +end subroutine + +! CHECK-LABEL: func @_QPcst_len_2 +subroutine cst_len_2() + character(7) :: bar2 + external :: bar2 +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar2) : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: %[[VAL_1:.*]] = arith.constant 7 : i64 +! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_1]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo2(%[[VAL_5]]) : (tuple ()>, i64>) -> () + call foo2(bar2) +end subroutine + +! CHECK-LABEL: func @_QPdyn_len( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref{{.*}}) { +subroutine dyn_len(n) + integer :: n + character(n) :: bar3 + external :: bar3 +! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QPbar3) : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i32) -> i64 +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64 +! CHECK: %[[VAL_5:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[VAL_4]] : i64 +! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_5]], %[[VAL_3]], %[[VAL_4]] : i64 +! CHECK: %[[VAL_7:.*]] = fir.emboxproc %[[VAL_1]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_8:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_9:.*]] = fir.insert_value %[[VAL_8]], %[[VAL_7]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_6]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo3(%[[VAL_10]]) : (tuple ()>, i64>) -> () + call foo3(bar3) +end subroutine + +! CHECK-LABEL: func @_QPcannot_compute_len_yet +subroutine cannot_compute_len_yet() + interface + function bar4(n) + integer :: n + character(n) :: bar4 + end function + end interface +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar4) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> +! CHECK: %[[VAL_1:.*]] = arith.constant -1 : index +! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 +! CHECK: %[[VAL_4:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_3]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo4(%[[VAL_6]]) : (tuple ()>, i64>) -> () + call foo4(bar4) +end subroutine + +! CHECK-LABEL: func @_QPcannot_compute_len_yet_2 +subroutine cannot_compute_len_yet_2() + character(*) :: bar5 + external :: bar5 +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QPbar5) : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: %[[VAL_1:.*]] = arith.constant -1 : index +! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 +! CHECK: %[[VAL_4:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_3]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo5(%[[VAL_6]]) : (tuple ()>, i64>) -> () + call foo5(bar5) +end subroutine + +! CHECK-LABEL: func @_QPforward_incoming_length +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { +subroutine forward_incoming_length(bar6) + character(*) :: bar6 + external :: bar6 +! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> +! CHECK: %[[WAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.boxproc<() -> ()>) -> (() -> ()) +! CHECK: %[[VAL_2:.*]] = fir.extract_value %[[VAL_0]], [1 : index] : (tuple ()>, i64>) -> i64 +! CHECK: %[[WAL_1:.*]] = fir.emboxproc %[[WAL_2]] : (() -> ()) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[WAL_1]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo6(%[[VAL_5]]) : (tuple ()>, i64>) -> () + call foo6(bar6) +end subroutine + +! CHECK-LABEL: func @_QPoverride_incoming_length +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { +subroutine override_incoming_length(bar7) + character(7) :: bar7 + external :: bar7 +! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> +! CHECK: %[[WAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.boxproc<() -> ()>) -> (() -> ()) +! CHECK: %[[VAL_2:.*]] = arith.constant 7 : i64 +! CHECK: %[[WAL_1:.*]] = fir.emboxproc %[[WAL_2]] : (() -> ()) -> !fir.boxproc<() -> ()> +! CHECK: %[[VAL_3:.*]] = fir.undefined tuple ()>, i64> +! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_3]], %[[WAL_1]], [0 : index] : (tuple ()>, i64>, !fir.boxproc<() -> ()>) -> tuple ()>, i64> +! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_2]], [1 : index] : (tuple ()>, i64>, i64) -> tuple ()>, i64> +! CHECK: fir.call @_QPfoo7(%[[VAL_5]]) : (tuple ()>, i64>) -> () + call foo7(bar7) +end subroutine + +! ----------------------------------------------------------------------------- +! Test calling character dummy function +! ----------------------------------------------------------------------------- + +! CHECK-LABEL: func @_QPcall_assumed_length +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { +subroutine call_assumed_length(bar8) + character(*) :: bar8 + external :: bar8 +! CHECK: %[[VAL_3:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> +! CHECK: %[[WAL_2:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ()) +! CHECK: %[[VAL_4:.*]] = fir.extract_value %[[VAL_0]], [1 : index] : (tuple ()>, i64>) -> i64 +! CHECK: %[[VAL_6:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_4]] : i64) {bindc_name = ".result"} +! CHECK: %[[VAL_7:.*]] = fir.convert %[[WAL_2]] : (() -> ()) -> ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_4]] : (i64) -> index +! CHECK: fir.call %[[VAL_7]](%[[VAL_6]], %[[VAL_8]], %{{.*}}) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> + call test(bar8(42)) +end subroutine + +! CHECK-LABEL: func @_QPcall_explicit_length +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { +subroutine call_explicit_length(bar9) + character(7) :: bar9 + external :: bar9 +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1,7> {bindc_name = ".result"} +! CHECK: %[[VAL_4:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> +! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ()) +! CHECK: %[[VAL_5:.*]] = arith.constant 7 : i64 +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i64) -> index +! CHECK: %[[VAL_8:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) +! CHECK: fir.call %[[VAL_8]](%[[VAL_1]], %[[VAL_6]], %{{.*}}) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> + call test(bar9(42)) +end subroutine + +! CHECK-LABEL: func @_QPcall_explicit_length_with_iface +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) { +subroutine call_explicit_length_with_iface(bar10) + interface + function bar10(n) + integer(8) :: n + character(n) :: bar10 + end function + end interface +! CHECK: %[[VAL_1:.*]] = fir.alloca i64 +! CHECK: %[[VAL_2:.*]] = arith.constant 42 : i64 +! CHECK: fir.store %[[VAL_2]] to %[[VAL_1]] : !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> +! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ()) +! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> index +! CHECK: %[[VAL_6:.*]] = fir.call @llvm.stacksave() : () -> !fir.ref +! CHECK: %[[VAL_7:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_5]] : index) {bindc_name = ".result"} +! CHECK: %[[VAL_8:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index, !fir.ref) -> !fir.boxchar<1>) +! CHECK: fir.call %[[VAL_8]](%[[VAL_7]], %[[VAL_5]], %[[VAL_1]]) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> + call test(bar10(42_8)) +end subroutine + + +! CHECK-LABEL: func @_QPhost( +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> +subroutine host(f) + character*(*) :: f + external :: f + ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1:.*]], %{{.*}} : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> + ! CHECK: fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref ()>, i64>> + ! CHECK: fir.call @_QFhostPintern(%[[VAL_1]]) + call intern() +contains +! CHECK-LABEL: func @_QFhostPintern( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref ()>, i64>>> {fir.host_assoc}) + subroutine intern() +! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref ()>, i64>> +! CHECK: %[[VAL_4:.*]] = fir.extract_value %[[VAL_3]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> +! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ()) +! CHECK: %[[VAL_5:.*]] = fir.extract_value %[[VAL_3]], [1 : index] : (tuple ()>, i64>) -> i64 +! CHECK: %[[VAL_7:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_5]] : i64) {bindc_name = ".result"} +! CHECK: %[[VAL_8:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index) -> !fir.boxchar<1>) +! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_5]] : (i64) -> index +! CHECK: fir.call %[[VAL_8]](%[[VAL_7]], %[[VAL_9]]) : (!fir.ref>, index) -> !fir.boxchar<1> + call test(f()) end subroutine - - ! CHECK-LABEL: func @_QPhost2( - ! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) - subroutine host2(f) - ! Test that dummy length is overridden by local length even when used - ! in the internal procedure. - character*(42) :: f - external :: f - ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1:.*]], %{{.*}} : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> - ! CHECK: fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref ()>, i64>> - ! CHECK: fir.call @_QFhost2Pintern(%[[VAL_1]]) - call intern() - contains - ! CHECK-LABEL: func @_QFhost2Pintern( - ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref ()>, i64>>> {fir.host_assoc}) - subroutine intern() - ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1,42> {bindc_name = ".result"} - ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 - ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> - ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref ()>, i64>> - ! CHECK: %[[VAL_5:.*]] = fir.extract_value %[[VAL_4]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> - ! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_5]] : (!fir.boxproc<() -> ()>) -> (() -> ()) - ! CHECK: %[[VAL_6:.*]] = arith.constant 42 : i64 - ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> index - ! CHECK: %[[VAL_9:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index) -> !fir.boxchar<1>) - ! CHECK: fir.call %[[VAL_9]](%[[VAL_1]], %[[VAL_7]]) : (!fir.ref>, index) -> !fir.boxchar<1> - call test(f()) - end subroutine +end subroutine + +! CHECK-LABEL: func @_QPhost2( +! CHECK-SAME: %[[VAL_0:.*]]: tuple ()>, i64> {fir.char_proc}) +subroutine host2(f) + ! Test that dummy length is overridden by local length even when used + ! in the internal procedure. + character*(42) :: f + external :: f + ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1:.*]], %{{.*}} : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> + ! CHECK: fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref ()>, i64>> + ! CHECK: fir.call @_QFhost2Pintern(%[[VAL_1]]) + call intern() +contains +! CHECK-LABEL: func @_QFhost2Pintern( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref ()>, i64>>> {fir.host_assoc}) + subroutine intern() + ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1,42> {bindc_name = ".result"} + ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 + ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref ()>, i64>>>, i32) -> !fir.ref ()>, i64>> + ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref ()>, i64>> + ! CHECK: %[[VAL_5:.*]] = fir.extract_value %[[VAL_4]], [0 : index] : (tuple ()>, i64>) -> !fir.boxproc<() -> ()> + ! CHECK: %[[WAL_1:.*]] = fir.box_addr %[[VAL_5]] : (!fir.boxproc<() -> ()>) -> (() -> ()) + ! CHECK: %[[VAL_6:.*]] = arith.constant 42 : i64 + ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> index + ! CHECK: %[[VAL_9:.*]] = fir.convert %[[WAL_1]] : (() -> ()) -> ((!fir.ref>, index) -> !fir.boxchar<1>) + ! CHECK: fir.call %[[VAL_9]](%[[VAL_1]], %[[VAL_7]]) : (!fir.ref>, index) -> !fir.boxchar<1> + call test(f()) end subroutine +end subroutine diff --git a/flang/test/Lower/entry-statement.f90 b/flang/test/Lower/entry-statement.f90 index 4c83a3b4c63cb..c4d202200e9d5 100644 --- a/flang/test/Lower/entry-statement.f90 +++ b/flang/test/Lower/entry-statement.f90 @@ -4,155 +4,155 @@ ! CHECK-LABEL: func @_QPcompare1( ! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) { subroutine compare1(x, c1, c2) - character(*) c1, c2, d1, d2 - logical x, y - x = c1 < c2 - return - - ! CHECK-LABEL: func @_QPcompare2( - ! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) { - entry compare2(y, d2, d1) - y = d1 < d2 - end - - program entries - character(10) hh, qq, m - character(len=4) s1, s2 - integer mm - logical r - s1 = 'a111' - s2 = 'a222' - call compare1(r, s1, s2); print*, r - call compare2(r, s1, s2); print*, r - call ss(mm); print*, mm - call e1(mm, 17); print*, mm - call e2(17, mm); print*, mm - call e3(mm); print*, mm - print*, jj(11) - print*, rr(22) - m = 'abcd efgh' - print*, hh(m) - print*, qq(m) - call dd1 - call dd2 - call dd3(6) - 6 continue - end - - ! CHECK-LABEL: func @_QPss( - ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) { - subroutine ss(n1) - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} - integer n17, n2 - nx = 100 - n1 = nx + 10 - return - - ! CHECK-LABEL: func @_QPe1( + character(*) c1, c2, d1, d2 + logical x, y + x = c1 < c2 + return + +! CHECK-LABEL: func @_QPcompare2( +! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) { +entry compare2(y, d2, d1) + y = d1 < d2 +end + +program entries + character(10) hh, qq, m + character(len=4) s1, s2 + integer mm + logical r + s1 = 'a111' + s2 = 'a222' + call compare1(r, s1, s2); print*, r + call compare2(r, s1, s2); print*, r + call ss(mm); print*, mm + call e1(mm, 17); print*, mm + call e2(17, mm); print*, mm + call e3(mm); print*, mm + print*, jj(11) + print*, rr(22) + m = 'abcd efgh' + print*, hh(m) + print*, qq(m) + call dd1 + call dd2 + call dd3(6) +6 continue +end + +! CHECK-LABEL: func @_QPss( +! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) { +subroutine ss(n1) + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} + integer n17, n2 + nx = 100 + n1 = nx + 10 + return + +! CHECK-LABEL: func @_QPe1( +! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}) { +entry e1(n2, n17) + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} + ny = 200 + n2 = ny + 20 + return + + ! CHECK-LABEL: func @_QPe2( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}) { - entry e1(n2, n17) - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} - ny = 200 - n2 = ny + 20 - return - - ! CHECK-LABEL: func @_QPe2( - ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}) { - entry e2(n3, n1) - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} - - ! CHECK-LABEL: func @_QPe3( - ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) { - entry e3(n1) - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} - n1 = 30 - end - - ! CHECK-LABEL: func @_QPjj( - ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> i32 - function jj(n1) - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Ejj"} - jj = 100 - jj = jj + n1 - return - - ! CHECK-LABEL: func @_QPrr( - ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> f32 - entry rr(n2) - ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Ejj"} - rr = 200.0 - rr = rr + n2 - end - - ! CHECK-LABEL: func @_QPhh( +entry e2(n3, n1) + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} + +! CHECK-LABEL: func @_QPe3( +! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) { +entry e3(n1) + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"} + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"} + n1 = 30 +end + +! CHECK-LABEL: func @_QPjj( +! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> i32 +function jj(n1) + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Ejj"} + jj = 100 + jj = jj + n1 + return + + ! CHECK-LABEL: func @_QPrr( + ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> f32 +entry rr(n2) + ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Ejj"} + rr = 200.0 + rr = rr + n2 +end + +! CHECK-LABEL: func @_QPhh( +! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: index{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) -> !fir.boxchar<1> +function hh(c1) + character(10) c1, hh, qq + hh = c1 + return + ! CHECK-LABEL: func @_QPqq( ! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: index{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) -> !fir.boxchar<1> - function hh(c1) - character(10) c1, hh, qq - hh = c1 - return - ! CHECK-LABEL: func @_QPqq( - ! CHECK-SAME: %{{.*}}: !fir.ref>{{.*}}, %{{.*}}: index{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) -> !fir.boxchar<1> - entry qq(c1) - qq = c1 - end - - ! CHECK-LABEL: func @_QPchar_array() - function char_array() - character(10), c(5) - ! CHECK-LABEL: func @_QPchar_array_entry( - ! CHECK-SAME: %{{.*}}: !fir.boxchar<1>{{.*}}) -> f32 { - entry char_array_entry(c) - end - - ! CHECK-LABEL: func @_QPdd1() - subroutine dd1 - ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name = - ! "_QFdd1Ekk"} - ! CHECK: br ^bb1 - ! CHECK: ^bb1: // pred: ^bb0 - ! CHECK: %[[ten:.*]] = arith.constant 10 : i32 - ! CHECK: fir.store %[[ten:.*]] to %[[kk]] : !fir.ref - ! CHECK: br ^bb2 - ! CHECK: ^bb2: // pred: ^bb1 - ! CHECK: %[[twenty:.*]] = arith.constant 20 : i32 - ! CHECK: fir.store %[[twenty:.*]] to %[[kk]] : !fir.ref - ! CHECK: br ^bb3 - ! CHECK: ^bb3: // pred: ^bb2 - ! CHECK: return - kk = 10 - - ! CHECK-LABEL: func @_QPdd2() - ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name = - ! "_QFdd1Ekk"} - ! CHECK: br ^bb1 - ! CHECK: ^bb1: // pred: ^bb0 - ! CHECK: %[[twenty:.*]] = arith.constant 20 : i32 - ! CHECK: fir.store %[[twenty:.*]] to %[[kk]] : !fir.ref - ! CHECK: br ^bb2 - ! CHECK: ^bb2: // pred: ^bb1 - ! CHECK: return - entry dd2 - kk = 20 - return - - ! CHECK-LABEL: func @_QPdd3 - ! CHECK: %[[dd3:[0-9]*]] = fir.alloca index {bindc_name = "dd3"} - ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name = - ! "_QFdd1Ekk"} - ! CHECK: %[[zero:.*]] = arith.constant 0 : index - ! CHECK: fir.store %[[zero:.*]] to %[[dd3]] : !fir.ref - ! CHECK: br ^bb1 - ! CHECK: ^bb1: // pred: ^bb0 - ! CHECK: %[[thirty:.*]] = arith.constant 30 : i32 - ! CHECK: fir.store %[[thirty:.*]] to %[[kk:[0-9]*]] : !fir.ref - ! CHECK: br ^bb2 - ! CHECK: ^bb2: // pred: ^bb1 - ! CHECK: %[[altret:[0-9]*]] = fir.load %[[dd3]] : !fir.ref - ! CHECK: return %[[altret:[0-9]*]] : index - entry dd3(*) - kk = 30 - end +entry qq(c1) + qq = c1 +end + +! CHECK-LABEL: func @_QPchar_array() +function char_array() + character(10), c(5) +! CHECK-LABEL: func @_QPchar_array_entry( +! CHECK-SAME: %{{.*}}: !fir.boxchar<1>{{.*}}) -> f32 { +entry char_array_entry(c) +end + +! CHECK-LABEL: func @_QPdd1() +subroutine dd1 + ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name = + ! "_QFdd1Ekk"} + ! CHECK: br ^bb1 + ! CHECK: ^bb1: // pred: ^bb0 + ! CHECK: %[[ten:.*]] = arith.constant 10 : i32 + ! CHECK: fir.store %[[ten:.*]] to %[[kk]] : !fir.ref + ! CHECK: br ^bb2 + ! CHECK: ^bb2: // pred: ^bb1 + ! CHECK: %[[twenty:.*]] = arith.constant 20 : i32 + ! CHECK: fir.store %[[twenty:.*]] to %[[kk]] : !fir.ref + ! CHECK: br ^bb3 + ! CHECK: ^bb3: // pred: ^bb2 + ! CHECK: return + kk = 10 + + ! CHECK-LABEL: func @_QPdd2() + ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name = + ! "_QFdd1Ekk"} + ! CHECK: br ^bb1 + ! CHECK: ^bb1: // pred: ^bb0 + ! CHECK: %[[twenty:.*]] = arith.constant 20 : i32 + ! CHECK: fir.store %[[twenty:.*]] to %[[kk]] : !fir.ref + ! CHECK: br ^bb2 + ! CHECK: ^bb2: // pred: ^bb1 + ! CHECK: return + entry dd2 + kk = 20 + return + + ! CHECK-LABEL: func @_QPdd3 + ! CHECK: %[[dd3:[0-9]*]] = fir.alloca index {bindc_name = "dd3"} + ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name = + ! "_QFdd1Ekk"} + ! CHECK: %[[zero:.*]] = arith.constant 0 : index + ! CHECK: fir.store %[[zero:.*]] to %[[dd3]] : !fir.ref + ! CHECK: br ^bb1 + ! CHECK: ^bb1: // pred: ^bb0 + ! CHECK: %[[thirty:.*]] = arith.constant 30 : i32 + ! CHECK: fir.store %[[thirty:.*]] to %[[kk:[0-9]*]] : !fir.ref + ! CHECK: br ^bb2 + ! CHECK: ^bb2: // pred: ^bb1 + ! CHECK: %[[altret:[0-9]*]] = fir.load %[[dd3]] : !fir.ref + ! CHECK: return %[[altret:[0-9]*]] : index + entry dd3(*) + kk = 30 +end diff --git a/flang/test/Lower/forall/forall-construct.f90 b/flang/test/Lower/forall/forall-construct.f90 index 0bd463090854f..08415bfea1eb9 100644 --- a/flang/test/Lower/forall/forall-construct.f90 +++ b/flang/test/Lower/forall/forall-construct.f90 @@ -4,95 +4,94 @@ !*** Test a FORALL construct subroutine test_forall_construct(a,b) - integer :: i, j - real :: a(:,:), b(:,:) - forall (i=1:ubound(a,1), j=1:ubound(a,2), b(j,i) > 0.0) - a(i,j) = b(j,i) / 3.14 - end forall - end subroutine test_forall_construct - - ! CHECK-LABEL: func @_QPtest_forall_construct( - ! 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:.*]] = arith.constant 1 : i32 - ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index - ! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]]#1 : (index) -> i64 - ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i64 - ! CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_8]], %[[VAL_10]] : i64 - ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_13:.*]] = arith.subi %[[VAL_11]], %[[VAL_12]] : i64 - ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> i32 - ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> index - ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_17:.*]] = arith.constant 1 : i32 - ! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index - ! CHECK: %[[VAL_19:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]]#1 : (index) -> i64 - ! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (index) -> i64 - ! CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_21]], %[[VAL_23]] : i64 - ! CHECK: %[[VAL_25:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_24]], %[[VAL_25]] : i64 - ! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i64) -> i32 - ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i32) -> index - ! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_30:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_31:.*]] = fir.array_load %[[VAL_1]] : (!fir.box>) -> !fir.array - ! CHECK: %[[VAL_32:.*]] = fir.do_loop %[[VAL_33:.*]] = %[[VAL_5]] to %[[VAL_15]] step %[[VAL_16]] unordered iter_args(%[[VAL_34:.*]] = %[[VAL_30]]) -> (!fir.array) { - ! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_33]] : (index) -> i32 - ! CHECK: fir.store %[[VAL_35]] to %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_36:.*]] = fir.do_loop %[[VAL_37:.*]] = %[[VAL_18]] to %[[VAL_28]] step %[[VAL_29]] unordered iter_args(%[[VAL_38:.*]] = %[[VAL_34]]) -> (!fir.array) { - ! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (index) -> i32 - ! CHECK: fir.store %[[VAL_39]] to %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i32) -> i64 - ! CHECK: %[[VAL_42:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_43:.*]] = arith.subi %[[VAL_41]], %[[VAL_42]] : i64 - ! CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (i32) -> i64 - ! CHECK: %[[VAL_46:.*]] = arith.constant 1 : i64 - ! CHECK: %[[VAL_47:.*]] = arith.subi %[[VAL_45]], %[[VAL_46]] : i64 - ! CHECK: %[[VAL_48:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_43]], %[[VAL_47]] : (!fir.box>, i64, i64) -> !fir.ref - ! CHECK: %[[VAL_49:.*]] = fir.load %[[VAL_48]] : !fir.ref - ! CHECK: %[[VAL_50:.*]] = arith.constant 0.000000e+00 : f32 - ! CHECK: %[[VAL_51:.*]] = arith.cmpf ogt, %[[VAL_49]], %[[VAL_50]] : f32 - ! CHECK: %[[VAL_52:.*]] = fir.if %[[VAL_51]] -> (!fir.array) { - ! CHECK: %[[VAL_53:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_54:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_54]] : (i32) -> i64 - ! CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_55]] : (i64) -> index - ! CHECK: %[[VAL_57:.*]] = arith.subi %[[VAL_56]], %[[VAL_53]] : index - ! CHECK: %[[VAL_58:.*]] = fir.load %[[VAL_3]] : !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_53]] : index - ! CHECK: %[[VAL_62:.*]] = arith.constant 3.140000e+00 : f32 - ! CHECK: %[[VAL_63:.*]] = fir.array_fetch %[[VAL_31]], %[[VAL_57]], %[[VAL_61]] : (!fir.array, index, index) -> f32 - ! CHECK: %[[VAL_64:.*]] = arith.divf %[[VAL_63]], %[[VAL_62]] : f32 - ! CHECK: %[[VAL_65:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_66:.*]] = fir.load %[[VAL_3]] : !fir.ref - ! CHECK: %[[VAL_67:.*]] = fir.convert %[[VAL_66]] : (i32) -> i64 - ! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_67]] : (i64) -> index - ! CHECK: %[[VAL_69:.*]] = arith.subi %[[VAL_68]], %[[VAL_65]] : index - ! CHECK: %[[VAL_70:.*]] = fir.load %[[VAL_2]] : !fir.ref - ! CHECK: %[[VAL_71:.*]] = fir.convert %[[VAL_70]] : (i32) -> i64 - ! CHECK: %[[VAL_72:.*]] = fir.convert %[[VAL_71]] : (i64) -> index - ! CHECK: %[[VAL_73:.*]] = arith.subi %[[VAL_72]], %[[VAL_65]] : index - ! CHECK: %[[VAL_74:.*]] = fir.array_update %[[VAL_38]], %[[VAL_64]], %[[VAL_69]], %[[VAL_73]] : (!fir.array, f32, index, index) -> !fir.array - ! CHECK: fir.result %[[VAL_74]] : !fir.array - ! CHECK: } else { - ! CHECK: fir.result %[[VAL_38]] : !fir.array - ! CHECK: } - ! CHECK: fir.result %[[VAL_75:.*]] : !fir.array - ! CHECK: } - ! CHECK: fir.result %[[VAL_76:.*]] : !fir.array - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_30]], %[[VAL_77:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> - ! CHECK: return - ! CHECK: } - \ No newline at end of file + integer :: i, j + real :: a(:,:), b(:,:) + forall (i=1:ubound(a,1), j=1:ubound(a,2), b(j,i) > 0.0) + a(i,j) = b(j,i) / 3.14 + end forall +end subroutine test_forall_construct + +! CHECK-LABEL: func @_QPtest_forall_construct( +! 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:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]]#1 : (index) -> i64 +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i64 +! CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_8]], %[[VAL_10]] : i64 +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_13:.*]] = arith.subi %[[VAL_11]], %[[VAL_12]] : i64 +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> i32 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> index +! CHECK: %[[VAL_16:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_17:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index +! CHECK: %[[VAL_19:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]]#1 : (index) -> i64 +! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (index) -> i64 +! CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_21]], %[[VAL_23]] : i64 +! CHECK: %[[VAL_25:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_24]], %[[VAL_25]] : i64 +! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i64) -> i32 +! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i32) -> index +! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_30:.*]] = fir.array_load %[[VAL_0]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_31:.*]] = fir.array_load %[[VAL_1]] : (!fir.box>) -> !fir.array +! CHECK: %[[VAL_32:.*]] = fir.do_loop %[[VAL_33:.*]] = %[[VAL_5]] to %[[VAL_15]] step %[[VAL_16]] unordered iter_args(%[[VAL_34:.*]] = %[[VAL_30]]) -> (!fir.array) { +! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_33]] : (index) -> i32 +! CHECK: fir.store %[[VAL_35]] to %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_36:.*]] = fir.do_loop %[[VAL_37:.*]] = %[[VAL_18]] to %[[VAL_28]] step %[[VAL_29]] unordered iter_args(%[[VAL_38:.*]] = %[[VAL_34]]) -> (!fir.array) { +! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (index) -> i32 +! CHECK: fir.store %[[VAL_39]] to %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i32) -> i64 +! CHECK: %[[VAL_42:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_43:.*]] = arith.subi %[[VAL_41]], %[[VAL_42]] : i64 +! CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (i32) -> i64 +! CHECK: %[[VAL_46:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_47:.*]] = arith.subi %[[VAL_45]], %[[VAL_46]] : i64 +! CHECK: %[[VAL_48:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_43]], %[[VAL_47]] : (!fir.box>, i64, i64) -> !fir.ref +! CHECK: %[[VAL_49:.*]] = fir.load %[[VAL_48]] : !fir.ref +! CHECK: %[[VAL_50:.*]] = arith.constant 0.000000e+00 : f32 +! CHECK: %[[VAL_51:.*]] = arith.cmpf ogt, %[[VAL_49]], %[[VAL_50]] : f32 +! CHECK: %[[VAL_52:.*]] = fir.if %[[VAL_51]] -> (!fir.array) { +! CHECK: %[[VAL_53:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_54:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_54]] : (i32) -> i64 +! CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_55]] : (i64) -> index +! CHECK: %[[VAL_57:.*]] = arith.subi %[[VAL_56]], %[[VAL_53]] : index +! CHECK: %[[VAL_58:.*]] = fir.load %[[VAL_3]] : !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_53]] : index +! CHECK: %[[VAL_62:.*]] = arith.constant 3.140000e+00 : f32 +! CHECK: %[[VAL_63:.*]] = fir.array_fetch %[[VAL_31]], %[[VAL_57]], %[[VAL_61]] : (!fir.array, index, index) -> f32 +! CHECK: %[[VAL_64:.*]] = arith.divf %[[VAL_63]], %[[VAL_62]] : f32 +! CHECK: %[[VAL_65:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_66:.*]] = fir.load %[[VAL_3]] : !fir.ref +! CHECK: %[[VAL_67:.*]] = fir.convert %[[VAL_66]] : (i32) -> i64 +! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_67]] : (i64) -> index +! CHECK: %[[VAL_69:.*]] = arith.subi %[[VAL_68]], %[[VAL_65]] : index +! CHECK: %[[VAL_70:.*]] = fir.load %[[VAL_2]] : !fir.ref +! CHECK: %[[VAL_71:.*]] = fir.convert %[[VAL_70]] : (i32) -> i64 +! CHECK: %[[VAL_72:.*]] = fir.convert %[[VAL_71]] : (i64) -> index +! CHECK: %[[VAL_73:.*]] = arith.subi %[[VAL_72]], %[[VAL_65]] : index +! CHECK: %[[VAL_74:.*]] = fir.array_update %[[VAL_38]], %[[VAL_64]], %[[VAL_69]], %[[VAL_73]] : (!fir.array, f32, index, index) -> !fir.array +! CHECK: fir.result %[[VAL_74]] : !fir.array +! CHECK: } else { +! CHECK: fir.result %[[VAL_38]] : !fir.array +! CHECK: } +! CHECK: fir.result %[[VAL_75:.*]] : !fir.array +! CHECK: } +! CHECK: fir.result %[[VAL_76:.*]] : !fir.array +! CHECK: } +! CHECK: fir.array_merge_store %[[VAL_30]], %[[VAL_77:.*]] to %[[VAL_0]] : !fir.array, !fir.array, !fir.box> +! CHECK: return +! CHECK: } diff --git a/flang/test/Lower/nullify.f90 b/flang/test/Lower/nullify.f90 index f9fd3d8430077..a192dc64e84e4 100644 --- a/flang/test/Lower/nullify.f90 +++ b/flang/test/Lower/nullify.f90 @@ -10,42 +10,42 @@ ! CHECK-LABEL: func @_QPtest_scalar( ! CHECK-SAME: %[[p:.*]]: !fir.ref>>{{.*}}) subroutine test_scalar(p) - real, pointer :: p - ! CHECK: %[[null:.*]] = fir.zero_bits !fir.ptr - ! CHECK: %[[box:.*]] = fir.embox %[[null]] : (!fir.ptr) -> !fir.box> - ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref>> - nullify(p) - end subroutine - - ! CHECK-LABEL: func @_QPtest_scalar_char( - ! CHECK-SAME: %[[p:.*]]: !fir.ref>>>{{.*}}) - subroutine test_scalar_char(p) - character(:), pointer :: p - ! CHECK: %[[null:.*]] = fir.zero_bits !fir.ptr> - ! CHECK: %[[box:.*]] = fir.embox %[[null]] typeparams %c0{{.*}} : (!fir.ptr>, index) -> !fir.box>> - ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref>>> - nullify(p) - end subroutine - - ! CHECK-LABEL: func @_QPtest_array( - ! CHECK-SAME: %[[p:.*]]: !fir.ref>>>{{.*}}) - subroutine test_array(p) - real, pointer :: p(:) - ! CHECK: %[[null:.*]] = fir.zero_bits !fir.ptr> - ! CHECK: %[[shape:.*]] = fir.shape %c0{{.*}} - ! CHECK: %[[box:.*]] = fir.embox %[[null]](%[[shape]]) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> - ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref>>> - nullify(p) - end subroutine - - ! CHECK-LABEL: func @_QPtest_list( - ! CHECK-SAME: %[[p1:.*]]: !fir.ref>>{{.*}}, %[[p2:.*]]: !fir.ref>>>{{.*}}) - subroutine test_list(p1, p2) - real, pointer :: p1, p2(:) - ! CHECK: fir.zero_bits !fir.ptr - ! CHECK: fir.store %{{.*}} to %[[p1]] : !fir.ref>> - - ! CHECK: fir.zero_bits !fir.ptr> - ! CHECK: fir.store %{{.*}} to %[[p2]] : !fir.ref>>> - nullify(p1, p2) - end subroutine + real, pointer :: p + ! CHECK: %[[null:.*]] = fir.zero_bits !fir.ptr + ! CHECK: %[[box:.*]] = fir.embox %[[null]] : (!fir.ptr) -> !fir.box> + ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref>> + nullify(p) +end subroutine + +! CHECK-LABEL: func @_QPtest_scalar_char( +! CHECK-SAME: %[[p:.*]]: !fir.ref>>>{{.*}}) +subroutine test_scalar_char(p) + character(:), pointer :: p + ! CHECK: %[[null:.*]] = fir.zero_bits !fir.ptr> + ! CHECK: %[[box:.*]] = fir.embox %[[null]] typeparams %c0{{.*}} : (!fir.ptr>, index) -> !fir.box>> + ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref>>> + nullify(p) +end subroutine + +! CHECK-LABEL: func @_QPtest_array( +! CHECK-SAME: %[[p:.*]]: !fir.ref>>>{{.*}}) +subroutine test_array(p) + real, pointer :: p(:) + ! CHECK: %[[null:.*]] = fir.zero_bits !fir.ptr> + ! CHECK: %[[shape:.*]] = fir.shape %c0{{.*}} + ! CHECK: %[[box:.*]] = fir.embox %[[null]](%[[shape]]) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> + ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref>>> + nullify(p) +end subroutine + +! CHECK-LABEL: func @_QPtest_list( +! CHECK-SAME: %[[p1:.*]]: !fir.ref>>{{.*}}, %[[p2:.*]]: !fir.ref>>>{{.*}}) +subroutine test_list(p1, p2) + real, pointer :: p1, p2(:) + ! CHECK: fir.zero_bits !fir.ptr + ! CHECK: fir.store %{{.*}} to %[[p1]] : !fir.ref>> + + ! CHECK: fir.zero_bits !fir.ptr> + ! CHECK: fir.store %{{.*}} to %[[p2]] : !fir.ref>>> + nullify(p1, p2) +end subroutine diff --git a/flang/test/Lower/read-write-buffer.f90 b/flang/test/Lower/read-write-buffer.f90 index 330a48c6c7d59..2972049ba74ca 100644 --- a/flang/test/Lower/read-write-buffer.f90 +++ b/flang/test/Lower/read-write-buffer.f90 @@ -4,32 +4,31 @@ ! Format (Fortran 2018 12.6.2.2 point 3) ! CHECK-LABEL: func @_QPtest_array_format subroutine test_array_format - ! CHECK-DAG: %[[c2:.*]] = arith.constant 2 : index - ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : index - ! CHECK-DAG: %[[mem:.*]] = fir.alloca !fir.array<2x!fir.char<1,10>> - character(10) :: array(2) - array(1) ="(15HThis i" - array(2) ="s a test.)" - ! CHECK-DAG: %[[fmtLen:.*]] = arith.muli %[[c10]], %[[c2]] : index - ! CHECK-DAG: %[[scalarFmt:.*]] = fir.convert %[[mem]] : (!fir.ref>>) -> !fir.ref> - ! CHECK-DAG: %[[fmtArg:.*]] = fir.convert %[[scalarFmt]] : (!fir.ref>) -> !fir.ref - ! CHECK-DAG: %[[fmtLenArg:.*]] = fir.convert %[[fmtLen]] : (index) -> i64 - ! CHECK: fir.call @_FortranAioBeginExternalFormattedOutput(%[[fmtArg]], %[[fmtLenArg]], {{.*}}) - write(*, array) - end subroutine - - ! A test to check the buffer and it's length. - ! CHECK-LABEL: @_QPsome - subroutine some() - character(LEN=255):: buffer - character(LEN=255):: greeting - 10 format (A255) - ! CHECK: fir.address_of(@_QQcl.636F6D70696C6572) : - write (buffer, 10) "compiler" - read (buffer, 10) greeting - end - ! CHECK-LABEL: fir.global linkonce @_QQcl.636F6D70696C6572 - ! CHECK: %[[lit:.*]] = fir.string_lit "compiler"(8) : !fir.char<1,8> - ! CHECK: fir.has_value %[[lit]] : !fir.char<1,8> - ! CHECK: } - \ No newline at end of file + ! CHECK-DAG: %[[c2:.*]] = arith.constant 2 : index + ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : index + ! CHECK-DAG: %[[mem:.*]] = fir.alloca !fir.array<2x!fir.char<1,10>> + character(10) :: array(2) + array(1) ="(15HThis i" + array(2) ="s a test.)" + ! CHECK-DAG: %[[fmtLen:.*]] = arith.muli %[[c10]], %[[c2]] : index + ! CHECK-DAG: %[[scalarFmt:.*]] = fir.convert %[[mem]] : (!fir.ref>>) -> !fir.ref> + ! CHECK-DAG: %[[fmtArg:.*]] = fir.convert %[[scalarFmt]] : (!fir.ref>) -> !fir.ref + ! CHECK-DAG: %[[fmtLenArg:.*]] = fir.convert %[[fmtLen]] : (index) -> i64 + ! CHECK: fir.call @_FortranAioBeginExternalFormattedOutput(%[[fmtArg]], %[[fmtLenArg]], {{.*}}) + write(*, array) +end subroutine + +! A test to check the buffer and it's length. +! CHECK-LABEL: @_QPsome +subroutine some() + character(LEN=255):: buffer + character(LEN=255):: greeting +10 format (A255) + ! CHECK: fir.address_of(@_QQcl.636F6D70696C6572) : + write (buffer, 10) "compiler" + read (buffer, 10) greeting +end +! CHECK-LABEL: fir.global linkonce @_QQcl.636F6D70696C6572 +! CHECK: %[[lit:.*]] = fir.string_lit "compiler"(8) : !fir.char<1,8> +! CHECK: fir.has_value %[[lit]] : !fir.char<1,8> +! CHECK: } diff --git a/flang/test/Lower/statement-function.f90 b/flang/test/Lower/statement-function.f90 index 4f47668bab84d..b59b8fb1db9c6 100644 --- a/flang/test/Lower/statement-function.f90 +++ b/flang/test/Lower/statement-function.f90 @@ -6,17 +6,17 @@ ! CHECK-LABEL: func @_QPtest_stmt_0( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> f32 real function test_stmt_0(x) -real :: x, func, arg -func(arg) = arg + 0.123456 + real :: x, func, arg + func(arg) = arg + 0.123456 -! CHECK-DAG: %[[x:.*]] = fir.load %arg0 -! CHECK-DAG: %[[cst:.*]] = arith.constant 1.234560e-01 -! CHECK: %[[eval:.*]] = arith.addf %[[x]], %[[cst]] -! CHECK: fir.store %[[eval]] to %[[resmem:.*]] : !fir.ref -test_stmt_0 = func(x) + ! CHECK-DAG: %[[x:.*]] = fir.load %arg0 + ! CHECK-DAG: %[[cst:.*]] = arith.constant 1.234560e-01 + ! CHECK: %[[eval:.*]] = arith.addf %[[x]], %[[cst]] + ! CHECK: fir.store %[[eval]] to %[[resmem:.*]] : !fir.ref + test_stmt_0 = func(x) -! CHECK: %[[res:.*]] = fir.load %[[resmem]] -! CHECK: return %[[res]] + ! CHECK: %[[res:.*]] = fir.load %[[resmem]] + ! CHECK: return %[[res]] end function ! Check this is not lowered as a simple macro: e.g. argument is only @@ -24,51 +24,51 @@ real function test_stmt_0(x) ! statement function expression ! CHECK-LABEL: func @_QPtest_stmt_only_eval_arg_once() -> f32 real(4) function test_stmt_only_eval_arg_once() -real(4) :: only_once, x1 -func(x1) = x1 + x1 -! CHECK: %[[x2:.*]] = fir.alloca f32 {adapt.valuebyref} -! CHECK: %[[x1:.*]] = fir.call @_QPonly_once() -! Note: using -emit-fir, so the faked pass-by-reference is exposed -! CHECK: fir.store %[[x1]] to %[[x2]] -! CHECK: addf %{{.*}}, %{{.*}} -test_stmt_only_eval_arg_once = func(only_once()) + real(4) :: only_once, x1 + func(x1) = x1 + x1 + ! CHECK: %[[x2:.*]] = fir.alloca f32 {adapt.valuebyref} + ! CHECK: %[[x1:.*]] = fir.call @_QPonly_once() + ! Note: using -emit-fir, so the faked pass-by-reference is exposed + ! CHECK: fir.store %[[x1]] to %[[x2]] + ! CHECK: addf %{{.*}}, %{{.*}} + test_stmt_only_eval_arg_once = func(only_once()) end function ! Test nested statement function (note that they cannot be recursively ! nested as per F2018 C1577). real function test_stmt_1(x, a) -real :: y, a, b, foo -real :: func1, arg1, func2, arg2 -real :: res1, res2 -func1(arg1) = a + foo(arg1) -func2(arg2) = func1(arg2) + b -! CHECK-DAG: %[[bmem:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eb"} -! CHECK-DAG: %[[res1:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eres1"} -! CHECK-DAG: %[[res2:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eres2"} - -b = 5 - -! CHECK-DAG: %[[cst_8:.*]] = arith.constant 8.000000e+00 -! CHECK-DAG: fir.store %[[cst_8]] to %[[tmp1:.*]] : !fir.ref -! CHECK-DAG: %[[foocall1:.*]] = fir.call @_QPfoo(%[[tmp1]]) -! CHECK-DAG: %[[aload1:.*]] = fir.load %arg1 -! CHECK: %[[add1:.*]] = arith.addf %[[aload1]], %[[foocall1]] -! CHECK: fir.store %[[add1]] to %[[res1]] -res1 = func1(8.) - -! CHECK-DAG: %[[a2:.*]] = fir.load %arg1 -! CHECK-DAG: %[[foocall2:.*]] = fir.call @_QPfoo(%arg0) -! CHECK-DAG: %[[add2:.*]] = arith.addf %[[a2]], %[[foocall2]] -! CHECK-DAG: %[[b:.*]] = fir.load %[[bmem]] -! CHECK: %[[add3:.*]] = arith.addf %[[add2]], %[[b]] -! CHECK: fir.store %[[add3]] to %[[res2]] -res2 = func2(x) - -! CHECK-DAG: %[[res12:.*]] = fir.load %[[res1]] -! CHECK-DAG: %[[res22:.*]] = fir.load %[[res2]] -! CHECK: = arith.addf %[[res12]], %[[res22]] : f32 -test_stmt_1 = res1 + res2 -! CHECK: return %{{.*}} : f32 + real :: y, a, b, foo + real :: func1, arg1, func2, arg2 + real :: res1, res2 + func1(arg1) = a + foo(arg1) + func2(arg2) = func1(arg2) + b + ! CHECK-DAG: %[[bmem:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eb"} + ! CHECK-DAG: %[[res1:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eres1"} + ! CHECK-DAG: %[[res2:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eres2"} + + b = 5 + + ! CHECK-DAG: %[[cst_8:.*]] = arith.constant 8.000000e+00 + ! CHECK-DAG: fir.store %[[cst_8]] to %[[tmp1:.*]] : !fir.ref + ! CHECK-DAG: %[[foocall1:.*]] = fir.call @_QPfoo(%[[tmp1]]) + ! CHECK-DAG: %[[aload1:.*]] = fir.load %arg1 + ! CHECK: %[[add1:.*]] = arith.addf %[[aload1]], %[[foocall1]] + ! CHECK: fir.store %[[add1]] to %[[res1]] + res1 = func1(8.) + + ! CHECK-DAG: %[[a2:.*]] = fir.load %arg1 + ! CHECK-DAG: %[[foocall2:.*]] = fir.call @_QPfoo(%arg0) + ! CHECK-DAG: %[[add2:.*]] = arith.addf %[[a2]], %[[foocall2]] + ! CHECK-DAG: %[[b:.*]] = fir.load %[[bmem]] + ! CHECK: %[[add3:.*]] = arith.addf %[[add2]], %[[b]] + ! CHECK: fir.store %[[add3]] to %[[res2]] + res2 = func2(x) + + ! CHECK-DAG: %[[res12:.*]] = fir.load %[[res1]] + ! CHECK-DAG: %[[res22:.*]] = fir.load %[[res2]] + ! CHECK: = arith.addf %[[res12]], %[[res22]] : f32 + test_stmt_1 = res1 + res2 + ! CHECK: return %{{.*}} : f32 end function @@ -76,29 +76,29 @@ real function test_stmt_1(x, a) ! Test that they are not pre-evaluated. ! CHECK-LABEL: func @_QPtest_stmt_no_args real function test_stmt_no_args(x, y) -func() = x + y -! CHECK: addf -a = func() -! CHECK: fir.call @_QPfoo_may_modify_xy -call foo_may_modify_xy(x, y) -! CHECK: addf -! CHECK: addf -test_stmt_no_args = func() + a + func() = x + y + ! CHECK: addf + a = func() + ! CHECK: fir.call @_QPfoo_may_modify_xy + call foo_may_modify_xy(x, y) + ! CHECK: addf + ! CHECK: addf + test_stmt_no_args = func() + a end function ! Test statement function with character arguments ! CHECK-LABEL: @_QPtest_stmt_character integer function test_stmt_character(c, j) - integer :: i, j, func, argj - character(10) :: c, argc - ! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %arg0 : - ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : - ! CHECK: %[[c10_cast:.*]] = fir.convert %[[c10]] : (i32) -> index - ! CHECK: %[[c:.*]] = fir.emboxchar %[[unboxed]]#0, %[[c10_cast]] - - func(argc, argj) = len_trim(argc, 4) + argj - ! CHECK: addi %{{.*}}, %{{.*}} : i - test_stmt_character = func(c, j) + integer :: i, j, func, argj + character(10) :: c, argc + ! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %arg0 : + ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : + ! CHECK: %[[c10_cast:.*]] = fir.convert %[[c10]] : (i32) -> index + ! CHECK: %[[c:.*]] = fir.emboxchar %[[unboxed]]#0, %[[c10_cast]] + + func(argc, argj) = len_trim(argc, 4) + argj + ! CHECK: addi %{{.*}}, %{{.*}} : i + test_stmt_character = func(c, j) end function ! Test statement function with a character actual argument whose @@ -107,41 +107,41 @@ integer function test_stmt_character(c, j) ! CHECK-LABEL: @_QPtest_stmt_character_with_different_length( ! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1> integer function test_stmt_character_with_different_length(c) - integer :: func, ifoo - character(10) :: argc - character(*) :: c - ! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] : - ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : - ! CHECK: %[[c10_cast:.*]] = fir.convert %[[c10]] : (i32) -> index - ! CHECK: %[[argc:.*]] = fir.emboxchar %[[unboxed]]#0, %[[c10_cast]] - ! CHECK: fir.call @_QPifoo(%[[argc]]) : (!fir.boxchar<1>) -> i32 - func(argc) = ifoo(argc) - test_stmt_character = func(c) + integer :: func, ifoo + character(10) :: argc + character(*) :: c + ! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] : + ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : + ! CHECK: %[[c10_cast:.*]] = fir.convert %[[c10]] : (i32) -> index + ! CHECK: %[[argc:.*]] = fir.emboxchar %[[unboxed]]#0, %[[c10_cast]] + ! CHECK: fir.call @_QPifoo(%[[argc]]) : (!fir.boxchar<1>) -> i32 + func(argc) = ifoo(argc) + test_stmt_character = func(c) end function ! CHECK-LABEL: @_QPtest_stmt_character_with_different_length_2( ! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>{{.*}}, %[[arg1:.*]]: !fir.ref integer function test_stmt_character_with_different_length_2(c, n) - integer :: func, ifoo - character(n) :: argc - character(*) :: c - ! CHECK: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] : - ! CHECK: fir.load %[[arg1]] : !fir.ref - ! CHECK: %[[n:.*]] = fir.load %[[arg1]] : !fir.ref - ! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[n]], %c0{{.*}} : i32 - ! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[n]], %c0{{.*}} : i32 - ! CHECK: %[[lenCast:.*]] = fir.convert %[[len]] : (i32) -> index - ! CHECK: %[[argc:.*]] = fir.emboxchar %[[unboxed]]#0, %[[lenCast]] : (!fir.ref>, index) -> !fir.boxchar<1> - ! CHECK: fir.call @_QPifoo(%[[argc]]) : (!fir.boxchar<1>) -> i32 - func(argc) = ifoo(argc) - test_stmt_character = func(c) + integer :: func, ifoo + character(n) :: argc + character(*) :: c + ! CHECK: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] : + ! CHECK: fir.load %[[arg1]] : !fir.ref + ! CHECK: %[[n:.*]] = fir.load %[[arg1]] : !fir.ref + ! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[n]], %c0{{.*}} : i32 + ! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[n]], %c0{{.*}} : i32 + ! CHECK: %[[lenCast:.*]] = fir.convert %[[len]] : (i32) -> index + ! CHECK: %[[argc:.*]] = fir.emboxchar %[[unboxed]]#0, %[[lenCast]] : (!fir.ref>, index) -> !fir.boxchar<1> + ! CHECK: fir.call @_QPifoo(%[[argc]]) : (!fir.boxchar<1>) -> i32 + func(argc) = ifoo(argc) + test_stmt_character = func(c) end function ! issue #247 ! CHECK-LABEL: @_QPbug247 subroutine bug247(r) -I(R) = R -! CHECK: fir.call {{.*}}OutputInteger -PRINT *, I(2.5) -! CHECK: fir.call {{.*}}EndIo + I(R) = R + ! CHECK: fir.call {{.*}}OutputInteger + PRINT *, I(2.5) + ! CHECK: fir.call {{.*}}EndIo END subroutine bug247 diff --git a/flang/test/Lower/transformational-intrinsics.f90 b/flang/test/Lower/transformational-intrinsics.f90 index 4eed95c8e0924..819fec0759e04 100644 --- a/flang/test/Lower/transformational-intrinsics.f90 +++ b/flang/test/Lower/transformational-intrinsics.f90 @@ -9,281 +9,281 @@ module test2 - interface - subroutine takes_array_desc(l) - logical(1) :: l(:) - end subroutine - end interface - - contains - - ! CHECK-LABEL: func @_QMtest2Pin_io( - ! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}) { - subroutine in_io(x) - logical(1) :: x(:, :) - ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> - ! CHECK-DAG: %[[res_arg:.*]] = fir.convert %[[res_desc]] : (!fir.ref>>>>) -> !fir.ref> - ! CHECK-DAG: %[[x_arg:.*]] = fir.convert %[[arg0]] : (!fir.box>>) -> !fir.box - ! CHECK: fir.call @_Fortran{{.*}}AllDim(%[[res_arg]], %[[x_arg]], {{.*}}) : (!fir.ref>, !fir.box, i32, !fir.ref, i32) -> none - ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> - ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) - ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> - ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[io_embox:.*]] = fir.embox %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.box>> - ! CHECK: %[[io_embox_cast:.*]] = fir.convert %[[io_embox]] : (!fir.box>>) -> !fir.box - ! CHECK: fir.call @_Fortran{{.*}}ioOutputDescriptor({{.*}}, %[[io_embox_cast]]) : (!fir.ref, !fir.box) -> i1 - print *, all(x, 1) - ! CHECK: fir.freemem %[[res_addr]] - end subroutine - - ! CHECK-LABEL: func @_QMtest2Pin_call( - ! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}) { - subroutine in_call(x) - implicit none - logical(1) :: x(:, :) - ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> - ! CHECK-DAG: %[[res_arg:.*]] = fir.convert %[[res_desc]] : (!fir.ref>>>>) -> !fir.ref> - ! CHECK-DAG: %[[x_arg:.*]] = fir.convert %[[arg0]] : (!fir.box>>) -> !fir.box - ! CHECK: fir.call @_Fortran{{.*}}AllDim(%[[res_arg]], %[[x_arg]], {{.*}}) : (!fir.ref>, !fir.box, i32, !fir.ref, i32) -> none - ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> - ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) - ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> - ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[call_embox:.*]] = fir.embox %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.box>> - ! CHECK: fir.call @_QPtakes_array_desc(%[[call_embox]]) : (!fir.box>>) -> () - call takes_array_desc(all(x, 1)) - ! CHECK: fir.freemem %[[res_addr]] - end subroutine - - ! CHECK-LABEL: func @_QMtest2Pin_implicit_call( - ! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}) { - subroutine in_implicit_call(x) - logical(1) :: x(:, :) - ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> - ! CHECK: fir.call @_Fortran{{.*}}AllDim - ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> - ! CHECK: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> - ! CHECK: %[[res_addr_cast:.*]] = fir.convert %[[res_addr]] : (!fir.heap>>) -> !fir.ref>> - ! CHECK: fir.call @_QPtakes_implicit_array(%[[res_addr_cast]]) : (!fir.ref>>) -> () - call takes_implicit_array(all(x, 1)) - ! CHECK: fir.freemem %[[res_addr]] - end subroutine - - ! CHECK-LABEL: func @_QMtest2Pin_assignment( - ! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}, %[[arg1:.*]]: !fir.box>>{{.*}}) - subroutine in_assignment(x, y) - logical(1) :: x(:, :), y(:) - ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> - ! CHECK: %[[y_load:.*]] = fir.array_load %[[arg1]] : (!fir.box>>) -> !fir.array> - ! CHECK: fir.call @_Fortran{{.*}}AllDim - - ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> - ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) - ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> - ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[res_load:.*]] = fir.array_load %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.array> - - ! CHECK: %[[assign:.*]] = fir.do_loop %[[idx:.*]] = %{{.*}} to {{.*}} { - ! CHECK: %[[res_elt:.*]] = fir.array_fetch %[[res_load]], %[[idx]] : (!fir.array>, index) -> !fir.logical<1> - ! CHECK: fir.array_update %{{.*}} %[[res_elt]], %[[idx]] : (!fir.array>, !fir.logical<1>, index) -> !fir.array> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[y_load]], %[[assign]] to %[[arg1]] : !fir.array>, !fir.array>, !fir.box>> - y = all(x, 1) - ! CHECK: fir.freemem %[[res_addr]] - end subroutine - - ! CHECK-LABEL: func @_QMtest2Pin_elem_expr( - ! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}, %[[arg1:.*]]: !fir.box>>{{.*}}, %[[arg2:.*]]: !fir.box>>{{.*}}) - subroutine in_elem_expr(x, y, z) - logical(1) :: x(:, :), y(:), z(:) - ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> - ! CHECK-DAG: %[[y_load:.*]] = fir.array_load %[[arg1]] : (!fir.box>>) -> !fir.array> - ! CHECK-DAG: %[[z_load:.*]] = fir.array_load %[[arg2]] : (!fir.box>>) -> !fir.array> - ! CHECK: fir.call @_Fortran{{.*}}AllDim - - ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> - ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) - ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> - ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[res_load:.*]] = fir.array_load %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.array> - - ! CHECK: %[[elem_expr:.*]] = fir.do_loop %[[idx:.*]] = %{{.*}} to {{.*}} { - ! CHECK-DAG: %[[y_elt:.*]] = fir.array_fetch %[[y_load]], %[[idx]] : (!fir.array>, index) -> !fir.logical<1> - ! CHECK-DAG: %[[res_elt:.*]] = fir.array_fetch %[[res_load]], %[[idx]] : (!fir.array>, index) -> !fir.logical<1> - ! CHECK-DAG: %[[y_elt_i1:.*]] = fir.convert %[[y_elt]] : (!fir.logical<1>) -> i1 - ! CHECK-DAG: %[[res_elt_i1:.*]] = fir.convert %[[res_elt]] : (!fir.logical<1>) -> i1 - ! CHECK: %[[neqv_i1:.*]] = arith.cmpi ne, %[[y_elt_i1]], %[[res_elt_i1]] : i1 - ! CHECK: %[[neqv:.*]] = fir.convert %[[neqv_i1]] : (i1) -> !fir.logical<1> - ! CHECK: fir.array_update %{{.*}} %[[neqv]], %[[idx]] : (!fir.array>, !fir.logical<1>, index) -> !fir.array> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[z_load]], %[[elem_expr]] to %[[arg2]] : !fir.array>, !fir.array>, !fir.box>> - z = y .neqv. all(x, 1) - ! CHECK: fir.freemem %[[res_addr]] - end subroutine - - ! CSHIFT - - ! CHECK-LABEL: func @_QMtest2Pcshift_test() { - ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box>> - ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 - ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box>> - ! CHECK: %[[VAL_3:.*]] = arith.constant 3 : index - ! CHECK: %[[VAL_4:.*]] = arith.constant 3 : index - ! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "array", uniq_name = "_QMtest2Fcshift_testEarray"} - ! CHECK: %[[VAL_6:.*]] = arith.constant 3 : index - ! CHECK: %[[VAL_7:.*]] = arith.constant 3 : index - ! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "result", uniq_name = "_QMtest2Fcshift_testEresult"} - ! CHECK: %[[VAL_9:.*]] = arith.constant 3 : index - ! CHECK: %[[VAL_10:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = "shift", uniq_name = "_QMtest2Fcshift_testEshift"} - ! CHECK: %[[VAL_11:.*]] = arith.constant 6 : index - ! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.array<6xi32> {bindc_name = "vector", uniq_name = "_QMtest2Fcshift_testEvector"} - ! CHECK: %[[VAL_13:.*]] = arith.constant 6 : index - ! CHECK: %[[VAL_14:.*]] = fir.alloca !fir.array<6xi32> {bindc_name = "vectorresult", uniq_name = "_QMtest2Fcshift_testEvectorresult"} - ! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_6]], %[[VAL_7]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_16:.*]] = fir.array_load %[[VAL_8]](%[[VAL_15]]) : (!fir.ref>, !fir.shape<2>) -> !fir.array<3x3xi32> - ! CHECK: %[[VAL_17:.*]] = arith.constant -2 : i32 - ! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_3]], %[[VAL_4]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_5]](%[[VAL_18]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> - ! CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap> - ! CHECK: %[[VAL_21:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_22:.*]] = fir.shape %[[VAL_21]], %[[VAL_21]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_23:.*]] = fir.embox %[[VAL_20]](%[[VAL_22]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> - ! CHECK: fir.store %[[VAL_23]] to %[[VAL_2]] : !fir.ref>>> - ! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_9]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_10]](%[[VAL_24]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_26:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref>>>) -> !fir.ref> - ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_19]] : (!fir.box>) -> !fir.box - ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_25]] : (!fir.box>) -> !fir.box - ! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_32:.*]] = fir.call @_FortranACshift(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_17]], %[[VAL_31]], %[[VAL_27]]) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none - ! CHECK: %[[VAL_33:.*]] = fir.load %[[VAL_2]] : !fir.ref>>> - ! CHECK: %[[VAL_34:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_35:.*]]:3 = fir.box_dims %[[VAL_33]], %[[VAL_34]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_36:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_37:.*]]:3 = fir.box_dims %[[VAL_33]], %[[VAL_36]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_38:.*]] = fir.box_addr %[[VAL_33]] : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[VAL_39:.*]] = fir.shape_shift %[[VAL_35]]#0, %[[VAL_35]]#1, %[[VAL_37]]#0, %[[VAL_37]]#1 : (index, index, index, index) -> !fir.shapeshift<2> - ! CHECK: %[[VAL_40:.*]] = fir.array_load %[[VAL_38]](%[[VAL_39]]) : (!fir.heap>, !fir.shapeshift<2>) -> !fir.array - ! CHECK: %[[VAL_41:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_42:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_43:.*]] = arith.subi %[[VAL_6]], %[[VAL_41]] : index - ! CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_7]], %[[VAL_41]] : index - ! CHECK: %[[VAL_45:.*]] = fir.do_loop %[[VAL_46:.*]] = %[[VAL_42]] to %[[VAL_44]] step %[[VAL_41]] unordered iter_args(%[[VAL_47:.*]] = %[[VAL_16]]) -> (!fir.array<3x3xi32>) { - ! CHECK: %[[VAL_48:.*]] = fir.do_loop %[[VAL_49:.*]] = %[[VAL_42]] to %[[VAL_43]] step %[[VAL_41]] unordered iter_args(%[[VAL_50:.*]] = %[[VAL_47]]) -> (!fir.array<3x3xi32>) { - ! CHECK: %[[VAL_51:.*]] = fir.array_fetch %[[VAL_40]], %[[VAL_49]], %[[VAL_46]] : (!fir.array, index, index) -> i32 - ! CHECK: %[[VAL_52:.*]] = fir.array_update %[[VAL_50]], %[[VAL_51]], %[[VAL_49]], %[[VAL_46]] : (!fir.array<3x3xi32>, i32, index, index) -> !fir.array<3x3xi32> - ! CHECK: fir.result %[[VAL_52]] : !fir.array<3x3xi32> - ! CHECK: } - ! CHECK: fir.result %[[VAL_53:.*]] : !fir.array<3x3xi32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_16]], %[[VAL_54:.*]] to %[[VAL_8]] : !fir.array<3x3xi32>, !fir.array<3x3xi32>, !fir.ref> - ! CHECK: fir.freemem %[[VAL_38]] - ! CHECK: %[[VAL_55:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_56:.*]] = fir.array_load %[[VAL_14]](%[[VAL_55]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<6xi32> - ! CHECK: %[[VAL_57:.*]] = arith.constant 3 : i32 - ! CHECK: fir.store %[[VAL_57]] to %[[VAL_1]] : !fir.ref - ! CHECK: %[[VAL_58:.*]] = fir.shape %[[VAL_11]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_59:.*]] = fir.embox %[[VAL_12]](%[[VAL_58]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[VAL_60:.*]] = fir.zero_bits !fir.heap> - ! CHECK: %[[VAL_61:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_62:.*]] = fir.shape %[[VAL_61]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_63:.*]] = fir.embox %[[VAL_60]](%[[VAL_62]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> - ! CHECK: fir.store %[[VAL_63]] to %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_64:.*]] = fir.load %[[VAL_1]] : !fir.ref - ! CHECK: %[[VAL_65:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>>>) -> !fir.ref> - ! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_59]] : (!fir.box>) -> !fir.box - ! CHECK: %[[VAL_69:.*]] = fir.convert %[[VAL_64]] : (i32) -> i64 - ! CHECK: %[[VAL_70:.*]] = fir.convert %[[VAL_65]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_71:.*]] = fir.call @_FortranACshiftVector(%[[VAL_67]], %[[VAL_68]], %[[VAL_69]], %[[VAL_70]], %[[VAL_66]]) : (!fir.ref>, !fir.box, i64, !fir.ref, i32) -> none - ! CHECK: %[[VAL_72:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> - ! CHECK: %[[VAL_73:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_74:.*]]:3 = fir.box_dims %[[VAL_72]], %[[VAL_73]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_75:.*]] = fir.box_addr %[[VAL_72]] : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[VAL_76:.*]] = fir.shape_shift %[[VAL_74]]#0, %[[VAL_74]]#1 : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[VAL_77:.*]] = fir.array_load %[[VAL_75]](%[[VAL_76]]) : (!fir.heap>, !fir.shapeshift<1>) -> !fir.array - ! CHECK: %[[VAL_78:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_79:.*]] = arith.constant 0 : index - ! CHECK: %[[VAL_80:.*]] = arith.subi %[[VAL_13]], %[[VAL_78]] : index - ! CHECK: %[[VAL_81:.*]] = fir.do_loop %[[VAL_82:.*]] = %[[VAL_79]] to %[[VAL_80]] step %[[VAL_78]] unordered iter_args(%[[VAL_83:.*]] = %[[VAL_56]]) -> (!fir.array<6xi32>) { - ! CHECK: %[[VAL_84:.*]] = fir.array_fetch %[[VAL_77]], %[[VAL_82]] : (!fir.array, index) -> i32 - ! CHECK: %[[VAL_85:.*]] = fir.array_update %[[VAL_83]], %[[VAL_84]], %[[VAL_82]] : (!fir.array<6xi32>, i32, index) -> !fir.array<6xi32> - ! CHECK: fir.result %[[VAL_85]] : !fir.array<6xi32> - ! CHECK: } - ! CHECK: fir.array_merge_store %[[VAL_56]], %[[VAL_86:.*]] to %[[VAL_14]] : !fir.array<6xi32>, !fir.array<6xi32>, !fir.ref> - ! CHECK: fir.freemem %[[VAL_75]] - ! CHECK: return - ! CHECK: } - - subroutine cshift_test() - integer, dimension (3, 3) :: array - integer, dimension(3) :: shift - integer, dimension(3, 3) :: result - integer, dimension(6) :: vectorResult - integer, dimension (6) :: vector - result = cshift(array, shift, -2) ! non-vector case - vectorResult = cshift(vector, 3) ! vector case - end subroutine cshift_test - - ! UNPACK - ! CHECK-LABEL: func @_QMtest2Punpack_test - subroutine unpack_test() - integer, dimension(3) :: vector - integer, dimension (3,3) :: field - - logical, dimension(3,3) :: mask - integer, dimension(3,3) :: result - result = unpack(vector, mask, field) - ! CHECK-DAG: %[[a0:.*]] = fir.alloca !fir.box>> - ! CHECK-DAG: %[[a1:.*]] = fir.alloca i32 - ! CHECK-DAG: %[[a2:.*]] = fir.alloca !fir.box>> - ! CHECK-DAG: %[[a3:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "field", uniq_name = "_QMtest2Funpack_testEfield"} - ! CHECK-DAG: %[[a4:.*]] = fir.alloca !fir.array<3x3x!fir.logical<4>> {bindc_name = "mask", uniq_name = "_QMtest2Funpack_testEmask"} - ! CHECK-DAG: %[[a5:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "result", uniq_name = "_QMtest2Funpack_testEresult"} - ! CHECK-DAG: %[[a6:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = "vector", uniq_name = "_QMtest2Funpack_testEvector"} - ! CHECK: %[[a7:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK-NEXT: %[[a8:.*]] = fir.array_load %[[a5]](%[[a7]]) : (!fir.ref>, !fir.shape<2>) -> !fir.array<3x3xi32> - ! CHECK: %[[a9:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> - ! CHECK: %[[a10:.*]] = fir.embox %[[a6]](%[[a9]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[a11:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[a12:.*]] = fir.embox %[[a4]](%[[a11]]) : (!fir.ref>>, !fir.shape<2>) -> !fir.box>> - ! CHECK: %[[a13:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK-NEXT: %[[a14:.*]] = fir.embox %[[a3]](%[[a13]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> - ! CHECK: %[[a15:.*]] = fir.zero_bits !fir.heap> - ! CHECK: %[[a16:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[a17:.*]] = fir.embox %[[a15]](%[[a16]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> - ! CHECK-NEXT: fir.store %[[a17]] to %[[a2]] : !fir.ref>>> - ! CHECK-DAG: %[[a19:.*]] = fir.convert %[[a2]] : (!fir.ref>>>) -> !fir.ref> - ! CHECK-DAG: %[[a20:.*]] = fir.convert %[[a10]] : (!fir.box>) -> !fir.box - ! CHECK-DAG: %[[a21:.*]] = fir.convert %[[a12]] : (!fir.box>>) -> !fir.box - ! CHECK-DAG: %[[a22:.*]] = fir.convert %[[a14]] : (!fir.box>) -> !fir.box - ! CHECK: fir.call @_FortranAUnpack(%[[a19]], %[[a20]], %[[a21]], %[[a22]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, !fir.box, !fir.ref, i32) -> none - ! CHECK-NEXT: %[[a22:.*]] = fir.load %{{.*}} : !fir.ref>>> - ! CHECK: %[[a25:.*]] = fir.box_addr %[[a22]] : (!fir.box>>) -> !fir.heap> - ! CHECK: fir.freemem %[[a25]] - ! CHECK: %[[a36:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[a38:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> - ! CHECK-NEXT: %[[a39:.*]] = fir.embox %[[a6]](%[[a38]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> - ! CHECK: %[[a40:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK-NEXT: %[[a41:.*]] = fir.embox %[[a4]](%[[a40]]) : (!fir.ref>>, !fir.shape<2>) -> !fir.box>> - ! CHECK: %[[a42:.*]] = fir.embox %[[a1]] : (!fir.ref) -> !fir.box - ! CHECK: %[[a43:.*]] = fir.zero_bits !fir.heap> - ! CHECK: %[[a44:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> - ! CHECK: %[[a45:.*]] = fir.embox %[[a43]](%[[a44]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> - ! CHECK-NEXT: fir.store %[[a45]] to %[[a0]] : !fir.ref>>> - ! CHECK: %[[a47:.*]] = fir.convert %[[a0]] : (!fir.ref>>>) -> !fir.ref> - ! CHECK: %[[a48:.*]] = fir.convert %[[a39]] : (!fir.box>) -> !fir.box - ! CHECK: %[[a49:.*]] = fir.convert %[[a41]] : (!fir.box>>) -> !fir.box - ! CHECK: %[[a50:.*]] = fir.convert %[[a42]] : (!fir.box) -> !fir.box - result = unpack(vector, mask, 343) - ! CHECK: fir.call @_FortranAUnpack(%[[a47]], %[[a48]], %[[a49]], %[[a50]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, !fir.box, !fir.ref, i32) -> none - ! CHECK: %[[a53:.*]] = fir.load %[[a0]] : !fir.ref>>> - ! CHECK: %[[a56:.*]] = fir.box_addr %[[a53]] : (!fir.box>>) -> !fir.heap> - ! CHECK: fir.freemem %[[a56]] - ! CHECK-NEXT: return - end subroutine unpack_test - - end module +interface + subroutine takes_array_desc(l) + logical(1) :: l(:) + end subroutine +end interface + +contains + +! CHECK-LABEL: func @_QMtest2Pin_io( +! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}) { +subroutine in_io(x) + logical(1) :: x(:, :) + ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> + ! CHECK-DAG: %[[res_arg:.*]] = fir.convert %[[res_desc]] : (!fir.ref>>>>) -> !fir.ref> + ! CHECK-DAG: %[[x_arg:.*]] = fir.convert %[[arg0]] : (!fir.box>>) -> !fir.box + ! CHECK: fir.call @_Fortran{{.*}}AllDim(%[[res_arg]], %[[x_arg]], {{.*}}) : (!fir.ref>, !fir.box, i32, !fir.ref, i32) -> none + ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> + ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) + ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> + ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> + ! CHECK: %[[io_embox:.*]] = fir.embox %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.box>> + ! CHECK: %[[io_embox_cast:.*]] = fir.convert %[[io_embox]] : (!fir.box>>) -> !fir.box + ! CHECK: fir.call @_Fortran{{.*}}ioOutputDescriptor({{.*}}, %[[io_embox_cast]]) : (!fir.ref, !fir.box) -> i1 + print *, all(x, 1) + ! CHECK: fir.freemem %[[res_addr]] +end subroutine + +! CHECK-LABEL: func @_QMtest2Pin_call( +! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}) { +subroutine in_call(x) + implicit none + logical(1) :: x(:, :) + ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> + ! CHECK-DAG: %[[res_arg:.*]] = fir.convert %[[res_desc]] : (!fir.ref>>>>) -> !fir.ref> + ! CHECK-DAG: %[[x_arg:.*]] = fir.convert %[[arg0]] : (!fir.box>>) -> !fir.box + ! CHECK: fir.call @_Fortran{{.*}}AllDim(%[[res_arg]], %[[x_arg]], {{.*}}) : (!fir.ref>, !fir.box, i32, !fir.ref, i32) -> none + ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> + ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) + ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> + ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> + ! CHECK: %[[call_embox:.*]] = fir.embox %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.box>> + ! CHECK: fir.call @_QPtakes_array_desc(%[[call_embox]]) : (!fir.box>>) -> () + call takes_array_desc(all(x, 1)) + ! CHECK: fir.freemem %[[res_addr]] +end subroutine + +! CHECK-LABEL: func @_QMtest2Pin_implicit_call( +! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}) { +subroutine in_implicit_call(x) + logical(1) :: x(:, :) + ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> + ! CHECK: fir.call @_Fortran{{.*}}AllDim + ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> + ! CHECK: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> + ! CHECK: %[[res_addr_cast:.*]] = fir.convert %[[res_addr]] : (!fir.heap>>) -> !fir.ref>> + ! CHECK: fir.call @_QPtakes_implicit_array(%[[res_addr_cast]]) : (!fir.ref>>) -> () + call takes_implicit_array(all(x, 1)) + ! CHECK: fir.freemem %[[res_addr]] +end subroutine + +! CHECK-LABEL: func @_QMtest2Pin_assignment( +! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}, %[[arg1:.*]]: !fir.box>>{{.*}}) +subroutine in_assignment(x, y) + logical(1) :: x(:, :), y(:) + ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> + ! CHECK: %[[y_load:.*]] = fir.array_load %[[arg1]] : (!fir.box>>) -> !fir.array> + ! CHECK: fir.call @_Fortran{{.*}}AllDim + + ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> + ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) + ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> + ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> + ! CHECK: %[[res_load:.*]] = fir.array_load %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.array> + + ! CHECK: %[[assign:.*]] = fir.do_loop %[[idx:.*]] = %{{.*}} to {{.*}} { + ! CHECK: %[[res_elt:.*]] = fir.array_fetch %[[res_load]], %[[idx]] : (!fir.array>, index) -> !fir.logical<1> + ! CHECK: fir.array_update %{{.*}} %[[res_elt]], %[[idx]] : (!fir.array>, !fir.logical<1>, index) -> !fir.array> + ! CHECK: } + ! CHECK: fir.array_merge_store %[[y_load]], %[[assign]] to %[[arg1]] : !fir.array>, !fir.array>, !fir.box>> + y = all(x, 1) + ! CHECK: fir.freemem %[[res_addr]] +end subroutine + +! CHECK-LABEL: func @_QMtest2Pin_elem_expr( +! CHECK-SAME: %[[arg0:.*]]: !fir.box>>{{.*}}, %[[arg1:.*]]: !fir.box>>{{.*}}, %[[arg2:.*]]: !fir.box>>{{.*}}) +subroutine in_elem_expr(x, y, z) + logical(1) :: x(:, :), y(:), z(:) + ! CHECK: %[[res_desc:.]] = fir.alloca !fir.box>>> + ! CHECK-DAG: %[[y_load:.*]] = fir.array_load %[[arg1]] : (!fir.box>>) -> !fir.array> + ! CHECK-DAG: %[[z_load:.*]] = fir.array_load %[[arg2]] : (!fir.box>>) -> !fir.array> + ! CHECK: fir.call @_Fortran{{.*}}AllDim + + ! CHECK: %[[res_desc_load:.*]] = fir.load %[[res_desc]] : !fir.ref>>>> + ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[res_desc_load]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) + ! CHECK-DAG: %[[res_addr:.*]] = fir.box_addr %[[res_desc_load]] : (!fir.box>>>) -> !fir.heap>> + ! CHECK-DAG: %[[res_shape:.*]] = fir.shape_shift %[[dims]]#0, %[[dims]]#1 : (index, index) -> !fir.shapeshift<1> + ! CHECK: %[[res_load:.*]] = fir.array_load %[[res_addr]](%[[res_shape]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.array> + + ! CHECK: %[[elem_expr:.*]] = fir.do_loop %[[idx:.*]] = %{{.*}} to {{.*}} { + ! CHECK-DAG: %[[y_elt:.*]] = fir.array_fetch %[[y_load]], %[[idx]] : (!fir.array>, index) -> !fir.logical<1> + ! CHECK-DAG: %[[res_elt:.*]] = fir.array_fetch %[[res_load]], %[[idx]] : (!fir.array>, index) -> !fir.logical<1> + ! CHECK-DAG: %[[y_elt_i1:.*]] = fir.convert %[[y_elt]] : (!fir.logical<1>) -> i1 + ! CHECK-DAG: %[[res_elt_i1:.*]] = fir.convert %[[res_elt]] : (!fir.logical<1>) -> i1 + ! CHECK: %[[neqv_i1:.*]] = arith.cmpi ne, %[[y_elt_i1]], %[[res_elt_i1]] : i1 + ! CHECK: %[[neqv:.*]] = fir.convert %[[neqv_i1]] : (i1) -> !fir.logical<1> + ! CHECK: fir.array_update %{{.*}} %[[neqv]], %[[idx]] : (!fir.array>, !fir.logical<1>, index) -> !fir.array> + ! CHECK: } + ! CHECK: fir.array_merge_store %[[z_load]], %[[elem_expr]] to %[[arg2]] : !fir.array>, !fir.array>, !fir.box>> + z = y .neqv. all(x, 1) + ! CHECK: fir.freemem %[[res_addr]] +end subroutine + +! CSHIFT + + ! CHECK-LABEL: func @_QMtest2Pcshift_test() { + ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box>> + ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 + ! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box>> + ! CHECK: %[[VAL_3:.*]] = arith.constant 3 : index + ! CHECK: %[[VAL_4:.*]] = arith.constant 3 : index + ! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "array", uniq_name = "_QMtest2Fcshift_testEarray"} + ! CHECK: %[[VAL_6:.*]] = arith.constant 3 : index + ! CHECK: %[[VAL_7:.*]] = arith.constant 3 : index + ! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "result", uniq_name = "_QMtest2Fcshift_testEresult"} + ! CHECK: %[[VAL_9:.*]] = arith.constant 3 : index + ! CHECK: %[[VAL_10:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = "shift", uniq_name = "_QMtest2Fcshift_testEshift"} + ! CHECK: %[[VAL_11:.*]] = arith.constant 6 : index + ! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.array<6xi32> {bindc_name = "vector", uniq_name = "_QMtest2Fcshift_testEvector"} + ! CHECK: %[[VAL_13:.*]] = arith.constant 6 : index + ! CHECK: %[[VAL_14:.*]] = fir.alloca !fir.array<6xi32> {bindc_name = "vectorresult", uniq_name = "_QMtest2Fcshift_testEvectorresult"} + ! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_6]], %[[VAL_7]] : (index, index) -> !fir.shape<2> + ! CHECK: %[[VAL_16:.*]] = fir.array_load %[[VAL_8]](%[[VAL_15]]) : (!fir.ref>, !fir.shape<2>) -> !fir.array<3x3xi32> + ! CHECK: %[[VAL_17:.*]] = arith.constant -2 : i32 + ! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_3]], %[[VAL_4]] : (index, index) -> !fir.shape<2> + ! CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_5]](%[[VAL_18]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> + ! CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap> + ! CHECK: %[[VAL_21:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_22:.*]] = fir.shape %[[VAL_21]], %[[VAL_21]] : (index, index) -> !fir.shape<2> + ! CHECK: %[[VAL_23:.*]] = fir.embox %[[VAL_20]](%[[VAL_22]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> + ! CHECK: fir.store %[[VAL_23]] to %[[VAL_2]] : !fir.ref>>> + ! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_9]] : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_10]](%[[VAL_24]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[VAL_26:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref>>>) -> !fir.ref> + ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_19]] : (!fir.box>) -> !fir.box + ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_25]] : (!fir.box>) -> !fir.box + ! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_32:.*]] = fir.call @_FortranACshift(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_17]], %[[VAL_31]], %[[VAL_27]]) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none + ! CHECK: %[[VAL_33:.*]] = fir.load %[[VAL_2]] : !fir.ref>>> + ! CHECK: %[[VAL_34:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_35:.*]]:3 = fir.box_dims %[[VAL_33]], %[[VAL_34]] : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[VAL_36:.*]] = arith.constant 1 : index + ! CHECK: %[[VAL_37:.*]]:3 = fir.box_dims %[[VAL_33]], %[[VAL_36]] : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[VAL_38:.*]] = fir.box_addr %[[VAL_33]] : (!fir.box>>) -> !fir.heap> + ! CHECK: %[[VAL_39:.*]] = fir.shape_shift %[[VAL_35]]#0, %[[VAL_35]]#1, %[[VAL_37]]#0, %[[VAL_37]]#1 : (index, index, index, index) -> !fir.shapeshift<2> + ! CHECK: %[[VAL_40:.*]] = fir.array_load %[[VAL_38]](%[[VAL_39]]) : (!fir.heap>, !fir.shapeshift<2>) -> !fir.array + ! CHECK: %[[VAL_41:.*]] = arith.constant 1 : index + ! CHECK: %[[VAL_42:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_43:.*]] = arith.subi %[[VAL_6]], %[[VAL_41]] : index + ! CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_7]], %[[VAL_41]] : index + ! CHECK: %[[VAL_45:.*]] = fir.do_loop %[[VAL_46:.*]] = %[[VAL_42]] to %[[VAL_44]] step %[[VAL_41]] unordered iter_args(%[[VAL_47:.*]] = %[[VAL_16]]) -> (!fir.array<3x3xi32>) { + ! CHECK: %[[VAL_48:.*]] = fir.do_loop %[[VAL_49:.*]] = %[[VAL_42]] to %[[VAL_43]] step %[[VAL_41]] unordered iter_args(%[[VAL_50:.*]] = %[[VAL_47]]) -> (!fir.array<3x3xi32>) { + ! CHECK: %[[VAL_51:.*]] = fir.array_fetch %[[VAL_40]], %[[VAL_49]], %[[VAL_46]] : (!fir.array, index, index) -> i32 + ! CHECK: %[[VAL_52:.*]] = fir.array_update %[[VAL_50]], %[[VAL_51]], %[[VAL_49]], %[[VAL_46]] : (!fir.array<3x3xi32>, i32, index, index) -> !fir.array<3x3xi32> + ! CHECK: fir.result %[[VAL_52]] : !fir.array<3x3xi32> + ! CHECK: } + ! CHECK: fir.result %[[VAL_53:.*]] : !fir.array<3x3xi32> + ! CHECK: } + ! CHECK: fir.array_merge_store %[[VAL_16]], %[[VAL_54:.*]] to %[[VAL_8]] : !fir.array<3x3xi32>, !fir.array<3x3xi32>, !fir.ref> + ! CHECK: fir.freemem %[[VAL_38]] + ! CHECK: %[[VAL_55:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_56:.*]] = fir.array_load %[[VAL_14]](%[[VAL_55]]) : (!fir.ref>, !fir.shape<1>) -> !fir.array<6xi32> + ! CHECK: %[[VAL_57:.*]] = arith.constant 3 : i32 + ! CHECK: fir.store %[[VAL_57]] to %[[VAL_1]] : !fir.ref + ! CHECK: %[[VAL_58:.*]] = fir.shape %[[VAL_11]] : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_59:.*]] = fir.embox %[[VAL_12]](%[[VAL_58]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[VAL_60:.*]] = fir.zero_bits !fir.heap> + ! CHECK: %[[VAL_61:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_62:.*]] = fir.shape %[[VAL_61]] : (index) -> !fir.shape<1> + ! CHECK: %[[VAL_63:.*]] = fir.embox %[[VAL_60]](%[[VAL_62]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> + ! CHECK: fir.store %[[VAL_63]] to %[[VAL_0]] : !fir.ref>>> + ! CHECK: %[[VAL_64:.*]] = fir.load %[[VAL_1]] : !fir.ref + ! CHECK: %[[VAL_65:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref>>>) -> !fir.ref> + ! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_59]] : (!fir.box>) -> !fir.box + ! CHECK: %[[VAL_69:.*]] = fir.convert %[[VAL_64]] : (i32) -> i64 + ! CHECK: %[[VAL_70:.*]] = fir.convert %[[VAL_65]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[VAL_71:.*]] = fir.call @_FortranACshiftVector(%[[VAL_67]], %[[VAL_68]], %[[VAL_69]], %[[VAL_70]], %[[VAL_66]]) : (!fir.ref>, !fir.box, i64, !fir.ref, i32) -> none + ! CHECK: %[[VAL_72:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> + ! CHECK: %[[VAL_73:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_74:.*]]:3 = fir.box_dims %[[VAL_72]], %[[VAL_73]] : (!fir.box>>, index) -> (index, index, index) + ! CHECK: %[[VAL_75:.*]] = fir.box_addr %[[VAL_72]] : (!fir.box>>) -> !fir.heap> + ! CHECK: %[[VAL_76:.*]] = fir.shape_shift %[[VAL_74]]#0, %[[VAL_74]]#1 : (index, index) -> !fir.shapeshift<1> + ! CHECK: %[[VAL_77:.*]] = fir.array_load %[[VAL_75]](%[[VAL_76]]) : (!fir.heap>, !fir.shapeshift<1>) -> !fir.array + ! CHECK: %[[VAL_78:.*]] = arith.constant 1 : index + ! CHECK: %[[VAL_79:.*]] = arith.constant 0 : index + ! CHECK: %[[VAL_80:.*]] = arith.subi %[[VAL_13]], %[[VAL_78]] : index + ! CHECK: %[[VAL_81:.*]] = fir.do_loop %[[VAL_82:.*]] = %[[VAL_79]] to %[[VAL_80]] step %[[VAL_78]] unordered iter_args(%[[VAL_83:.*]] = %[[VAL_56]]) -> (!fir.array<6xi32>) { + ! CHECK: %[[VAL_84:.*]] = fir.array_fetch %[[VAL_77]], %[[VAL_82]] : (!fir.array, index) -> i32 + ! CHECK: %[[VAL_85:.*]] = fir.array_update %[[VAL_83]], %[[VAL_84]], %[[VAL_82]] : (!fir.array<6xi32>, i32, index) -> !fir.array<6xi32> + ! CHECK: fir.result %[[VAL_85]] : !fir.array<6xi32> + ! CHECK: } + ! CHECK: fir.array_merge_store %[[VAL_56]], %[[VAL_86:.*]] to %[[VAL_14]] : !fir.array<6xi32>, !fir.array<6xi32>, !fir.ref> + ! CHECK: fir.freemem %[[VAL_75]] + ! CHECK: return + ! CHECK: } + +subroutine cshift_test() + integer, dimension (3, 3) :: array + integer, dimension(3) :: shift + integer, dimension(3, 3) :: result + integer, dimension(6) :: vectorResult + integer, dimension (6) :: vector + result = cshift(array, shift, -2) ! non-vector case + vectorResult = cshift(vector, 3) ! vector case +end subroutine cshift_test + +! UNPACK +! CHECK-LABEL: func @_QMtest2Punpack_test +subroutine unpack_test() + integer, dimension(3) :: vector + integer, dimension (3,3) :: field + + logical, dimension(3,3) :: mask + integer, dimension(3,3) :: result + result = unpack(vector, mask, field) + ! CHECK-DAG: %[[a0:.*]] = fir.alloca !fir.box>> + ! CHECK-DAG: %[[a1:.*]] = fir.alloca i32 + ! CHECK-DAG: %[[a2:.*]] = fir.alloca !fir.box>> + ! CHECK-DAG: %[[a3:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "field", uniq_name = "_QMtest2Funpack_testEfield"} + ! CHECK-DAG: %[[a4:.*]] = fir.alloca !fir.array<3x3x!fir.logical<4>> {bindc_name = "mask", uniq_name = "_QMtest2Funpack_testEmask"} + ! CHECK-DAG: %[[a5:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "result", uniq_name = "_QMtest2Funpack_testEresult"} + ! CHECK-DAG: %[[a6:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = "vector", uniq_name = "_QMtest2Funpack_testEvector"} + ! CHECK: %[[a7:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK-NEXT: %[[a8:.*]] = fir.array_load %[[a5]](%[[a7]]) : (!fir.ref>, !fir.shape<2>) -> !fir.array<3x3xi32> + ! CHECK: %[[a9:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> + ! CHECK: %[[a10:.*]] = fir.embox %[[a6]](%[[a9]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[a11:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[a12:.*]] = fir.embox %[[a4]](%[[a11]]) : (!fir.ref>>, !fir.shape<2>) -> !fir.box>> + ! CHECK: %[[a13:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK-NEXT: %[[a14:.*]] = fir.embox %[[a3]](%[[a13]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> + ! CHECK: %[[a15:.*]] = fir.zero_bits !fir.heap> + ! CHECK: %[[a16:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[a17:.*]] = fir.embox %[[a15]](%[[a16]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> + ! CHECK-NEXT: fir.store %[[a17]] to %[[a2]] : !fir.ref>>> + ! CHECK-DAG: %[[a19:.*]] = fir.convert %[[a2]] : (!fir.ref>>>) -> !fir.ref> + ! CHECK-DAG: %[[a20:.*]] = fir.convert %[[a10]] : (!fir.box>) -> !fir.box + ! CHECK-DAG: %[[a21:.*]] = fir.convert %[[a12]] : (!fir.box>>) -> !fir.box + ! CHECK-DAG: %[[a22:.*]] = fir.convert %[[a14]] : (!fir.box>) -> !fir.box + ! CHECK: fir.call @_FortranAUnpack(%[[a19]], %[[a20]], %[[a21]], %[[a22]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, !fir.box, !fir.ref, i32) -> none + ! CHECK-NEXT: %[[a22:.*]] = fir.load %{{.*}} : !fir.ref>>> + ! CHECK: %[[a25:.*]] = fir.box_addr %[[a22]] : (!fir.box>>) -> !fir.heap> + ! CHECK: fir.freemem %[[a25]] + ! CHECK: %[[a36:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[a38:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> + ! CHECK-NEXT: %[[a39:.*]] = fir.embox %[[a6]](%[[a38]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[a40:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK-NEXT: %[[a41:.*]] = fir.embox %[[a4]](%[[a40]]) : (!fir.ref>>, !fir.shape<2>) -> !fir.box>> + ! CHECK: %[[a42:.*]] = fir.embox %[[a1]] : (!fir.ref) -> !fir.box + ! CHECK: %[[a43:.*]] = fir.zero_bits !fir.heap> + ! CHECK: %[[a44:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> + ! CHECK: %[[a45:.*]] = fir.embox %[[a43]](%[[a44]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> + ! CHECK-NEXT: fir.store %[[a45]] to %[[a0]] : !fir.ref>>> + ! CHECK: %[[a47:.*]] = fir.convert %[[a0]] : (!fir.ref>>>) -> !fir.ref> + ! CHECK: %[[a48:.*]] = fir.convert %[[a39]] : (!fir.box>) -> !fir.box + ! CHECK: %[[a49:.*]] = fir.convert %[[a41]] : (!fir.box>>) -> !fir.box + ! CHECK: %[[a50:.*]] = fir.convert %[[a42]] : (!fir.box) -> !fir.box + result = unpack(vector, mask, 343) + ! CHECK: fir.call @_FortranAUnpack(%[[a47]], %[[a48]], %[[a49]], %[[a50]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, !fir.box, !fir.ref, i32) -> none + ! CHECK: %[[a53:.*]] = fir.load %[[a0]] : !fir.ref>>> + ! CHECK: %[[a56:.*]] = fir.box_addr %[[a53]] : (!fir.box>>) -> !fir.heap> + ! CHECK: fir.freemem %[[a56]] + ! CHECK-NEXT: return +end subroutine unpack_test + +end module diff --git a/flang/test/Lower/vector-subscript-io.f90 b/flang/test/Lower/vector-subscript-io.f90 index 76b617cfac72a..e0ac93efbfab7 100644 --- a/flang/test/Lower/vector-subscript-io.f90 +++ b/flang/test/Lower/vector-subscript-io.f90 @@ -5,578 +5,578 @@ ! CHECK-LABEL: func @_QPsimple( ! CHECK-SAME: %[[VAL_20:.*]]: !fir.ref>{{.*}}, %[[VAL_16:.*]]: !fir.ref>{{.*}}) { subroutine simple(x, y) - integer :: y(3) - integer :: x(10) - read(*,*) x(y) - ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 10 : index - ! CHECK-DAG: %[[VAL_1:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 4 : i32 - ! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_7:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_1]], %[[VAL_8]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_11:.*]] = fir.slice %[[VAL_6]], %[[VAL_4]], %[[VAL_6]] : (index, index, index) -> !fir.slice<1> - ! CHECK: cf.br ^bb1(%[[VAL_5]], %[[VAL_4]] : index, index) - ! CHECK: ^bb1(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index): - ! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_5]] : index - ! CHECK: cf.cond_br %[[VAL_14]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_16]], %[[VAL_12]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_15]] : !fir.ref - ! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index - ! CHECK: %[[VAL_19:.*]] = fir.array_coor %[[VAL_20]](%[[VAL_10]]) {{\[}}%[[VAL_11]]] %[[VAL_18]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref - ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_9]], %[[VAL_21]], %[[VAL_3]]) : (!fir.ref, !fir.ref, i32) -> i1 - ! CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_12]], %[[VAL_6]] : index - ! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_13]], %[[VAL_6]] : index - ! CHECK: cf.br ^bb1(%[[VAL_23]], %[[VAL_24]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_25:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_9]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPonly_once( - ! CHECK-SAME: %[[VAL_51:.*]]: !fir.box>{{.*}}) { - subroutine only_once(x) - interface - function get_vector() - integer, allocatable :: get_vector(:) - end function - integer function get_substcript() - end function - end interface - real :: x(:, :) - ! Test subscripts are only evaluated once. - read(*,*) x(get_substcript(), get_vector()) - ! CHECK-DAG: %[[VAL_26:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_28:.*]] = arith.constant 0 : i64 - ! CHECK-DAG: %[[VAL_29:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_30:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_31:.*]] = fir.alloca !fir.box>> {bindc_name = ".result"} - ! CHECK: %[[VAL_32:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_34:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_26]], %[[VAL_33]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_35:.*]] = fir.call @_QPget_substcript() : () -> i32 - ! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> i64 - ! CHECK: %[[VAL_37:.*]] = fir.call @_QPget_vector() : () -> !fir.box>> - ! CHECK: fir.save_result %[[VAL_37]] to %[[VAL_31]] : !fir.box>>, !fir.ref>>> - ! CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_31]] : !fir.ref>>> - ! CHECK: %[[VAL_39:.*]]:3 = fir.box_dims %[[VAL_38]], %[[VAL_29]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[VAL_40:.*]] = fir.box_addr %[[VAL_38]] : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[VAL_41:.*]] = fir.undefined index - ! CHECK: %[[VAL_42:.*]] = fir.slice %[[VAL_36]], %[[VAL_41]], %[[VAL_41]], %[[VAL_30]], %[[VAL_39]]#1, %[[VAL_30]] : (i64, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: cf.br ^bb1(%[[VAL_29]], %[[VAL_39]]#1 : index, index) - ! CHECK: ^bb1(%[[VAL_43:.*]]: index, %[[VAL_44:.*]]: index): - ! CHECK: %[[VAL_45:.*]] = arith.cmpi sgt, %[[VAL_44]], %[[VAL_29]] : index - ! CHECK: cf.cond_br %[[VAL_45]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_35]] : (i32) -> index - ! CHECK: %[[VAL_47:.*]] = fir.coordinate_of %[[VAL_40]], %[[VAL_43]] : (!fir.heap>, index) -> !fir.ref - ! CHECK: %[[VAL_48:.*]] = fir.load %[[VAL_47]] : !fir.ref - ! CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_48]] : (i32) -> index - ! CHECK: %[[VAL_50:.*]] = fir.array_coor %[[VAL_51]] {{\[}}%[[VAL_42]]] %[[VAL_46]], %[[VAL_49]] : (!fir.box>, !fir.slice<2>, index, index) -> !fir.ref - ! CHECK: %[[VAL_52:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_34]], %[[VAL_50]]) : (!fir.ref, !fir.ref) -> i1 - ! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_43]], %[[VAL_30]] : index - ! CHECK: %[[VAL_54:.*]] = arith.subi %[[VAL_44]], %[[VAL_30]] : index - ! CHECK: cf.br ^bb1(%[[VAL_53]], %[[VAL_54]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_55:.*]] = fir.load %[[VAL_31]] : !fir.ref>>> - ! CHECK: %[[VAL_56:.*]] = fir.box_addr %[[VAL_55]] : (!fir.box>>) -> !fir.heap> - ! CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_56]] : (!fir.heap>) -> i64 - ! CHECK: %[[VAL_58:.*]] = arith.cmpi ne, %[[VAL_57]], %[[VAL_28]] : i64 - ! CHECK: cf.cond_br %[[VAL_58]], ^bb4, ^bb5 - ! CHECK: ^bb4: - ! CHECK: fir.freemem %[[VAL_56]] - ! CHECK: cf.br ^bb5 - ! CHECK: ^bb5: - ! CHECK: %[[VAL_59:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_34]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPwith_assumed_shapes( - ! CHECK-SAME: %[[VAL_78:.*]]: !fir.box>{{.*}}, %[[VAL_69:.*]]: !fir.box>{{.*}}) { - subroutine with_assumed_shapes(x, y) - integer :: y(:) - integer :: x(:) - read(*,*) x(y) - ! CHECK-DAG: %[[VAL_60:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_62:.*]] = arith.constant 4 : i32 - ! CHECK-DAG: %[[VAL_63:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_64:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_65:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_66:.*]] = fir.convert %[[VAL_65]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_67:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_60]], %[[VAL_66]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_68:.*]]:3 = fir.box_dims %[[VAL_69]], %[[VAL_63]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_70:.*]] = fir.slice %[[VAL_64]], %[[VAL_68]]#1, %[[VAL_64]] : (index, index, index) -> !fir.slice<1> - ! CHECK: cf.br ^bb1(%[[VAL_63]], %[[VAL_68]]#1 : index, index) - ! CHECK: ^bb1(%[[VAL_71:.*]]: index, %[[VAL_72:.*]]: index): - ! CHECK: %[[VAL_73:.*]] = arith.cmpi sgt, %[[VAL_72]], %[[VAL_63]] : index - ! CHECK: cf.cond_br %[[VAL_73]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_74:.*]] = fir.coordinate_of %[[VAL_69]], %[[VAL_71]] : (!fir.box>, index) -> !fir.ref - ! CHECK: %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref - ! CHECK: %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (i32) -> index - ! CHECK: %[[VAL_77:.*]] = fir.array_coor %[[VAL_78]] {{\[}}%[[VAL_70]]] %[[VAL_76]] : (!fir.box>, !fir.slice<1>, index) -> !fir.ref - ! CHECK: %[[VAL_79:.*]] = fir.convert %[[VAL_77]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[VAL_80:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_67]], %[[VAL_79]], %[[VAL_62]]) : (!fir.ref, !fir.ref, i32) -> i1 - ! CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_71]], %[[VAL_64]] : index - ! CHECK: %[[VAL_82:.*]] = arith.subi %[[VAL_72]], %[[VAL_64]] : index - ! CHECK: cf.br ^bb1(%[[VAL_81]], %[[VAL_82]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_83:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_67]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPlower_bounds( - ! CHECK-SAME: %[[VAL_108:.*]]: !fir.ref>{{.*}}, %[[VAL_104:.*]]: !fir.ref>{{.*}}) { - subroutine lower_bounds(x, y) - integer :: y(3) - integer :: x(2:5,3:8) - read(*,*) x(3, y) - ! CHECK-DAG: %[[VAL_84:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_85:.*]] = arith.constant 6 : index - ! CHECK-DAG: %[[VAL_86:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_88:.*]] = arith.constant 3 : i64 - ! CHECK-DAG: %[[VAL_89:.*]] = arith.constant 2 : index - ! CHECK-DAG: %[[VAL_90:.*]] = arith.constant 4 : i32 - ! CHECK-DAG: %[[VAL_91:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_92:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_93:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_94:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_95:.*]] = fir.convert %[[VAL_94]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_96:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_86]], %[[VAL_95]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_97:.*]] = fir.shape_shift %[[VAL_89]], %[[VAL_84]], %[[VAL_91]], %[[VAL_85]] : (index, index, index, index) -> !fir.shapeshift<2> - ! CHECK: %[[VAL_98:.*]] = fir.undefined index - ! CHECK: %[[VAL_99:.*]] = fir.slice %[[VAL_88]], %[[VAL_98]], %[[VAL_98]], %[[VAL_93]], %[[VAL_91]], %[[VAL_93]] : (i64, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: cf.br ^bb1(%[[VAL_92]], %[[VAL_91]] : index, index) - ! CHECK: ^bb1(%[[VAL_100:.*]]: index, %[[VAL_101:.*]]: index): - ! CHECK: %[[VAL_102:.*]] = arith.cmpi sgt, %[[VAL_101]], %[[VAL_92]] : index - ! CHECK: cf.cond_br %[[VAL_102]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_103:.*]] = fir.coordinate_of %[[VAL_104]], %[[VAL_100]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_105:.*]] = fir.load %[[VAL_103]] : !fir.ref - ! CHECK: %[[VAL_106:.*]] = fir.convert %[[VAL_105]] : (i32) -> index - ! CHECK: %[[VAL_107:.*]] = fir.array_coor %[[VAL_108]](%[[VAL_97]]) {{\[}}%[[VAL_99]]] %[[VAL_91]], %[[VAL_106]] : (!fir.ref>, !fir.shapeshift<2>, !fir.slice<2>, index, index) -> !fir.ref - ! CHECK: %[[VAL_109:.*]] = fir.convert %[[VAL_107]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[VAL_110:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_96]], %[[VAL_109]], %[[VAL_90]]) : (!fir.ref, !fir.ref, i32) -> i1 - ! CHECK: %[[VAL_111:.*]] = arith.addi %[[VAL_100]], %[[VAL_93]] : index - ! CHECK: %[[VAL_112:.*]] = arith.subi %[[VAL_101]], %[[VAL_93]] : index - ! CHECK: cf.br ^bb1(%[[VAL_111]], %[[VAL_112]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_113:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_96]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPtwo_vectors( - ! CHECK-SAME: %[[VAL_140:.*]]: !fir.ref>{{.*}}, %[[VAL_132:.*]]: !fir.ref>{{.*}}, %[[VAL_136:.*]]: !fir.ref>{{.*}}) { - subroutine two_vectors(x, y1, y2) - integer :: y1(3), y2(3) - real :: x(4, 4) - read(*,*) x(y1, y2) - ! CHECK-DAG: %[[VAL_114:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_115:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_117:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_118:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_119:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_120:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_121:.*]] = fir.convert %[[VAL_120]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_122:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_115]], %[[VAL_121]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_123:.*]] = fir.shape %[[VAL_114]], %[[VAL_114]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_124:.*]] = fir.slice %[[VAL_119]], %[[VAL_117]], %[[VAL_119]], %[[VAL_119]], %[[VAL_117]], %[[VAL_119]] : (index, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: cf.br ^bb1(%[[VAL_118]], %[[VAL_117]] : index, index) - ! CHECK: ^bb1(%[[VAL_125:.*]]: index, %[[VAL_126:.*]]: index): - ! CHECK: %[[VAL_127:.*]] = arith.cmpi sgt, %[[VAL_126]], %[[VAL_118]] : index - ! CHECK: cf.cond_br %[[VAL_127]], ^bb2(%[[VAL_118]], %[[VAL_117]] : index, index), ^bb5 - ! CHECK: ^bb2(%[[VAL_128:.*]]: index, %[[VAL_129:.*]]: index): - ! CHECK: %[[VAL_130:.*]] = arith.cmpi sgt, %[[VAL_129]], %[[VAL_118]] : index - ! CHECK: cf.cond_br %[[VAL_130]], ^bb3, ^bb4 - ! CHECK: ^bb3: - ! CHECK: %[[VAL_131:.*]] = fir.coordinate_of %[[VAL_132]], %[[VAL_128]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_133:.*]] = fir.load %[[VAL_131]] : !fir.ref - ! CHECK: %[[VAL_134:.*]] = fir.convert %[[VAL_133]] : (i32) -> index - ! CHECK: %[[VAL_135:.*]] = fir.coordinate_of %[[VAL_136]], %[[VAL_125]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_137:.*]] = fir.load %[[VAL_135]] : !fir.ref - ! CHECK: %[[VAL_138:.*]] = fir.convert %[[VAL_137]] : (i32) -> index - ! CHECK: %[[VAL_139:.*]] = fir.array_coor %[[VAL_140]](%[[VAL_123]]) {{\[}}%[[VAL_124]]] %[[VAL_134]], %[[VAL_138]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref - ! CHECK: %[[VAL_141:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_122]], %[[VAL_139]]) : (!fir.ref, !fir.ref) -> i1 - ! CHECK: %[[VAL_142:.*]] = arith.addi %[[VAL_128]], %[[VAL_119]] : index - ! CHECK: %[[VAL_143:.*]] = arith.subi %[[VAL_129]], %[[VAL_119]] : index - ! CHECK: cf.br ^bb2(%[[VAL_142]], %[[VAL_143]] : index, index) - ! CHECK: ^bb4: - ! CHECK: %[[VAL_144:.*]] = arith.addi %[[VAL_125]], %[[VAL_119]] : index - ! CHECK: %[[VAL_145:.*]] = arith.subi %[[VAL_126]], %[[VAL_119]] : index - ! CHECK: cf.br ^bb1(%[[VAL_144]], %[[VAL_145]] : index, index) - ! CHECK: ^bb5: - ! CHECK: %[[VAL_146:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_122]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPtriplets_and_vector( - ! CHECK-SAME: %[[VAL_170:.*]]: !fir.ref>>{{.*}}, %[[VAL_166:.*]]: !fir.ref>{{.*}}) { - subroutine triplets_and_vector(x, y) - integer :: y(3) - complex :: x(4, 4) - read(*,*) x(1:4:2, y) - ! CHECK-DAG: %[[VAL_147:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_149:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_150:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_151:.*]] = arith.constant 2 : index - ! CHECK-DAG: %[[VAL_152:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_153:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_154:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_155:.*]] = fir.convert %[[VAL_154]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_156:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_147]], %[[VAL_155]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_157:.*]] = fir.shape %[[VAL_149]], %[[VAL_149]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_158:.*]] = fir.slice %[[VAL_153]], %[[VAL_149]], %[[VAL_151]], %[[VAL_153]], %[[VAL_150]], %[[VAL_153]] : (index, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: cf.br ^bb1(%[[VAL_152]], %[[VAL_150]] : index, index) - ! CHECK: ^bb1(%[[VAL_159:.*]]: index, %[[VAL_160:.*]]: index): - ! CHECK: %[[VAL_161:.*]] = arith.cmpi sgt, %[[VAL_160]], %[[VAL_152]] : index - ! CHECK: cf.cond_br %[[VAL_161]], ^bb2(%[[VAL_153]], %[[VAL_151]] : index, index), ^bb5 - ! CHECK: ^bb2(%[[VAL_162:.*]]: index, %[[VAL_163:.*]]: index): - ! CHECK: %[[VAL_164:.*]] = arith.cmpi sgt, %[[VAL_163]], %[[VAL_152]] : index - ! CHECK: cf.cond_br %[[VAL_164]], ^bb3, ^bb4 - ! CHECK: ^bb3: - ! CHECK: %[[VAL_165:.*]] = fir.coordinate_of %[[VAL_166]], %[[VAL_159]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_167:.*]] = fir.load %[[VAL_165]] : !fir.ref - ! CHECK: %[[VAL_168:.*]] = fir.convert %[[VAL_167]] : (i32) -> index - ! CHECK: %[[VAL_169:.*]] = fir.array_coor %[[VAL_170]](%[[VAL_157]]) {{\[}}%[[VAL_158]]] %[[VAL_162]], %[[VAL_168]] : (!fir.ref>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_171:.*]] = fir.convert %[[VAL_169]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_172:.*]] = fir.call @_FortranAioInputComplex32(%[[VAL_156]], %[[VAL_171]]) : (!fir.ref, !fir.ref) -> i1 - ! CHECK: %[[VAL_173:.*]] = arith.addi %[[VAL_162]], %[[VAL_153]] : index - ! CHECK: %[[VAL_174:.*]] = arith.subi %[[VAL_163]], %[[VAL_153]] : index - ! CHECK: cf.br ^bb2(%[[VAL_173]], %[[VAL_174]] : index, index) - ! CHECK: ^bb4: - ! CHECK: %[[VAL_175:.*]] = arith.addi %[[VAL_159]], %[[VAL_153]] : index - ! CHECK: %[[VAL_176:.*]] = arith.subi %[[VAL_160]], %[[VAL_153]] : index - ! CHECK: cf.br ^bb1(%[[VAL_175]], %[[VAL_176]] : index, index) - ! CHECK: ^bb5: - ! CHECK: %[[VAL_177:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_156]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPsimple_char( - ! CHECK-SAME: %[[VAL_185:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_196:.*]]: !fir.ref>{{.*}}) { - subroutine simple_char(x, y) - integer :: y(3) - character(*) :: x(3:8) - read(*,*) x(y) - ! CHECK-DAG: %[[VAL_178:.*]] = arith.constant 6 : index - ! CHECK-DAG: %[[VAL_179:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_181:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_182:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_183:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_184:.*]]:2 = fir.unboxchar %[[VAL_185]] : (!fir.boxchar<1>) -> (!fir.ref>, index) - ! CHECK: %[[VAL_186:.*]] = fir.convert %[[VAL_184]]#0 : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_187:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_188:.*]] = fir.convert %[[VAL_187]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_189:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_179]], %[[VAL_188]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_190:.*]] = fir.shape_shift %[[VAL_181]], %[[VAL_178]] : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[VAL_191:.*]] = fir.slice %[[VAL_183]], %[[VAL_181]], %[[VAL_183]] : (index, index, index) -> !fir.slice<1> - ! CHECK: cf.br ^bb1(%[[VAL_182]], %[[VAL_181]] : index, index) - ! CHECK: ^bb1(%[[VAL_192:.*]]: index, %[[VAL_193:.*]]: index): - ! CHECK: %[[VAL_194:.*]] = arith.cmpi sgt, %[[VAL_193]], %[[VAL_182]] : index - ! CHECK: cf.cond_br %[[VAL_194]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_195:.*]] = fir.coordinate_of %[[VAL_196]], %[[VAL_192]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_197:.*]] = fir.load %[[VAL_195]] : !fir.ref - ! CHECK: %[[VAL_198:.*]] = fir.convert %[[VAL_197]] : (i32) -> index - ! CHECK: %[[VAL_199:.*]] = fir.array_coor %[[VAL_186]](%[[VAL_190]]) {{\[}}%[[VAL_191]]] %[[VAL_198]] typeparams %[[VAL_184]]#1 : (!fir.ref>>, !fir.shapeshift<1>, !fir.slice<1>, index, index) -> !fir.ref> - ! CHECK: %[[VAL_200:.*]] = fir.convert %[[VAL_199]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_201:.*]] = fir.convert %[[VAL_184]]#1 : (index) -> i64 - ! CHECK: %[[VAL_202:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_189]], %[[VAL_200]], %[[VAL_201]]) : (!fir.ref, !fir.ref, i64) -> i1 - ! CHECK: %[[VAL_203:.*]] = arith.addi %[[VAL_192]], %[[VAL_183]] : index - ! CHECK: %[[VAL_204:.*]] = arith.subi %[[VAL_193]], %[[VAL_183]] : index - ! CHECK: cf.br ^bb1(%[[VAL_203]], %[[VAL_204]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_205:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_189]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPsubstring( - ! CHECK-SAME: %[[VAL_229:.*]]: !fir.box>>{{.*}}, %[[VAL_225:.*]]: !fir.ref>{{.*}}, %[[VAL_215:.*]]: !fir.ref{{.*}}, %[[VAL_218:.*]]: !fir.ref{{.*}}) { - subroutine substring(x, y, i, j) - integer :: y(3), i, j - character(*) :: x(:) - read(*,*) x(y)(i:j) - ! CHECK-DAG: %[[VAL_206:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_208:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_209:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_210:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_211:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_212:.*]] = fir.convert %[[VAL_211]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_213:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_206]], %[[VAL_212]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_214:.*]] = fir.load %[[VAL_215]] : !fir.ref - ! CHECK: %[[VAL_216:.*]] = fir.convert %[[VAL_214]] : (i32) -> index - ! CHECK: %[[VAL_217:.*]] = fir.load %[[VAL_218]] : !fir.ref - ! CHECK: %[[VAL_219:.*]] = fir.convert %[[VAL_217]] : (i32) -> index - ! CHECK: %[[VAL_220:.*]] = fir.slice %[[VAL_210]], %[[VAL_208]], %[[VAL_210]] : (index, index, index) -> !fir.slice<1> - ! CHECK: cf.br ^bb1(%[[VAL_209]], %[[VAL_208]] : index, index) - ! CHECK: ^bb1(%[[VAL_221:.*]]: index, %[[VAL_222:.*]]: index): - ! CHECK: %[[VAL_223:.*]] = arith.cmpi sgt, %[[VAL_222]], %[[VAL_209]] : index - ! CHECK: cf.cond_br %[[VAL_223]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_224:.*]] = fir.coordinate_of %[[VAL_225]], %[[VAL_221]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_226:.*]] = fir.load %[[VAL_224]] : !fir.ref - ! CHECK: %[[VAL_227:.*]] = fir.convert %[[VAL_226]] : (i32) -> index - ! CHECK: %[[VAL_228:.*]] = fir.array_coor %[[VAL_229]] {{\[}}%[[VAL_220]]] %[[VAL_227]] : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref> - ! CHECK: %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index - ! CHECK: %[[VAL_231:.*]] = fir.convert %[[VAL_228]] : (!fir.ref>) -> !fir.ref>> - ! CHECK: %[[VAL_232:.*]] = fir.coordinate_of %[[VAL_231]], %[[VAL_230]] : (!fir.ref>>, index) -> !fir.ref> - ! CHECK: %[[VAL_233:.*]] = fir.convert %[[VAL_232]] : (!fir.ref>) -> !fir.ref> - ! CHECK: %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index - ! CHECK: %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index - ! CHECK: %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index - ! CHECK: %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index - ! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_233]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64 - ! CHECK: %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) : (!fir.ref, !fir.ref, i64) -> i1 - ! CHECK: %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] : index - ! CHECK: %[[VAL_242:.*]] = arith.subi %[[VAL_222]], %[[VAL_210]] : index - ! CHECK: cf.br ^bb1(%[[VAL_241]], %[[VAL_242]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_243:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_213]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPcomplex_part( - ! CHECK-SAME: %[[VAL_262:.*]]: !fir.box>>{{.*}}, %[[VAL_253:.*]]: !fir.box>{{.*}}) { - subroutine complex_part(z, y) - integer :: y(:) - complex :: z(:) - read(*,*) z(y)%IM - ! CHECK-DAG: %[[VAL_244:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_246:.*]] = arith.constant 1 : i32 - ! CHECK-DAG: %[[VAL_247:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_248:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_249:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_250:.*]] = fir.convert %[[VAL_249]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_251:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_244]], %[[VAL_250]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_252:.*]]:3 = fir.box_dims %[[VAL_253]], %[[VAL_247]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_254:.*]] = fir.slice %[[VAL_248]], %[[VAL_252]]#1, %[[VAL_248]] path %[[VAL_246]] : (index, index, index, i32) -> !fir.slice<1> - ! CHECK: cf.br ^bb1(%[[VAL_247]], %[[VAL_252]]#1 : index, index) - ! CHECK: ^bb1(%[[VAL_255:.*]]: index, %[[VAL_256:.*]]: index): - ! CHECK: %[[VAL_257:.*]] = arith.cmpi sgt, %[[VAL_256]], %[[VAL_247]] : index - ! CHECK: cf.cond_br %[[VAL_257]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_258:.*]] = fir.coordinate_of %[[VAL_253]], %[[VAL_255]] : (!fir.box>, index) -> !fir.ref - ! CHECK: %[[VAL_259:.*]] = fir.load %[[VAL_258]] : !fir.ref - ! CHECK: %[[VAL_260:.*]] = fir.convert %[[VAL_259]] : (i32) -> index - ! CHECK: %[[VAL_261:.*]] = fir.array_coor %[[VAL_262]] {{\[}}%[[VAL_254]]] %[[VAL_260]] : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref - ! CHECK: %[[VAL_263:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_251]], %[[VAL_261]]) : (!fir.ref, !fir.ref) -> i1 - ! CHECK: %[[VAL_264:.*]] = arith.addi %[[VAL_255]], %[[VAL_248]] : index - ! CHECK: %[[VAL_265:.*]] = arith.subi %[[VAL_256]], %[[VAL_248]] : index - ! CHECK: cf.br ^bb1(%[[VAL_264]], %[[VAL_265]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_266:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_251]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - module derived_types - type t - integer :: i - character(2) :: c - end type - type t2 - type(t) :: a(5,5) - end type - end module - - ! CHECK-LABEL: func @_QPsimple_derived( - ! CHECK-SAME: %[[VAL_287:.*]]: !fir.ref}>>>{{.*}}, %[[VAL_283:.*]]: !fir.ref>{{.*}}) { - subroutine simple_derived(x, y) - use derived_types - integer :: y(4) - type(t) :: x(3:8) - read(*,*) x(y) - ! CHECK-DAG: %[[VAL_267:.*]] = arith.constant 6 : index - ! CHECK-DAG: %[[VAL_268:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_270:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_271:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_272:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_273:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_274:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_275:.*]] = fir.convert %[[VAL_274]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_276:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_268]], %[[VAL_275]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_277:.*]] = fir.shape_shift %[[VAL_270]], %[[VAL_267]] : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[VAL_278:.*]] = fir.slice %[[VAL_273]], %[[VAL_271]], %[[VAL_273]] : (index, index, index) -> !fir.slice<1> - ! CHECK: cf.br ^bb1(%[[VAL_272]], %[[VAL_271]] : index, index) - ! CHECK: ^bb1(%[[VAL_279:.*]]: index, %[[VAL_280:.*]]: index): - ! CHECK: %[[VAL_281:.*]] = arith.cmpi sgt, %[[VAL_280]], %[[VAL_272]] : index - ! CHECK: cf.cond_br %[[VAL_281]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_282:.*]] = fir.coordinate_of %[[VAL_283]], %[[VAL_279]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_284:.*]] = fir.load %[[VAL_282]] : !fir.ref - ! CHECK: %[[VAL_285:.*]] = fir.convert %[[VAL_284]] : (i32) -> index - ! CHECK: %[[VAL_286:.*]] = fir.array_coor %[[VAL_287]](%[[VAL_277]]) {{\[}}%[[VAL_278]]] %[[VAL_285]] : (!fir.ref}>>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref}>> - ! CHECK: %[[VAL_288:.*]] = fir.embox %[[VAL_286]] : (!fir.ref}>>) -> !fir.box}>> - ! CHECK: %[[VAL_289:.*]] = fir.convert %[[VAL_288]] : (!fir.box}>>) -> !fir.box - ! CHECK: %[[VAL_290:.*]] = fir.call @_FortranAioInputDescriptor(%[[VAL_276]], %[[VAL_289]]) : (!fir.ref, !fir.box) -> i1 - ! CHECK: %[[VAL_291:.*]] = arith.addi %[[VAL_279]], %[[VAL_273]] : index - ! CHECK: %[[VAL_292:.*]] = arith.subi %[[VAL_280]], %[[VAL_273]] : index - ! CHECK: cf.br ^bb1(%[[VAL_291]], %[[VAL_292]] : index, index) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_293:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_276]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPwith_path( - ! CHECK-SAME: [[VAL_326:.*]]: !fir.box}>>}>>>{{.*}}, [[VAL_310:.*]]: !fir.box>{{.*}}) { - subroutine with_path(b, i) - use derived_types - type(t2) :: b(4:, 4:, 4:) - integer :: i(:) - read (*, *) b(5, i, 8:9:1)%a(4,5)%i - ! CHECK-DAG: %[[VAL_294:.*]] = arith.constant 4 : index - ! CHECK-DAG: %[[VAL_295:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_297:.*]] = arith.constant 8 : index - ! CHECK-DAG: %[[VAL_298:.*]] = arith.constant 9 : index - ! CHECK-DAG: %[[VAL_299:.*]] = arith.constant 4 : i64 - ! CHECK-DAG: %[[VAL_300:.*]] = arith.constant 5 : i64 - ! CHECK-DAG: %[[VAL_301:.*]] = arith.constant 5 : index - ! CHECK-DAG: %[[VAL_302:.*]] = arith.constant 4 : i32 - ! CHECK-DAG: %[[VAL_303:.*]] = arith.constant 2 : index - ! CHECK-DAG: %[[VAL_304:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_305:.*]] = arith.constant 1 : index - ! CHECK: %[[VAL_306:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_307:.*]] = fir.convert %[[VAL_306]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_308:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_295]], %[[VAL_307]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_309:.*]]:3 = fir.box_dims %[[VAL_310:.*]], %[[VAL_304]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_311:.*]] = fir.field_index a, !fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}> - ! CHECK: %[[VAL_312:.*]] = fir.field_index i, !fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}> - ! CHECK: %[[VAL_313:.*]] = fir.shift %[[VAL_294]], %[[VAL_294]], %[[VAL_294]] : (index, index, index) -> !fir.shift<3> - ! CHECK: %[[VAL_314:.*]] = fir.undefined index - ! CHECK: %[[VAL_315:.*]] = fir.slice %[[VAL_300]], %[[VAL_314]], %[[VAL_314]], %[[VAL_305]], %[[VAL_309]]#1, %[[VAL_305]], %[[VAL_297]], %[[VAL_298]], %[[VAL_305]] path %[[VAL_311]], %[[VAL_299]], %[[VAL_300]], %[[VAL_312]] : (i64, index, index, index, index, index, index, index, index, !fir.field, i64, i64, !fir.field) -> !fir.slice<3> - ! CHECK: cf.br ^bb1(%[[VAL_294]], %[[VAL_303]] : index, index) - ! CHECK: ^bb1(%[[VAL_316:.*]]: index, %[[VAL_317:.*]]: index): - ! CHECK: %[[VAL_318:.*]] = arith.cmpi sgt, %[[VAL_317]], %[[VAL_304]] : index - ! CHECK: cf.cond_br %[[VAL_318]], ^bb2(%[[VAL_304]], %[[VAL_309]]#1 : index, index), ^bb5 - ! CHECK: ^bb2(%[[VAL_319:.*]]: index, %[[VAL_320:.*]]: index): - ! CHECK: %[[VAL_321:.*]] = arith.cmpi sgt, %[[VAL_320]], %[[VAL_304]] : index - ! CHECK: cf.cond_br %[[VAL_321]], ^bb3, ^bb4 - ! CHECK: ^bb3: - ! CHECK: %[[VAL_322:.*]] = fir.coordinate_of %[[VAL_310]], %[[VAL_319]] : (!fir.box>, index) -> !fir.ref - ! CHECK: %[[VAL_323:.*]] = fir.load %[[VAL_322]] : !fir.ref - ! CHECK: %[[VAL_324:.*]] = fir.convert %[[VAL_323]] : (i32) -> index - ! CHECK: %[[VAL_325:.*]] = fir.array_coor %[[VAL_326:.*]](%[[VAL_313]]) {{\[}}%[[VAL_315]]] %[[VAL_301]], %[[VAL_324]], %[[VAL_316]] : (!fir.box}>>}>>>, !fir.shift<3>, !fir.slice<3>, index, index, index) -> !fir.ref - ! CHECK: %[[VAL_327:.*]] = fir.convert %[[VAL_325]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[VAL_328:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_308]], %[[VAL_327]], %[[VAL_302]]) : (!fir.ref, !fir.ref, i32) -> i1 - ! CHECK: %[[VAL_329:.*]] = arith.addi %[[VAL_319]], %[[VAL_305]] : index - ! CHECK: %[[VAL_330:.*]] = arith.subi %[[VAL_320]], %[[VAL_305]] : index - ! CHECK: cf.br ^bb2(%[[VAL_329]], %[[VAL_330]] : index, index) - ! CHECK: ^bb4: - ! CHECK: %[[VAL_331:.*]] = arith.addi %[[VAL_316]], %[[VAL_305]] : index - ! CHECK: %[[VAL_332:.*]] = arith.subi %[[VAL_317]], %[[VAL_305]] : index - ! CHECK: cf.br ^bb1(%[[VAL_331]], %[[VAL_332]] : index, index) - ! CHECK: ^bb5: - ! CHECK: %[[VAL_333:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_308]]) : (!fir.ref) -> i32 - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPsimple_iostat( - ! CHECK-SAME: %[[VAL_357:.*]]: !fir.box>{{.*}}, %[[VAL_346:.*]]: !fir.box>{{.*}}, %[[VAL_361:.*]]: !fir.ref{{.*}}, %[[VAL_364:.*]]: !fir.ref{{.*}}) { - subroutine simple_iostat(x, y, j, stat) - integer :: j, y(:), stat - real :: x(:) - read(*, *, iostat=stat) x(y), j - ! CHECK-DAG: %[[VAL_334:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_336:.*]] = arith.constant false - ! CHECK-DAG: %[[VAL_337:.*]] = arith.constant true - ! CHECK-DAG: %[[VAL_338:.*]] = arith.constant 1 : index - ! CHECK-DAG: %[[VAL_339:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_340:.*]] = arith.constant 4 : i32 - ! CHECK: %[[VAL_341:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_342:.*]] = fir.convert %[[VAL_341]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_343:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_334]], %[[VAL_342]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_344:.*]] = fir.call @_FortranAioEnableHandlers(%[[VAL_343]], %[[VAL_337]], %[[VAL_336]], %[[VAL_336]], %[[VAL_336]], %[[VAL_336]]) : (!fir.ref, i1, i1, i1, i1, i1) -> none - ! CHECK: %[[VAL_345:.*]]:3 = fir.box_dims %[[VAL_346]], %[[VAL_339]] : (!fir.box>, index) -> (index, index, index) - ! CHECK: %[[VAL_347:.*]] = fir.slice %[[VAL_338]], %[[VAL_345]]#1, %[[VAL_338]] : (index, index, index) -> !fir.slice<1> - ! CHECK: %[[VAL_348:.*]] = arith.subi %[[VAL_345]]#1, %[[VAL_338]] : index - ! CHECK: cf.br ^bb1(%[[VAL_339]], %[[VAL_337]] : index, i1) - ! CHECK: ^bb1(%[[VAL_349:.*]]: index, %[[VAL_350:.*]]: i1): - ! CHECK: %[[VAL_351:.*]] = arith.cmpi sle, %[[VAL_349]], %[[VAL_348]] : index - ! CHECK: %[[VAL_352:.*]] = arith.andi %[[VAL_350]], %[[VAL_351]] : i1 - ! CHECK: cf.cond_br %[[VAL_352]], ^bb2, ^bb3 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_353:.*]] = fir.coordinate_of %[[VAL_346]], %[[VAL_349]] : (!fir.box>, index) -> !fir.ref - ! CHECK: %[[VAL_354:.*]] = fir.load %[[VAL_353]] : !fir.ref - ! CHECK: %[[VAL_355:.*]] = fir.convert %[[VAL_354]] : (i32) -> index - ! CHECK: %[[VAL_356:.*]] = fir.array_coor %[[VAL_357]] {{\[}}%[[VAL_347]]] %[[VAL_355]] : (!fir.box>, !fir.slice<1>, index) -> !fir.ref - ! CHECK: %[[VAL_358:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_343]], %[[VAL_356]]) : (!fir.ref, !fir.ref) -> i1 - ! CHECK: %[[VAL_359:.*]] = arith.addi %[[VAL_349]], %[[VAL_338]] : index - ! CHECK: cf.br ^bb1(%[[VAL_359]], %[[VAL_358]] : index, i1) - ! CHECK: ^bb3: - ! CHECK: cf.cond_br %[[VAL_350]], ^bb4, ^bb5 - ! CHECK: ^bb4: - ! CHECK: %[[VAL_360:.*]] = fir.convert %[[VAL_361]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[VAL_362:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_343]], %[[VAL_360]], %[[VAL_340]]) : (!fir.ref, !fir.ref, i32) -> i1 - ! CHECK: cf.br ^bb5 - ! CHECK: ^bb5: - ! CHECK: %[[VAL_363:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_343]]) : (!fir.ref) -> i32 - ! CHECK: fir.store %[[VAL_363]] to %[[VAL_364]] : !fir.ref - ! CHECK: return - end subroutine - - ! CHECK-LABEL: func @_QPiostat_in_io_loop( - ! CHECK-SAME: %[[VAL_400:.*]]: !fir.ref>{{.*}}, %[[VAL_396:.*]]: !fir.ref>{{.*}}, %[[VAL_408:.*]]: !fir.ref{{.*}}) { - subroutine iostat_in_io_loop(k, j, stat) - integer :: k(3, 5) - integer :: j(3) - integer :: stat - read(*, *, iostat=stat) (k(i, j), i=1,3,1) - ! CHECK-DAG: %[[VAL_365:.*]] = arith.constant 5 : index - ! CHECK-DAG: %[[VAL_366:.*]] = arith.constant -1 : i32 - ! CHECK-DAG: %[[VAL_368:.*]] = arith.constant 3 : index - ! CHECK-DAG: %[[VAL_369:.*]] = arith.constant true - ! CHECK-DAG: %[[VAL_370:.*]] = arith.constant false - ! CHECK-DAG: %[[VAL_371:.*]] = arith.constant 1 : index - ! CHECK-DAG: %[[VAL_372:.*]] = arith.constant 0 : index - ! CHECK-DAG: %[[VAL_373:.*]] = arith.constant 2 : index - ! CHECK-DAG: %[[VAL_374:.*]] = arith.constant 4 : i32 - ! CHECK: %[[VAL_375:.*]] = fir.alloca i32 - ! CHECK: %[[VAL_376:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> - ! CHECK: %[[VAL_377:.*]] = fir.convert %[[VAL_376]] : (!fir.ref>) -> !fir.ref - ! CHECK: %[[VAL_378:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_366]], %[[VAL_377]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[VAL_379:.*]] = fir.call @_FortranAioEnableHandlers(%[[VAL_378]], %[[VAL_369]], %[[VAL_370]], %[[VAL_370]], %[[VAL_370]], %[[VAL_370]]) : (!fir.ref, i1, i1, i1, i1, i1) -> none - ! CHECK: cf.br ^bb1(%[[VAL_371]], %[[VAL_369]] : index, i1) - ! CHECK: ^bb1(%[[VAL_380:.*]]: index, %[[VAL_381:.*]]: i1): - ! CHECK: %[[VAL_382:.*]] = arith.cmpi sle, %[[VAL_380]], %[[VAL_368]] : index - ! CHECK: %[[VAL_383:.*]] = arith.andi %[[VAL_381]], %[[VAL_382]] : i1 - ! CHECK: cf.cond_br %[[VAL_383]], ^bb2, ^bb7 - ! CHECK: ^bb2: - ! CHECK: %[[VAL_384:.*]] = fir.convert %[[VAL_380]] : (index) -> i32 - ! CHECK: fir.store %[[VAL_384]] to %[[VAL_375]] : !fir.ref - ! CHECK: cf.cond_br %[[VAL_381]], ^bb3, ^bb6(%[[VAL_370]] : i1) - ! CHECK: ^bb3: - ! CHECK: %[[VAL_385:.*]] = fir.load %[[VAL_375]] : !fir.ref - ! CHECK: %[[VAL_386:.*]] = fir.convert %[[VAL_385]] : (i32) -> i64 - ! CHECK: %[[VAL_387:.*]] = fir.shape %[[VAL_368]], %[[VAL_365]] : (index, index) -> !fir.shape<2> - ! CHECK: %[[VAL_388:.*]] = fir.undefined index - ! CHECK: %[[VAL_389:.*]] = fir.slice %[[VAL_386]], %[[VAL_388]], %[[VAL_388]], %[[VAL_371]], %[[VAL_368]], %[[VAL_371]] : (i64, index, index, index, index, index) -> !fir.slice<2> - ! CHECK: cf.br ^bb4(%[[VAL_372]], %[[VAL_369]] : index, i1) - ! CHECK: ^bb4(%[[VAL_390:.*]]: index, %[[VAL_391:.*]]: i1): - ! CHECK: %[[VAL_392:.*]] = arith.cmpi sle, %[[VAL_390]], %[[VAL_373]] : index - ! CHECK: %[[VAL_393:.*]] = arith.andi %[[VAL_391]], %[[VAL_392]] : i1 - ! CHECK: cf.cond_br %[[VAL_393]], ^bb5, ^bb6(%[[VAL_391]] : i1) - ! CHECK: ^bb5: - ! CHECK: %[[VAL_394:.*]] = fir.convert %[[VAL_385]] : (i32) -> index - ! CHECK: %[[VAL_395:.*]] = fir.coordinate_of %[[VAL_396]], %[[VAL_390]] : (!fir.ref>, index) -> !fir.ref - ! CHECK: %[[VAL_397:.*]] = fir.load %[[VAL_395]] : !fir.ref - ! CHECK: %[[VAL_398:.*]] = fir.convert %[[VAL_397]] : (i32) -> index - ! CHECK: %[[VAL_399:.*]] = fir.array_coor %[[VAL_400]](%[[VAL_387]]) {{\[}}%[[VAL_389]]] %[[VAL_394]], %[[VAL_398]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref - ! CHECK: %[[VAL_401:.*]] = fir.convert %[[VAL_399]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[VAL_402:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_378]], %[[VAL_401]], %[[VAL_374]]) : (!fir.ref, !fir.ref, i32) -> i1 - ! CHECK: %[[VAL_403:.*]] = arith.addi %[[VAL_390]], %[[VAL_371]] : index - ! CHECK: cf.br ^bb4(%[[VAL_403]], %[[VAL_402]] : index, i1) - ! CHECK: ^bb6(%[[VAL_404:.*]]: i1): - ! CHECK: %[[VAL_405:.*]] = arith.addi %[[VAL_380]], %[[VAL_371]] : index - ! CHECK: cf.br ^bb1(%[[VAL_405]], %[[VAL_404]] : index, i1) - ! CHECK: ^bb7: - ! CHECK: %[[VAL_406:.*]] = fir.convert %[[VAL_380]] : (index) -> i32 - ! CHECK: fir.store %[[VAL_406]] to %[[VAL_375]] : !fir.ref - ! CHECK: %[[VAL_407:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_378]]) : (!fir.ref) -> i32 - ! CHECK: fir.store %[[VAL_407]] to %[[VAL_408]] : !fir.ref - ! CHECK: return - end subroutine + integer :: y(3) + integer :: x(10) + read(*,*) x(y) +! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 10 : index +! CHECK-DAG: %[[VAL_1:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 4 : i32 +! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_7:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_1]], %[[VAL_8]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_11:.*]] = fir.slice %[[VAL_6]], %[[VAL_4]], %[[VAL_6]] : (index, index, index) -> !fir.slice<1> +! CHECK: cf.br ^bb1(%[[VAL_5]], %[[VAL_4]] : index, index) +! CHECK: ^bb1(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index): +! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_5]] : index +! CHECK: cf.cond_br %[[VAL_14]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_16]], %[[VAL_12]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_15]] : !fir.ref +! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index +! CHECK: %[[VAL_19:.*]] = fir.array_coor %[[VAL_20]](%[[VAL_10]]) {{\[}}%[[VAL_11]]] %[[VAL_18]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref) -> !fir.ref +! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_9]], %[[VAL_21]], %[[VAL_3]]) : (!fir.ref, !fir.ref, i32) -> i1 +! CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_12]], %[[VAL_6]] : index +! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_13]], %[[VAL_6]] : index +! CHECK: cf.br ^bb1(%[[VAL_23]], %[[VAL_24]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_25:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_9]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPonly_once( +! CHECK-SAME: %[[VAL_51:.*]]: !fir.box>{{.*}}) { +subroutine only_once(x) + interface + function get_vector() + integer, allocatable :: get_vector(:) + end function + integer function get_substcript() + end function + end interface + real :: x(:, :) + ! Test subscripts are only evaluated once. + read(*,*) x(get_substcript(), get_vector()) +! CHECK-DAG: %[[VAL_26:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_28:.*]] = arith.constant 0 : i64 +! CHECK-DAG: %[[VAL_29:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_30:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_31:.*]] = fir.alloca !fir.box>> {bindc_name = ".result"} +! CHECK: %[[VAL_32:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_34:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_26]], %[[VAL_33]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_35:.*]] = fir.call @_QPget_substcript() : () -> i32 +! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> i64 +! CHECK: %[[VAL_37:.*]] = fir.call @_QPget_vector() : () -> !fir.box>> +! CHECK: fir.save_result %[[VAL_37]] to %[[VAL_31]] : !fir.box>>, !fir.ref>>> +! CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_31]] : !fir.ref>>> +! CHECK: %[[VAL_39:.*]]:3 = fir.box_dims %[[VAL_38]], %[[VAL_29]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[VAL_40:.*]] = fir.box_addr %[[VAL_38]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[VAL_41:.*]] = fir.undefined index +! CHECK: %[[VAL_42:.*]] = fir.slice %[[VAL_36]], %[[VAL_41]], %[[VAL_41]], %[[VAL_30]], %[[VAL_39]]#1, %[[VAL_30]] : (i64, index, index, index, index, index) -> !fir.slice<2> +! CHECK: cf.br ^bb1(%[[VAL_29]], %[[VAL_39]]#1 : index, index) +! CHECK: ^bb1(%[[VAL_43:.*]]: index, %[[VAL_44:.*]]: index): +! CHECK: %[[VAL_45:.*]] = arith.cmpi sgt, %[[VAL_44]], %[[VAL_29]] : index +! CHECK: cf.cond_br %[[VAL_45]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_35]] : (i32) -> index +! CHECK: %[[VAL_47:.*]] = fir.coordinate_of %[[VAL_40]], %[[VAL_43]] : (!fir.heap>, index) -> !fir.ref +! CHECK: %[[VAL_48:.*]] = fir.load %[[VAL_47]] : !fir.ref +! CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_48]] : (i32) -> index +! CHECK: %[[VAL_50:.*]] = fir.array_coor %[[VAL_51]] {{\[}}%[[VAL_42]]] %[[VAL_46]], %[[VAL_49]] : (!fir.box>, !fir.slice<2>, index, index) -> !fir.ref +! CHECK: %[[VAL_52:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_34]], %[[VAL_50]]) : (!fir.ref, !fir.ref) -> i1 +! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_43]], %[[VAL_30]] : index +! CHECK: %[[VAL_54:.*]] = arith.subi %[[VAL_44]], %[[VAL_30]] : index +! CHECK: cf.br ^bb1(%[[VAL_53]], %[[VAL_54]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_55:.*]] = fir.load %[[VAL_31]] : !fir.ref>>> +! CHECK: %[[VAL_56:.*]] = fir.box_addr %[[VAL_55]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_56]] : (!fir.heap>) -> i64 +! CHECK: %[[VAL_58:.*]] = arith.cmpi ne, %[[VAL_57]], %[[VAL_28]] : i64 +! CHECK: cf.cond_br %[[VAL_58]], ^bb4, ^bb5 +! CHECK: ^bb4: +! CHECK: fir.freemem %[[VAL_56]] +! CHECK: cf.br ^bb5 +! CHECK: ^bb5: +! CHECK: %[[VAL_59:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_34]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPwith_assumed_shapes( +! CHECK-SAME: %[[VAL_78:.*]]: !fir.box>{{.*}}, %[[VAL_69:.*]]: !fir.box>{{.*}}) { +subroutine with_assumed_shapes(x, y) + integer :: y(:) + integer :: x(:) + read(*,*) x(y) +! CHECK-DAG: %[[VAL_60:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_62:.*]] = arith.constant 4 : i32 +! CHECK-DAG: %[[VAL_63:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_64:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_65:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_66:.*]] = fir.convert %[[VAL_65]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_67:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_60]], %[[VAL_66]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_68:.*]]:3 = fir.box_dims %[[VAL_69]], %[[VAL_63]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_70:.*]] = fir.slice %[[VAL_64]], %[[VAL_68]]#1, %[[VAL_64]] : (index, index, index) -> !fir.slice<1> +! CHECK: cf.br ^bb1(%[[VAL_63]], %[[VAL_68]]#1 : index, index) +! CHECK: ^bb1(%[[VAL_71:.*]]: index, %[[VAL_72:.*]]: index): +! CHECK: %[[VAL_73:.*]] = arith.cmpi sgt, %[[VAL_72]], %[[VAL_63]] : index +! CHECK: cf.cond_br %[[VAL_73]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_74:.*]] = fir.coordinate_of %[[VAL_69]], %[[VAL_71]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref +! CHECK: %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (i32) -> index +! CHECK: %[[VAL_77:.*]] = fir.array_coor %[[VAL_78]] {{\[}}%[[VAL_70]]] %[[VAL_76]] : (!fir.box>, !fir.slice<1>, index) -> !fir.ref +! CHECK: %[[VAL_79:.*]] = fir.convert %[[VAL_77]] : (!fir.ref) -> !fir.ref +! CHECK: %[[VAL_80:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_67]], %[[VAL_79]], %[[VAL_62]]) : (!fir.ref, !fir.ref, i32) -> i1 +! CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_71]], %[[VAL_64]] : index +! CHECK: %[[VAL_82:.*]] = arith.subi %[[VAL_72]], %[[VAL_64]] : index +! CHECK: cf.br ^bb1(%[[VAL_81]], %[[VAL_82]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_83:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_67]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPlower_bounds( +! CHECK-SAME: %[[VAL_108:.*]]: !fir.ref>{{.*}}, %[[VAL_104:.*]]: !fir.ref>{{.*}}) { +subroutine lower_bounds(x, y) + integer :: y(3) + integer :: x(2:5,3:8) + read(*,*) x(3, y) +! CHECK-DAG: %[[VAL_84:.*]] = arith.constant 4 : index +! CHECK-DAG: %[[VAL_85:.*]] = arith.constant 6 : index +! CHECK-DAG: %[[VAL_86:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_88:.*]] = arith.constant 3 : i64 +! CHECK-DAG: %[[VAL_89:.*]] = arith.constant 2 : index +! CHECK-DAG: %[[VAL_90:.*]] = arith.constant 4 : i32 +! CHECK-DAG: %[[VAL_91:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_92:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_93:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_94:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_95:.*]] = fir.convert %[[VAL_94]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_96:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_86]], %[[VAL_95]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_97:.*]] = fir.shape_shift %[[VAL_89]], %[[VAL_84]], %[[VAL_91]], %[[VAL_85]] : (index, index, index, index) -> !fir.shapeshift<2> +! CHECK: %[[VAL_98:.*]] = fir.undefined index +! CHECK: %[[VAL_99:.*]] = fir.slice %[[VAL_88]], %[[VAL_98]], %[[VAL_98]], %[[VAL_93]], %[[VAL_91]], %[[VAL_93]] : (i64, index, index, index, index, index) -> !fir.slice<2> +! CHECK: cf.br ^bb1(%[[VAL_92]], %[[VAL_91]] : index, index) +! CHECK: ^bb1(%[[VAL_100:.*]]: index, %[[VAL_101:.*]]: index): +! CHECK: %[[VAL_102:.*]] = arith.cmpi sgt, %[[VAL_101]], %[[VAL_92]] : index +! CHECK: cf.cond_br %[[VAL_102]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_103:.*]] = fir.coordinate_of %[[VAL_104]], %[[VAL_100]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_105:.*]] = fir.load %[[VAL_103]] : !fir.ref +! CHECK: %[[VAL_106:.*]] = fir.convert %[[VAL_105]] : (i32) -> index +! CHECK: %[[VAL_107:.*]] = fir.array_coor %[[VAL_108]](%[[VAL_97]]) {{\[}}%[[VAL_99]]] %[[VAL_91]], %[[VAL_106]] : (!fir.ref>, !fir.shapeshift<2>, !fir.slice<2>, index, index) -> !fir.ref +! CHECK: %[[VAL_109:.*]] = fir.convert %[[VAL_107]] : (!fir.ref) -> !fir.ref +! CHECK: %[[VAL_110:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_96]], %[[VAL_109]], %[[VAL_90]]) : (!fir.ref, !fir.ref, i32) -> i1 +! CHECK: %[[VAL_111:.*]] = arith.addi %[[VAL_100]], %[[VAL_93]] : index +! CHECK: %[[VAL_112:.*]] = arith.subi %[[VAL_101]], %[[VAL_93]] : index +! CHECK: cf.br ^bb1(%[[VAL_111]], %[[VAL_112]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_113:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_96]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPtwo_vectors( +! CHECK-SAME: %[[VAL_140:.*]]: !fir.ref>{{.*}}, %[[VAL_132:.*]]: !fir.ref>{{.*}}, %[[VAL_136:.*]]: !fir.ref>{{.*}}) { +subroutine two_vectors(x, y1, y2) + integer :: y1(3), y2(3) + real :: x(4, 4) + read(*,*) x(y1, y2) +! CHECK-DAG: %[[VAL_114:.*]] = arith.constant 4 : index +! CHECK-DAG: %[[VAL_115:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_117:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_118:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_119:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_120:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_121:.*]] = fir.convert %[[VAL_120]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_122:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_115]], %[[VAL_121]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_123:.*]] = fir.shape %[[VAL_114]], %[[VAL_114]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_124:.*]] = fir.slice %[[VAL_119]], %[[VAL_117]], %[[VAL_119]], %[[VAL_119]], %[[VAL_117]], %[[VAL_119]] : (index, index, index, index, index, index) -> !fir.slice<2> +! CHECK: cf.br ^bb1(%[[VAL_118]], %[[VAL_117]] : index, index) +! CHECK: ^bb1(%[[VAL_125:.*]]: index, %[[VAL_126:.*]]: index): +! CHECK: %[[VAL_127:.*]] = arith.cmpi sgt, %[[VAL_126]], %[[VAL_118]] : index +! CHECK: cf.cond_br %[[VAL_127]], ^bb2(%[[VAL_118]], %[[VAL_117]] : index, index), ^bb5 +! CHECK: ^bb2(%[[VAL_128:.*]]: index, %[[VAL_129:.*]]: index): +! CHECK: %[[VAL_130:.*]] = arith.cmpi sgt, %[[VAL_129]], %[[VAL_118]] : index +! CHECK: cf.cond_br %[[VAL_130]], ^bb3, ^bb4 +! CHECK: ^bb3: +! CHECK: %[[VAL_131:.*]] = fir.coordinate_of %[[VAL_132]], %[[VAL_128]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_133:.*]] = fir.load %[[VAL_131]] : !fir.ref +! CHECK: %[[VAL_134:.*]] = fir.convert %[[VAL_133]] : (i32) -> index +! CHECK: %[[VAL_135:.*]] = fir.coordinate_of %[[VAL_136]], %[[VAL_125]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_137:.*]] = fir.load %[[VAL_135]] : !fir.ref +! CHECK: %[[VAL_138:.*]] = fir.convert %[[VAL_137]] : (i32) -> index +! CHECK: %[[VAL_139:.*]] = fir.array_coor %[[VAL_140]](%[[VAL_123]]) {{\[}}%[[VAL_124]]] %[[VAL_134]], %[[VAL_138]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref +! CHECK: %[[VAL_141:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_122]], %[[VAL_139]]) : (!fir.ref, !fir.ref) -> i1 +! CHECK: %[[VAL_142:.*]] = arith.addi %[[VAL_128]], %[[VAL_119]] : index +! CHECK: %[[VAL_143:.*]] = arith.subi %[[VAL_129]], %[[VAL_119]] : index +! CHECK: cf.br ^bb2(%[[VAL_142]], %[[VAL_143]] : index, index) +! CHECK: ^bb4: +! CHECK: %[[VAL_144:.*]] = arith.addi %[[VAL_125]], %[[VAL_119]] : index +! CHECK: %[[VAL_145:.*]] = arith.subi %[[VAL_126]], %[[VAL_119]] : index +! CHECK: cf.br ^bb1(%[[VAL_144]], %[[VAL_145]] : index, index) +! CHECK: ^bb5: +! CHECK: %[[VAL_146:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_122]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPtriplets_and_vector( +! CHECK-SAME: %[[VAL_170:.*]]: !fir.ref>>{{.*}}, %[[VAL_166:.*]]: !fir.ref>{{.*}}) { +subroutine triplets_and_vector(x, y) + integer :: y(3) + complex :: x(4, 4) + read(*,*) x(1:4:2, y) +! CHECK-DAG: %[[VAL_147:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_149:.*]] = arith.constant 4 : index +! CHECK-DAG: %[[VAL_150:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_151:.*]] = arith.constant 2 : index +! CHECK-DAG: %[[VAL_152:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_153:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_154:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_155:.*]] = fir.convert %[[VAL_154]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_156:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_147]], %[[VAL_155]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_157:.*]] = fir.shape %[[VAL_149]], %[[VAL_149]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_158:.*]] = fir.slice %[[VAL_153]], %[[VAL_149]], %[[VAL_151]], %[[VAL_153]], %[[VAL_150]], %[[VAL_153]] : (index, index, index, index, index, index) -> !fir.slice<2> +! CHECK: cf.br ^bb1(%[[VAL_152]], %[[VAL_150]] : index, index) +! CHECK: ^bb1(%[[VAL_159:.*]]: index, %[[VAL_160:.*]]: index): +! CHECK: %[[VAL_161:.*]] = arith.cmpi sgt, %[[VAL_160]], %[[VAL_152]] : index +! CHECK: cf.cond_br %[[VAL_161]], ^bb2(%[[VAL_153]], %[[VAL_151]] : index, index), ^bb5 +! CHECK: ^bb2(%[[VAL_162:.*]]: index, %[[VAL_163:.*]]: index): +! CHECK: %[[VAL_164:.*]] = arith.cmpi sgt, %[[VAL_163]], %[[VAL_152]] : index +! CHECK: cf.cond_br %[[VAL_164]], ^bb3, ^bb4 +! CHECK: ^bb3: +! CHECK: %[[VAL_165:.*]] = fir.coordinate_of %[[VAL_166]], %[[VAL_159]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_167:.*]] = fir.load %[[VAL_165]] : !fir.ref +! CHECK: %[[VAL_168:.*]] = fir.convert %[[VAL_167]] : (i32) -> index +! CHECK: %[[VAL_169:.*]] = fir.array_coor %[[VAL_170]](%[[VAL_157]]) {{\[}}%[[VAL_158]]] %[[VAL_162]], %[[VAL_168]] : (!fir.ref>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref> +! CHECK: %[[VAL_171:.*]] = fir.convert %[[VAL_169]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_172:.*]] = fir.call @_FortranAioInputComplex32(%[[VAL_156]], %[[VAL_171]]) : (!fir.ref, !fir.ref) -> i1 +! CHECK: %[[VAL_173:.*]] = arith.addi %[[VAL_162]], %[[VAL_153]] : index +! CHECK: %[[VAL_174:.*]] = arith.subi %[[VAL_163]], %[[VAL_153]] : index +! CHECK: cf.br ^bb2(%[[VAL_173]], %[[VAL_174]] : index, index) +! CHECK: ^bb4: +! CHECK: %[[VAL_175:.*]] = arith.addi %[[VAL_159]], %[[VAL_153]] : index +! CHECK: %[[VAL_176:.*]] = arith.subi %[[VAL_160]], %[[VAL_153]] : index +! CHECK: cf.br ^bb1(%[[VAL_175]], %[[VAL_176]] : index, index) +! CHECK: ^bb5: +! CHECK: %[[VAL_177:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_156]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPsimple_char( +! CHECK-SAME: %[[VAL_185:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_196:.*]]: !fir.ref>{{.*}}) { +subroutine simple_char(x, y) + integer :: y(3) + character(*) :: x(3:8) + read(*,*) x(y) +! CHECK-DAG: %[[VAL_178:.*]] = arith.constant 6 : index +! CHECK-DAG: %[[VAL_179:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_181:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_182:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_183:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_184:.*]]:2 = fir.unboxchar %[[VAL_185]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_186:.*]] = fir.convert %[[VAL_184]]#0 : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_187:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_188:.*]] = fir.convert %[[VAL_187]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_189:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_179]], %[[VAL_188]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_190:.*]] = fir.shape_shift %[[VAL_181]], %[[VAL_178]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_191:.*]] = fir.slice %[[VAL_183]], %[[VAL_181]], %[[VAL_183]] : (index, index, index) -> !fir.slice<1> +! CHECK: cf.br ^bb1(%[[VAL_182]], %[[VAL_181]] : index, index) +! CHECK: ^bb1(%[[VAL_192:.*]]: index, %[[VAL_193:.*]]: index): +! CHECK: %[[VAL_194:.*]] = arith.cmpi sgt, %[[VAL_193]], %[[VAL_182]] : index +! CHECK: cf.cond_br %[[VAL_194]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_195:.*]] = fir.coordinate_of %[[VAL_196]], %[[VAL_192]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_197:.*]] = fir.load %[[VAL_195]] : !fir.ref +! CHECK: %[[VAL_198:.*]] = fir.convert %[[VAL_197]] : (i32) -> index +! CHECK: %[[VAL_199:.*]] = fir.array_coor %[[VAL_186]](%[[VAL_190]]) {{\[}}%[[VAL_191]]] %[[VAL_198]] typeparams %[[VAL_184]]#1 : (!fir.ref>>, !fir.shapeshift<1>, !fir.slice<1>, index, index) -> !fir.ref> +! CHECK: %[[VAL_200:.*]] = fir.convert %[[VAL_199]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_201:.*]] = fir.convert %[[VAL_184]]#1 : (index) -> i64 +! CHECK: %[[VAL_202:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_189]], %[[VAL_200]], %[[VAL_201]]) : (!fir.ref, !fir.ref, i64) -> i1 +! CHECK: %[[VAL_203:.*]] = arith.addi %[[VAL_192]], %[[VAL_183]] : index +! CHECK: %[[VAL_204:.*]] = arith.subi %[[VAL_193]], %[[VAL_183]] : index +! CHECK: cf.br ^bb1(%[[VAL_203]], %[[VAL_204]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_205:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_189]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPsubstring( +! CHECK-SAME: %[[VAL_229:.*]]: !fir.box>>{{.*}}, %[[VAL_225:.*]]: !fir.ref>{{.*}}, %[[VAL_215:.*]]: !fir.ref{{.*}}, %[[VAL_218:.*]]: !fir.ref{{.*}}) { +subroutine substring(x, y, i, j) + integer :: y(3), i, j + character(*) :: x(:) + read(*,*) x(y)(i:j) +! CHECK-DAG: %[[VAL_206:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_208:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_209:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_210:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_211:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_212:.*]] = fir.convert %[[VAL_211]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_213:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_206]], %[[VAL_212]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_214:.*]] = fir.load %[[VAL_215]] : !fir.ref +! CHECK: %[[VAL_216:.*]] = fir.convert %[[VAL_214]] : (i32) -> index +! CHECK: %[[VAL_217:.*]] = fir.load %[[VAL_218]] : !fir.ref +! CHECK: %[[VAL_219:.*]] = fir.convert %[[VAL_217]] : (i32) -> index +! CHECK: %[[VAL_220:.*]] = fir.slice %[[VAL_210]], %[[VAL_208]], %[[VAL_210]] : (index, index, index) -> !fir.slice<1> +! CHECK: cf.br ^bb1(%[[VAL_209]], %[[VAL_208]] : index, index) +! CHECK: ^bb1(%[[VAL_221:.*]]: index, %[[VAL_222:.*]]: index): +! CHECK: %[[VAL_223:.*]] = arith.cmpi sgt, %[[VAL_222]], %[[VAL_209]] : index +! CHECK: cf.cond_br %[[VAL_223]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_224:.*]] = fir.coordinate_of %[[VAL_225]], %[[VAL_221]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_226:.*]] = fir.load %[[VAL_224]] : !fir.ref +! CHECK: %[[VAL_227:.*]] = fir.convert %[[VAL_226]] : (i32) -> index +! CHECK: %[[VAL_228:.*]] = fir.array_coor %[[VAL_229]] {{\[}}%[[VAL_220]]] %[[VAL_227]] : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref> +! CHECK: %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index +! CHECK: %[[VAL_231:.*]] = fir.convert %[[VAL_228]] : (!fir.ref>) -> !fir.ref>> +! CHECK: %[[VAL_232:.*]] = fir.coordinate_of %[[VAL_231]], %[[VAL_230]] : (!fir.ref>>, index) -> !fir.ref> +! CHECK: %[[VAL_233:.*]] = fir.convert %[[VAL_232]] : (!fir.ref>) -> !fir.ref> +! CHECK: %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index +! CHECK: %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index +! CHECK: %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index +! CHECK: %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index +! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_233]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64 +! CHECK: %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) : (!fir.ref, !fir.ref, i64) -> i1 +! CHECK: %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] : index +! CHECK: %[[VAL_242:.*]] = arith.subi %[[VAL_222]], %[[VAL_210]] : index +! CHECK: cf.br ^bb1(%[[VAL_241]], %[[VAL_242]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_243:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_213]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPcomplex_part( +! CHECK-SAME: %[[VAL_262:.*]]: !fir.box>>{{.*}}, %[[VAL_253:.*]]: !fir.box>{{.*}}) { +subroutine complex_part(z, y) + integer :: y(:) + complex :: z(:) + read(*,*) z(y)%IM +! CHECK-DAG: %[[VAL_244:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_246:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[VAL_247:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_248:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_249:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_250:.*]] = fir.convert %[[VAL_249]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_251:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_244]], %[[VAL_250]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_252:.*]]:3 = fir.box_dims %[[VAL_253]], %[[VAL_247]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_254:.*]] = fir.slice %[[VAL_248]], %[[VAL_252]]#1, %[[VAL_248]] path %[[VAL_246]] : (index, index, index, i32) -> !fir.slice<1> +! CHECK: cf.br ^bb1(%[[VAL_247]], %[[VAL_252]]#1 : index, index) +! CHECK: ^bb1(%[[VAL_255:.*]]: index, %[[VAL_256:.*]]: index): +! CHECK: %[[VAL_257:.*]] = arith.cmpi sgt, %[[VAL_256]], %[[VAL_247]] : index +! CHECK: cf.cond_br %[[VAL_257]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_258:.*]] = fir.coordinate_of %[[VAL_253]], %[[VAL_255]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_259:.*]] = fir.load %[[VAL_258]] : !fir.ref +! CHECK: %[[VAL_260:.*]] = fir.convert %[[VAL_259]] : (i32) -> index +! CHECK: %[[VAL_261:.*]] = fir.array_coor %[[VAL_262]] {{\[}}%[[VAL_254]]] %[[VAL_260]] : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref +! CHECK: %[[VAL_263:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_251]], %[[VAL_261]]) : (!fir.ref, !fir.ref) -> i1 +! CHECK: %[[VAL_264:.*]] = arith.addi %[[VAL_255]], %[[VAL_248]] : index +! CHECK: %[[VAL_265:.*]] = arith.subi %[[VAL_256]], %[[VAL_248]] : index +! CHECK: cf.br ^bb1(%[[VAL_264]], %[[VAL_265]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_266:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_251]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +module derived_types + type t + integer :: i + character(2) :: c + end type + type t2 + type(t) :: a(5,5) + end type +end module + +! CHECK-LABEL: func @_QPsimple_derived( +! CHECK-SAME: %[[VAL_287:.*]]: !fir.ref}>>>{{.*}}, %[[VAL_283:.*]]: !fir.ref>{{.*}}) { +subroutine simple_derived(x, y) + use derived_types + integer :: y(4) + type(t) :: x(3:8) + read(*,*) x(y) +! CHECK-DAG: %[[VAL_267:.*]] = arith.constant 6 : index +! CHECK-DAG: %[[VAL_268:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_270:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_271:.*]] = arith.constant 4 : index +! CHECK-DAG: %[[VAL_272:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_273:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_274:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_275:.*]] = fir.convert %[[VAL_274]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_276:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_268]], %[[VAL_275]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_277:.*]] = fir.shape_shift %[[VAL_270]], %[[VAL_267]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_278:.*]] = fir.slice %[[VAL_273]], %[[VAL_271]], %[[VAL_273]] : (index, index, index) -> !fir.slice<1> +! CHECK: cf.br ^bb1(%[[VAL_272]], %[[VAL_271]] : index, index) +! CHECK: ^bb1(%[[VAL_279:.*]]: index, %[[VAL_280:.*]]: index): +! CHECK: %[[VAL_281:.*]] = arith.cmpi sgt, %[[VAL_280]], %[[VAL_272]] : index +! CHECK: cf.cond_br %[[VAL_281]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_282:.*]] = fir.coordinate_of %[[VAL_283]], %[[VAL_279]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_284:.*]] = fir.load %[[VAL_282]] : !fir.ref +! CHECK: %[[VAL_285:.*]] = fir.convert %[[VAL_284]] : (i32) -> index +! CHECK: %[[VAL_286:.*]] = fir.array_coor %[[VAL_287]](%[[VAL_277]]) {{\[}}%[[VAL_278]]] %[[VAL_285]] : (!fir.ref}>>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref}>> +! CHECK: %[[VAL_288:.*]] = fir.embox %[[VAL_286]] : (!fir.ref}>>) -> !fir.box}>> +! CHECK: %[[VAL_289:.*]] = fir.convert %[[VAL_288]] : (!fir.box}>>) -> !fir.box +! CHECK: %[[VAL_290:.*]] = fir.call @_FortranAioInputDescriptor(%[[VAL_276]], %[[VAL_289]]) : (!fir.ref, !fir.box) -> i1 +! CHECK: %[[VAL_291:.*]] = arith.addi %[[VAL_279]], %[[VAL_273]] : index +! CHECK: %[[VAL_292:.*]] = arith.subi %[[VAL_280]], %[[VAL_273]] : index +! CHECK: cf.br ^bb1(%[[VAL_291]], %[[VAL_292]] : index, index) +! CHECK: ^bb3: +! CHECK: %[[VAL_293:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_276]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPwith_path( +! CHECK-SAME: [[VAL_326:.*]]: !fir.box}>>}>>>{{.*}}, [[VAL_310:.*]]: !fir.box>{{.*}}) { +subroutine with_path(b, i) + use derived_types + type(t2) :: b(4:, 4:, 4:) + integer :: i(:) + read (*, *) b(5, i, 8:9:1)%a(4,5)%i +! CHECK-DAG: %[[VAL_294:.*]] = arith.constant 4 : index +! CHECK-DAG: %[[VAL_295:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_297:.*]] = arith.constant 8 : index +! CHECK-DAG: %[[VAL_298:.*]] = arith.constant 9 : index +! CHECK-DAG: %[[VAL_299:.*]] = arith.constant 4 : i64 +! CHECK-DAG: %[[VAL_300:.*]] = arith.constant 5 : i64 +! CHECK-DAG: %[[VAL_301:.*]] = arith.constant 5 : index +! CHECK-DAG: %[[VAL_302:.*]] = arith.constant 4 : i32 +! CHECK-DAG: %[[VAL_303:.*]] = arith.constant 2 : index +! CHECK-DAG: %[[VAL_304:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_305:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_306:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_307:.*]] = fir.convert %[[VAL_306]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_308:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_295]], %[[VAL_307]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_309:.*]]:3 = fir.box_dims %[[VAL_310:.*]], %[[VAL_304]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_311:.*]] = fir.field_index a, !fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}> +! CHECK: %[[VAL_312:.*]] = fir.field_index i, !fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}> +! CHECK: %[[VAL_313:.*]] = fir.shift %[[VAL_294]], %[[VAL_294]], %[[VAL_294]] : (index, index, index) -> !fir.shift<3> +! CHECK: %[[VAL_314:.*]] = fir.undefined index +! CHECK: %[[VAL_315:.*]] = fir.slice %[[VAL_300]], %[[VAL_314]], %[[VAL_314]], %[[VAL_305]], %[[VAL_309]]#1, %[[VAL_305]], %[[VAL_297]], %[[VAL_298]], %[[VAL_305]] path %[[VAL_311]], %[[VAL_299]], %[[VAL_300]], %[[VAL_312]] : (i64, index, index, index, index, index, index, index, index, !fir.field, i64, i64, !fir.field) -> !fir.slice<3> +! CHECK: cf.br ^bb1(%[[VAL_294]], %[[VAL_303]] : index, index) +! CHECK: ^bb1(%[[VAL_316:.*]]: index, %[[VAL_317:.*]]: index): +! CHECK: %[[VAL_318:.*]] = arith.cmpi sgt, %[[VAL_317]], %[[VAL_304]] : index +! CHECK: cf.cond_br %[[VAL_318]], ^bb2(%[[VAL_304]], %[[VAL_309]]#1 : index, index), ^bb5 +! CHECK: ^bb2(%[[VAL_319:.*]]: index, %[[VAL_320:.*]]: index): +! CHECK: %[[VAL_321:.*]] = arith.cmpi sgt, %[[VAL_320]], %[[VAL_304]] : index +! CHECK: cf.cond_br %[[VAL_321]], ^bb3, ^bb4 +! CHECK: ^bb3: +! CHECK: %[[VAL_322:.*]] = fir.coordinate_of %[[VAL_310]], %[[VAL_319]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_323:.*]] = fir.load %[[VAL_322]] : !fir.ref +! CHECK: %[[VAL_324:.*]] = fir.convert %[[VAL_323]] : (i32) -> index +! CHECK: %[[VAL_325:.*]] = fir.array_coor %[[VAL_326:.*]](%[[VAL_313]]) {{\[}}%[[VAL_315]]] %[[VAL_301]], %[[VAL_324]], %[[VAL_316]] : (!fir.box}>>}>>>, !fir.shift<3>, !fir.slice<3>, index, index, index) -> !fir.ref +! CHECK: %[[VAL_327:.*]] = fir.convert %[[VAL_325]] : (!fir.ref) -> !fir.ref +! CHECK: %[[VAL_328:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_308]], %[[VAL_327]], %[[VAL_302]]) : (!fir.ref, !fir.ref, i32) -> i1 +! CHECK: %[[VAL_329:.*]] = arith.addi %[[VAL_319]], %[[VAL_305]] : index +! CHECK: %[[VAL_330:.*]] = arith.subi %[[VAL_320]], %[[VAL_305]] : index +! CHECK: cf.br ^bb2(%[[VAL_329]], %[[VAL_330]] : index, index) +! CHECK: ^bb4: +! CHECK: %[[VAL_331:.*]] = arith.addi %[[VAL_316]], %[[VAL_305]] : index +! CHECK: %[[VAL_332:.*]] = arith.subi %[[VAL_317]], %[[VAL_305]] : index +! CHECK: cf.br ^bb1(%[[VAL_331]], %[[VAL_332]] : index, index) +! CHECK: ^bb5: +! CHECK: %[[VAL_333:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_308]]) : (!fir.ref) -> i32 +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPsimple_iostat( +! CHECK-SAME: %[[VAL_357:.*]]: !fir.box>{{.*}}, %[[VAL_346:.*]]: !fir.box>{{.*}}, %[[VAL_361:.*]]: !fir.ref{{.*}}, %[[VAL_364:.*]]: !fir.ref{{.*}}) { +subroutine simple_iostat(x, y, j, stat) + integer :: j, y(:), stat + real :: x(:) + read(*, *, iostat=stat) x(y), j +! CHECK-DAG: %[[VAL_334:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_336:.*]] = arith.constant false +! CHECK-DAG: %[[VAL_337:.*]] = arith.constant true +! CHECK-DAG: %[[VAL_338:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[VAL_339:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_340:.*]] = arith.constant 4 : i32 +! CHECK: %[[VAL_341:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_342:.*]] = fir.convert %[[VAL_341]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_343:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_334]], %[[VAL_342]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_344:.*]] = fir.call @_FortranAioEnableHandlers(%[[VAL_343]], %[[VAL_337]], %[[VAL_336]], %[[VAL_336]], %[[VAL_336]], %[[VAL_336]]) : (!fir.ref, i1, i1, i1, i1, i1) -> none +! CHECK: %[[VAL_345:.*]]:3 = fir.box_dims %[[VAL_346]], %[[VAL_339]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_347:.*]] = fir.slice %[[VAL_338]], %[[VAL_345]]#1, %[[VAL_338]] : (index, index, index) -> !fir.slice<1> +! CHECK: %[[VAL_348:.*]] = arith.subi %[[VAL_345]]#1, %[[VAL_338]] : index +! CHECK: cf.br ^bb1(%[[VAL_339]], %[[VAL_337]] : index, i1) +! CHECK: ^bb1(%[[VAL_349:.*]]: index, %[[VAL_350:.*]]: i1): +! CHECK: %[[VAL_351:.*]] = arith.cmpi sle, %[[VAL_349]], %[[VAL_348]] : index +! CHECK: %[[VAL_352:.*]] = arith.andi %[[VAL_350]], %[[VAL_351]] : i1 +! CHECK: cf.cond_br %[[VAL_352]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_353:.*]] = fir.coordinate_of %[[VAL_346]], %[[VAL_349]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_354:.*]] = fir.load %[[VAL_353]] : !fir.ref +! CHECK: %[[VAL_355:.*]] = fir.convert %[[VAL_354]] : (i32) -> index +! CHECK: %[[VAL_356:.*]] = fir.array_coor %[[VAL_357]] {{\[}}%[[VAL_347]]] %[[VAL_355]] : (!fir.box>, !fir.slice<1>, index) -> !fir.ref +! CHECK: %[[VAL_358:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_343]], %[[VAL_356]]) : (!fir.ref, !fir.ref) -> i1 +! CHECK: %[[VAL_359:.*]] = arith.addi %[[VAL_349]], %[[VAL_338]] : index +! CHECK: cf.br ^bb1(%[[VAL_359]], %[[VAL_358]] : index, i1) +! CHECK: ^bb3: +! CHECK: cf.cond_br %[[VAL_350]], ^bb4, ^bb5 +! CHECK: ^bb4: +! CHECK: %[[VAL_360:.*]] = fir.convert %[[VAL_361]] : (!fir.ref) -> !fir.ref +! CHECK: %[[VAL_362:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_343]], %[[VAL_360]], %[[VAL_340]]) : (!fir.ref, !fir.ref, i32) -> i1 +! CHECK: cf.br ^bb5 +! CHECK: ^bb5: +! CHECK: %[[VAL_363:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_343]]) : (!fir.ref) -> i32 +! CHECK: fir.store %[[VAL_363]] to %[[VAL_364]] : !fir.ref +! CHECK: return +end subroutine + +! CHECK-LABEL: func @_QPiostat_in_io_loop( +! CHECK-SAME: %[[VAL_400:.*]]: !fir.ref>{{.*}}, %[[VAL_396:.*]]: !fir.ref>{{.*}}, %[[VAL_408:.*]]: !fir.ref{{.*}}) { +subroutine iostat_in_io_loop(k, j, stat) + integer :: k(3, 5) + integer :: j(3) + integer :: stat + read(*, *, iostat=stat) (k(i, j), i=1,3,1) +! CHECK-DAG: %[[VAL_365:.*]] = arith.constant 5 : index +! CHECK-DAG: %[[VAL_366:.*]] = arith.constant -1 : i32 +! CHECK-DAG: %[[VAL_368:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[VAL_369:.*]] = arith.constant true +! CHECK-DAG: %[[VAL_370:.*]] = arith.constant false +! CHECK-DAG: %[[VAL_371:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[VAL_372:.*]] = arith.constant 0 : index +! CHECK-DAG: %[[VAL_373:.*]] = arith.constant 2 : index +! CHECK-DAG: %[[VAL_374:.*]] = arith.constant 4 : i32 +! CHECK: %[[VAL_375:.*]] = fir.alloca i32 +! CHECK: %[[VAL_376:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref> +! CHECK: %[[VAL_377:.*]] = fir.convert %[[VAL_376]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_378:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_366]], %[[VAL_377]], %{{.*}}) : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[VAL_379:.*]] = fir.call @_FortranAioEnableHandlers(%[[VAL_378]], %[[VAL_369]], %[[VAL_370]], %[[VAL_370]], %[[VAL_370]], %[[VAL_370]]) : (!fir.ref, i1, i1, i1, i1, i1) -> none +! CHECK: cf.br ^bb1(%[[VAL_371]], %[[VAL_369]] : index, i1) +! CHECK: ^bb1(%[[VAL_380:.*]]: index, %[[VAL_381:.*]]: i1): +! CHECK: %[[VAL_382:.*]] = arith.cmpi sle, %[[VAL_380]], %[[VAL_368]] : index +! CHECK: %[[VAL_383:.*]] = arith.andi %[[VAL_381]], %[[VAL_382]] : i1 +! CHECK: cf.cond_br %[[VAL_383]], ^bb2, ^bb7 +! CHECK: ^bb2: +! CHECK: %[[VAL_384:.*]] = fir.convert %[[VAL_380]] : (index) -> i32 +! CHECK: fir.store %[[VAL_384]] to %[[VAL_375]] : !fir.ref +! CHECK: cf.cond_br %[[VAL_381]], ^bb3, ^bb6(%[[VAL_370]] : i1) +! CHECK: ^bb3: +! CHECK: %[[VAL_385:.*]] = fir.load %[[VAL_375]] : !fir.ref +! CHECK: %[[VAL_386:.*]] = fir.convert %[[VAL_385]] : (i32) -> i64 +! CHECK: %[[VAL_387:.*]] = fir.shape %[[VAL_368]], %[[VAL_365]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_388:.*]] = fir.undefined index +! CHECK: %[[VAL_389:.*]] = fir.slice %[[VAL_386]], %[[VAL_388]], %[[VAL_388]], %[[VAL_371]], %[[VAL_368]], %[[VAL_371]] : (i64, index, index, index, index, index) -> !fir.slice<2> +! CHECK: cf.br ^bb4(%[[VAL_372]], %[[VAL_369]] : index, i1) +! CHECK: ^bb4(%[[VAL_390:.*]]: index, %[[VAL_391:.*]]: i1): +! CHECK: %[[VAL_392:.*]] = arith.cmpi sle, %[[VAL_390]], %[[VAL_373]] : index +! CHECK: %[[VAL_393:.*]] = arith.andi %[[VAL_391]], %[[VAL_392]] : i1 +! CHECK: cf.cond_br %[[VAL_393]], ^bb5, ^bb6(%[[VAL_391]] : i1) +! CHECK: ^bb5: +! CHECK: %[[VAL_394:.*]] = fir.convert %[[VAL_385]] : (i32) -> index +! CHECK: %[[VAL_395:.*]] = fir.coordinate_of %[[VAL_396]], %[[VAL_390]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_397:.*]] = fir.load %[[VAL_395]] : !fir.ref +! CHECK: %[[VAL_398:.*]] = fir.convert %[[VAL_397]] : (i32) -> index +! CHECK: %[[VAL_399:.*]] = fir.array_coor %[[VAL_400]](%[[VAL_387]]) {{\[}}%[[VAL_389]]] %[[VAL_394]], %[[VAL_398]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref +! CHECK: %[[VAL_401:.*]] = fir.convert %[[VAL_399]] : (!fir.ref) -> !fir.ref +! CHECK: %[[VAL_402:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_378]], %[[VAL_401]], %[[VAL_374]]) : (!fir.ref, !fir.ref, i32) -> i1 +! CHECK: %[[VAL_403:.*]] = arith.addi %[[VAL_390]], %[[VAL_371]] : index +! CHECK: cf.br ^bb4(%[[VAL_403]], %[[VAL_402]] : index, i1) +! CHECK: ^bb6(%[[VAL_404:.*]]: i1): +! CHECK: %[[VAL_405:.*]] = arith.addi %[[VAL_380]], %[[VAL_371]] : index +! CHECK: cf.br ^bb1(%[[VAL_405]], %[[VAL_404]] : index, i1) +! CHECK: ^bb7: +! CHECK: %[[VAL_406:.*]] = fir.convert %[[VAL_380]] : (index) -> i32 +! CHECK: fir.store %[[VAL_406]] to %[[VAL_375]] : !fir.ref +! CHECK: %[[VAL_407:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_378]]) : (!fir.ref) -> i32 +! CHECK: fir.store %[[VAL_407]] to %[[VAL_408]] : !fir.ref +! CHECK: return +end subroutine