Remove check for Android in Mips.cpp (#123793)
[llvm-project.git] / flang / test / HLFIR / opt-array-slice-assign.fir
blob3db47b1da8cd333a1cd78f1c1f1e06643b3bf1ac
1 // Test optimized bufferization for hlfir.assign of array
2 // slices, e.g.:
3 //   x(2:7999,1:120,new) = (x(2:7999,1:120,old))
4 // We can expand hlfir.assign if the slices are either identical
5 // or completely disjoint. In case they are identical, we still
6 // need to make sure that the one-based indices are used
7 // uniformly for both LHS and RHS.
8 // RUN: fir-opt --opt-bufferization %s | FileCheck %s
10 func.func @_QPtest1(%arg0: !fir.ref<!fir.array<8000x120x3xf32>> {fir.bindc_name = "x"}) {
11   %c7998 = arith.constant 7998 : index
12   %c1 = arith.constant 1 : index
13   %c7999 = arith.constant 7999 : index
14   %c2 = arith.constant 2 : index
15   %c3 = arith.constant 3 : index
16   %c120 = arith.constant 120 : index
17   %c8000 = arith.constant 8000 : index
18   %0 = fir.alloca i32 {bindc_name = "new", uniq_name = "_QFtest1Enew"}
19   %1:2 = hlfir.declare %0 {uniq_name = "_QFtest1Enew"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
20   %2 = fir.alloca i32 {bindc_name = "old", uniq_name = "_QFtest1Eold"}
21   %3:2 = hlfir.declare %2 {uniq_name = "_QFtest1Eold"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
22   %4 = fir.shape %c8000, %c120, %c3 : (index, index, index) -> !fir.shape<3>
23   %5:2 = hlfir.declare %arg0(%4) {uniq_name = "_QFtest1Ex"} : (!fir.ref<!fir.array<8000x120x3xf32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<8000x120x3xf32>>, !fir.ref<!fir.array<8000x120x3xf32>>)
24   %6 = fir.load %3#0 : !fir.ref<i32>
25   %7 = fir.convert %6 : (i32) -> i64
26   %8 = fir.shape %c7998, %c120 : (index, index) -> !fir.shape<2>
27   %9 = hlfir.designate %5#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %7)  shape %8 : (!fir.ref<!fir.array<8000x120x3xf32>>, index, index, index, index, index, index, i64, !fir.shape<2>) -> !fir.box<!fir.array<7998x120xf32>>
28   %10 = hlfir.elemental %8 unordered : (!fir.shape<2>) -> !hlfir.expr<7998x120xf32> {
29   ^bb0(%arg1: index, %arg2: index):
30     %14 = hlfir.designate %9 (%arg1, %arg2)  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
31     %15 = fir.load %14 : !fir.ref<f32>
32     %16 = hlfir.no_reassoc %15 : f32
33     hlfir.yield_element %16 : f32
34   }
35   %11 = fir.load %1#0 : !fir.ref<i32>
36   %12 = fir.convert %11 : (i32) -> i64
37   %13 = hlfir.designate %5#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %12)  shape %8 : (!fir.ref<!fir.array<8000x120x3xf32>>, index, index, index, index, index, index, i64, !fir.shape<2>) -> !fir.box<!fir.array<7998x120xf32>>
38   hlfir.assign %10 to %13 : !hlfir.expr<7998x120xf32>, !fir.box<!fir.array<7998x120xf32>>
39   hlfir.destroy %10 : !hlfir.expr<7998x120xf32>
40   return
42 // CHECK-LABEL:   func.func @_QPtest1(
43 // CHECK:           fir.do_loop %[[VAL_21:.*]] =
44 // CHECK:             fir.do_loop %[[VAL_22:.*]] =
45 // CHECK:               %[[VAL_23:.*]] = hlfir.designate %[[VAL_17:.*]] (%[[VAL_22]], %[[VAL_21]])  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
46 // CHECK:               %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref<f32>
47 // CHECK:               %[[VAL_25:.*]] = hlfir.no_reassoc %[[VAL_24]] : f32
48 // CHECK:               %[[VAL_26:.*]] = hlfir.designate %[[VAL_20:.*]] (%[[VAL_22]], %[[VAL_21]])  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
49 // CHECK:               hlfir.assign %[[VAL_25]] to %[[VAL_26]] : f32, !fir.ref<f32>
50 // CHECK:             }
51 // CHECK:           }
53 func.func @_QPtest2(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>> {fir.bindc_name = "x"}) {
54   %c120 = arith.constant 120 : index
55   %c7998 = arith.constant 7998 : index
56   %c1 = arith.constant 1 : index
57   %c7999 = arith.constant 7999 : index
58   %c2 = arith.constant 2 : index
59   %0:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>)
60   %1 = fir.load %0#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>
61   %2 = fir.shape %c7998, %c120 : (index, index) -> !fir.shape<2>
62   %3 = hlfir.designate %1 (%c2:%c7999:%c1, %c1:%c120:%c1, %c2)  shape %2 : (!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>, index, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<7998x120xf32>>
63   %4 = hlfir.elemental %2 unordered : (!fir.shape<2>) -> !hlfir.expr<7998x120xf32> {
64   ^bb0(%arg1: index, %arg2: index):
65     %6 = hlfir.designate %3 (%arg1, %arg2)  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
66     %7 = fir.load %6 : !fir.ref<f32>
67     %8 = hlfir.no_reassoc %7 : f32
68     hlfir.yield_element %8 : f32
69   }
70   %5 = hlfir.designate %1 (%c2:%c7999:%c1, %c1:%c120:%c1, %c1)  shape %2 : (!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>, index, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<7998x120xf32>>
71   hlfir.assign %4 to %5 : !hlfir.expr<7998x120xf32>, !fir.box<!fir.array<7998x120xf32>>
72   hlfir.destroy %4 : !hlfir.expr<7998x120xf32>
73   return
75 // CHECK-LABEL:   func.func @_QPtest2(
76 // CHECK:           fir.do_loop %[[VAL_11:.*]] =
77 // CHECK:             fir.do_loop %[[VAL_12:.*]] =
78 // CHECK:               %[[VAL_13:.*]] = hlfir.designate %[[VAL_9:.*]] (%[[VAL_12]], %[[VAL_11]])  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
79 // CHECK:               %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<f32>
80 // CHECK:               %[[VAL_15:.*]] = hlfir.no_reassoc %[[VAL_14]] : f32
81 // CHECK:               %[[VAL_16:.*]] = hlfir.designate %[[VAL_10:.*]] (%[[VAL_12]], %[[VAL_11]])  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
82 // CHECK:               hlfir.assign %[[VAL_15]] to %[[VAL_16]] : f32, !fir.ref<f32>
83 // CHECK:             }
84 // CHECK:           }
86 func.func @_QPtest3(%arg0: !fir.ref<!fir.array<10x!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>> {fir.bindc_name = "x"}) {
87   %c7998 = arith.constant 7998 : index
88   %c7999 = arith.constant 7999 : index
89   %c2 = arith.constant 2 : index
90   %c3 = arith.constant 3 : index
91   %c120 = arith.constant 120 : index
92   %c8000 = arith.constant 8000 : index
93   %c1 = arith.constant 1 : index
94   %c10 = arith.constant 10 : index
95   %0 = fir.alloca i32 {bindc_name = "new", uniq_name = "_QFtest3Enew"}
96   %1:2 = hlfir.declare %0 {uniq_name = "_QFtest3Enew"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
97   %2 = fir.alloca i32 {bindc_name = "old", uniq_name = "_QFtest3Eold"}
98   %3:2 = hlfir.declare %2 {uniq_name = "_QFtest3Eold"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
99   %4 = fir.shape %c10 : (index) -> !fir.shape<1>
100   %5:2 = hlfir.declare %arg0(%4) {uniq_name = "_QFtest3Ex"} : (!fir.ref<!fir.array<10x!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10x!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>>, !fir.ref<!fir.array<10x!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>>)
101   %6 = hlfir.designate %5#0 (%c1)  : (!fir.ref<!fir.array<10x!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>>, index) -> !fir.ref<!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>
102   %7 = fir.shape %c8000, %c120, %c3 : (index, index, index) -> !fir.shape<3>
103   %8 = fir.load %3#0 : !fir.ref<i32>
104   %9 = fir.convert %8 : (i32) -> i64
105   %10 = fir.shape %c7998, %c120 : (index, index) -> !fir.shape<2>
106   %11 = hlfir.designate %6{"x"} <%7> (%c2:%c7999:%c1, %c1:%c120:%c1, %9)  shape %10 : (!fir.ref<!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>, !fir.shape<3>, index, index, index, index, index, index, i64, !fir.shape<2>) -> !fir.box<!fir.array<7998x120xf32>>
107   %12 = hlfir.elemental %10 unordered : (!fir.shape<2>) -> !hlfir.expr<7998x120xf32> {
108   ^bb0(%arg1: index, %arg2: index):
109     %16 = hlfir.designate %11 (%arg1, %arg2)  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
110     %17 = fir.load %16 : !fir.ref<f32>
111     %18 = hlfir.no_reassoc %17 : f32
112     hlfir.yield_element %18 : f32
113   }
114   %13 = fir.load %1#0 : !fir.ref<i32>
115   %14 = fir.convert %13 : (i32) -> i64
116   %15 = hlfir.designate %6{"x"} <%7> (%c2:%c7999:%c1, %c1:%c120:%c1, %14)  shape %10 : (!fir.ref<!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>, !fir.shape<3>, index, index, index, index, index, index, i64, !fir.shape<2>) -> !fir.box<!fir.array<7998x120xf32>>
117   hlfir.assign %12 to %15 : !hlfir.expr<7998x120xf32>, !fir.box<!fir.array<7998x120xf32>>
118   hlfir.destroy %12 : !hlfir.expr<7998x120xf32>
119   return
121 // CHECK-LABEL:   func.func @_QPtest3(
122 // CHECK:           fir.do_loop %[[VAL_24:.*]] =
123 // CHECK:             fir.do_loop %[[VAL_25:.*]] =
124 // CHECK:               %[[VAL_26:.*]] = hlfir.designate %[[VAL_20:.*]] (%[[VAL_25]], %[[VAL_24]])  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
125 // CHECK:               %[[VAL_27:.*]] = fir.load %[[VAL_26]] : !fir.ref<f32>
126 // CHECK:               %[[VAL_28:.*]] = hlfir.no_reassoc %[[VAL_27]] : f32
127 // CHECK:               %[[VAL_29:.*]] = hlfir.designate %[[VAL_23:.*]] (%[[VAL_25]], %[[VAL_24]])  : (!fir.box<!fir.array<7998x120xf32>>, index, index) -> !fir.ref<f32>
128 // CHECK:               hlfir.assign %[[VAL_28]] to %[[VAL_29]] : f32, !fir.ref<f32>
129 // CHECK:             }
130 // CHECK:           }
132 // ! ub == lb - 1
133 // subroutine test4(x, i1, i2, nx)
134 //   real :: x(i2), f
135 //   do i=i1,i2,nx
136 //      x(i:i+nx-1) = (x(i-nx:i-1))
137 //   end do
138 // end subroutine test4
139 func.func @_QPtest4(%arg0: !fir.ref<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "i1"}, %arg2: !fir.ref<i32> {fir.bindc_name = "i2"}, %arg3: !fir.ref<i32> {fir.bindc_name = "nx"}) {
140   %c1 = arith.constant 1 : index
141   %c1_i32 = arith.constant 1 : i32
142   %c0 = arith.constant 0 : index
143   %0 = fir.alloca f32 {bindc_name = "f", uniq_name = "_QFtest4Ef"}
144   %1:2 = hlfir.declare %0 {uniq_name = "_QFtest4Ef"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
145   %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest4Ei"}
146   %3:2 = hlfir.declare %2 {uniq_name = "_QFtest4Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
147   %4:2 = hlfir.declare %arg1 {uniq_name = "_QFtest4Ei1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
148   %5:2 = hlfir.declare %arg2 {uniq_name = "_QFtest4Ei2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
149   %6:2 = hlfir.declare %arg3 {uniq_name = "_QFtest4Enx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
150   %7 = fir.load %5#0 : !fir.ref<i32>
151   %8 = fir.convert %7 : (i32) -> index
152   %9 = arith.cmpi sgt, %8, %c0 : index
153   %10 = arith.select %9, %8, %c0 : index
154   %11 = fir.shape %10 : (index) -> !fir.shape<1>
155   %12:2 = hlfir.declare %arg0(%11) {uniq_name = "_QFtest4Ex"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)
156   %13 = fir.load %4#0 : !fir.ref<i32>
157   %14 = fir.convert %13 : (i32) -> index
158   %15 = fir.load %5#0 : !fir.ref<i32>
159   %16 = fir.convert %15 : (i32) -> index
160   %17 = fir.load %6#0 : !fir.ref<i32>
161   %18 = fir.convert %17 : (i32) -> index
162   %19 = fir.convert %14 : (index) -> i32
163   %20:2 = fir.do_loop %arg4 = %14 to %16 step %18 iter_args(%arg5 = %19) -> (index, i32) {
164     fir.store %arg5 to %3#1 : !fir.ref<i32>
165     %21 = fir.load %3#0 : !fir.ref<i32>
166     %22 = fir.load %6#0 : !fir.ref<i32>
167     %23 = arith.subi %21, %22 : i32
168     %24 = arith.subi %21, %c1_i32 : i32
169     %25 = fir.convert %23 : (i32) -> index
170     %26 = fir.convert %24 : (i32) -> index
171     %27 = arith.subi %26, %25 : index
172     %28 = arith.addi %27, %c1 : index
173     %29 = arith.cmpi sgt, %28, %c0 : index
174     %30 = arith.select %29, %28, %c0 : index
175     %31 = fir.shape %30 : (index) -> !fir.shape<1>
176     %32 = hlfir.designate %12#0 (%25:%26:%c1)  shape %31 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
177     %33 = hlfir.elemental %31 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
178     ^bb0(%arg6: index):
179       %48 = hlfir.designate %32 (%arg6)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
180       %49 = fir.load %48 : !fir.ref<f32>
181       %50 = hlfir.no_reassoc %49 : f32
182       hlfir.yield_element %50 : f32
183     }
184     %34 = arith.addi %21, %22 : i32
185     %35 = arith.subi %34, %c1_i32 : i32
186     %36 = fir.convert %21 : (i32) -> index
187     %37 = fir.convert %35 : (i32) -> index
188     %38 = arith.subi %37, %36 : index
189     %39 = arith.addi %38, %c1 : index
190     %40 = arith.cmpi sgt, %39, %c0 : index
191     %41 = arith.select %40, %39, %c0 : index
192     %42 = fir.shape %41 : (index) -> !fir.shape<1>
193     %43 = hlfir.designate %12#0 (%36:%37:%c1)  shape %42 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
194     hlfir.assign %33 to %43 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
195     hlfir.destroy %33 : !hlfir.expr<?xf32>
196     %44 = arith.addi %arg4, %18 : index
197     %45 = fir.convert %18 : (index) -> i32
198     %46 = fir.load %3#1 : !fir.ref<i32>
199     %47 = arith.addi %46, %45 : i32
200     fir.result %44, %47 : index, i32
201   }
202   fir.store %20#1 to %3#1 : !fir.ref<i32>
203   return
205 // CHECK-LABEL:   func.func @_QPtest4(
206 // CHECK-NOT: hlfir.elemental
208 // ! lb == ub + 1
209 // subroutine test5(x, i1, i2, nx)
210 //   real :: x(i2), f
211 //   do i=i1,i2,nx
212 //      x(i+1:i+nx-1) = (x(i-nx:i))
213 //   end do
214 // end subroutine test5
215 func.func @_QPtest5(%arg0: !fir.ref<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "i1"}, %arg2: !fir.ref<i32> {fir.bindc_name = "i2"}, %arg3: !fir.ref<i32> {fir.bindc_name = "nx"}) {
216   %c1_i32 = arith.constant 1 : i32
217   %c1 = arith.constant 1 : index
218   %c0 = arith.constant 0 : index
219   %0 = fir.alloca f32 {bindc_name = "f", uniq_name = "_QFtest5Ef"}
220   %1:2 = hlfir.declare %0 {uniq_name = "_QFtest5Ef"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
221   %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest5Ei"}
222   %3:2 = hlfir.declare %2 {uniq_name = "_QFtest5Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
223   %4:2 = hlfir.declare %arg1 {uniq_name = "_QFtest5Ei1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
224   %5:2 = hlfir.declare %arg2 {uniq_name = "_QFtest5Ei2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
225   %6:2 = hlfir.declare %arg3 {uniq_name = "_QFtest5Enx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
226   %7 = fir.load %5#0 : !fir.ref<i32>
227   %8 = fir.convert %7 : (i32) -> index
228   %9 = arith.cmpi sgt, %8, %c0 : index
229   %10 = arith.select %9, %8, %c0 : index
230   %11 = fir.shape %10 : (index) -> !fir.shape<1>
231   %12:2 = hlfir.declare %arg0(%11) {uniq_name = "_QFtest5Ex"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)
232   %13 = fir.load %4#0 : !fir.ref<i32>
233   %14 = fir.convert %13 : (i32) -> index
234   %15 = fir.load %5#0 : !fir.ref<i32>
235   %16 = fir.convert %15 : (i32) -> index
236   %17 = fir.load %6#0 : !fir.ref<i32>
237   %18 = fir.convert %17 : (i32) -> index
238   %19 = fir.convert %14 : (index) -> i32
239   %20:2 = fir.do_loop %arg4 = %14 to %16 step %18 iter_args(%arg5 = %19) -> (index, i32) {
240     fir.store %arg5 to %3#1 : !fir.ref<i32>
241     %21 = fir.load %3#0 : !fir.ref<i32>
242     %22 = fir.load %6#0 : !fir.ref<i32>
243     %23 = arith.subi %21, %22 : i32
244     %24 = fir.convert %23 : (i32) -> index
245     %25 = fir.convert %21 : (i32) -> index
246     %26 = arith.subi %25, %24 : index
247     %27 = arith.addi %26, %c1 : index
248     %28 = arith.cmpi sgt, %27, %c0 : index
249     %29 = arith.select %28, %27, %c0 : index
250     %30 = fir.shape %29 : (index) -> !fir.shape<1>
251     %31 = hlfir.designate %12#0 (%24:%25:%c1)  shape %30 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
252     %32 = hlfir.elemental %30 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
253     ^bb0(%arg6: index):
254       %48 = hlfir.designate %31 (%arg6)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
255       %49 = fir.load %48 : !fir.ref<f32>
256       %50 = hlfir.no_reassoc %49 : f32
257       hlfir.yield_element %50 : f32
258     }
259     %33 = arith.addi %21, %c1_i32 : i32
260     %34 = arith.addi %21, %22 : i32
261     %35 = arith.subi %34, %c1_i32 : i32
262     %36 = fir.convert %33 : (i32) -> index
263     %37 = fir.convert %35 : (i32) -> index
264     %38 = arith.subi %37, %36 : index
265     %39 = arith.addi %38, %c1 : index
266     %40 = arith.cmpi sgt, %39, %c0 : index
267     %41 = arith.select %40, %39, %c0 : index
268     %42 = fir.shape %41 : (index) -> !fir.shape<1>
269     %43 = hlfir.designate %12#0 (%36:%37:%c1)  shape %42 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
270     hlfir.assign %32 to %43 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
271     hlfir.destroy %32 : !hlfir.expr<?xf32>
272     %44 = arith.addi %arg4, %18 : index
273     %45 = fir.convert %18 : (index) -> i32
274     %46 = fir.load %3#1 : !fir.ref<i32>
275     %47 = arith.addi %46, %45 : i32
276     fir.result %44, %47 : index, i32
277   }
278   fir.store %20#1 to %3#1 : !fir.ref<i32>
279   return
281 // CHECK-LABEL:   func.func @_QPtest5(
282 // CHECK-NOT: hlfir.elemental
284 // ! ub = lb - 1 and dim1 is unknown
285 // ! FIR lowering produces a temp.
286 // subroutine test6(x, i1, i2, nx)
287 //   real :: x(i2,i2), f
288 //   integer n1, n2, n3, n4
289 //   do i=i1,i2,nx
290 //      x(i:i+nx-1,n1:n2) = (x(i-nx:i-1,n3:n4))
291 //   end do
292 // end subroutine test6
293 func.func @_QPtest6(%arg0: !fir.ref<!fir.array<?x?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "i1"}, %arg2: !fir.ref<i32> {fir.bindc_name = "i2"}, %arg3: !fir.ref<i32> {fir.bindc_name = "nx"}) {
294   %c1 = arith.constant 1 : index
295   %c1_i32 = arith.constant 1 : i32
296   %c0 = arith.constant 0 : index
297   %0 = fir.alloca f32 {bindc_name = "f", uniq_name = "_QFtest6Ef"}
298   %1:2 = hlfir.declare %0 {uniq_name = "_QFtest6Ef"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
299   %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest6Ei"}
300   %3:2 = hlfir.declare %2 {uniq_name = "_QFtest6Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
301   %4:2 = hlfir.declare %arg1 {uniq_name = "_QFtest6Ei1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
302   %5:2 = hlfir.declare %arg2 {uniq_name = "_QFtest6Ei2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
303   %6 = fir.alloca i32 {bindc_name = "n1", uniq_name = "_QFtest6En1"}
304   %7:2 = hlfir.declare %6 {uniq_name = "_QFtest6En1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
305   %8 = fir.alloca i32 {bindc_name = "n2", uniq_name = "_QFtest6En2"}
306   %9:2 = hlfir.declare %8 {uniq_name = "_QFtest6En2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
307   %10 = fir.alloca i32 {bindc_name = "n3", uniq_name = "_QFtest6En3"}
308   %11:2 = hlfir.declare %10 {uniq_name = "_QFtest6En3"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
309   %12 = fir.alloca i32 {bindc_name = "n4", uniq_name = "_QFtest6En4"}
310   %13:2 = hlfir.declare %12 {uniq_name = "_QFtest6En4"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
311   %14:2 = hlfir.declare %arg3 {uniq_name = "_QFtest6Enx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
312   %15 = fir.load %5#0 : !fir.ref<i32>
313   %16 = fir.convert %15 : (i32) -> index
314   %17 = arith.cmpi sgt, %16, %c0 : index
315   %18 = arith.select %17, %16, %c0 : index
316   %19 = fir.shape %18, %18 : (index, index) -> !fir.shape<2>
317   %20:2 = hlfir.declare %arg0(%19) {uniq_name = "_QFtest6Ex"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
318   %21 = fir.load %4#0 : !fir.ref<i32>
319   %22 = fir.convert %21 : (i32) -> index
320   %23 = fir.load %5#0 : !fir.ref<i32>
321   %24 = fir.convert %23 : (i32) -> index
322   %25 = fir.load %14#0 : !fir.ref<i32>
323   %26 = fir.convert %25 : (i32) -> index
324   %27 = fir.convert %22 : (index) -> i32
325   %28:2 = fir.do_loop %arg4 = %22 to %24 step %26 iter_args(%arg5 = %27) -> (index, i32) {
326     fir.store %arg5 to %3#1 : !fir.ref<i32>
327     %29 = fir.load %3#0 : !fir.ref<i32>
328     %30 = fir.load %14#0 : !fir.ref<i32>
329     %31 = arith.subi %29, %30 : i32
330     %32 = arith.subi %29, %c1_i32 : i32
331     %33 = fir.convert %31 : (i32) -> index
332     %34 = fir.convert %32 : (i32) -> index
333     %35 = arith.subi %34, %33 : index
334     %36 = arith.addi %35, %c1 : index
335     %37 = arith.cmpi sgt, %36, %c0 : index
336     %38 = arith.select %37, %36, %c0 : index
337     %39 = fir.load %11#0 : !fir.ref<i32>
338     %40 = fir.load %13#0 : !fir.ref<i32>
339     %41 = fir.convert %39 : (i32) -> index
340     %42 = fir.convert %40 : (i32) -> index
341     %43 = arith.subi %42, %41 : index
342     %44 = arith.addi %43, %c1 : index
343     %45 = arith.cmpi sgt, %44, %c0 : index
344     %46 = arith.select %45, %44, %c0 : index
345     %47 = fir.shape %38, %46 : (index, index) -> !fir.shape<2>
346     %48 = hlfir.designate %20#0 (%33:%34:%c1, %41:%42:%c1)  shape %47 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
347     %49 = hlfir.elemental %47 unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xf32> {
348     ^bb0(%arg6: index, %arg7: index):
349       %72 = hlfir.designate %48 (%arg6, %arg7)  : (!fir.box<!fir.array<?x?xf32>>, index, index) -> !fir.ref<f32>
350       %73 = fir.load %72 : !fir.ref<f32>
351       %74 = hlfir.no_reassoc %73 : f32
352       hlfir.yield_element %74 : f32
353     }
354     %50 = arith.addi %29, %30 : i32
355     %51 = arith.subi %50, %c1_i32 : i32
356     %52 = fir.convert %29 : (i32) -> index
357     %53 = fir.convert %51 : (i32) -> index
358     %54 = arith.subi %53, %52 : index
359     %55 = arith.addi %54, %c1 : index
360     %56 = arith.cmpi sgt, %55, %c0 : index
361     %57 = arith.select %56, %55, %c0 : index
362     %58 = fir.load %7#0 : !fir.ref<i32>
363     %59 = fir.load %9#0 : !fir.ref<i32>
364     %60 = fir.convert %58 : (i32) -> index
365     %61 = fir.convert %59 : (i32) -> index
366     %62 = arith.subi %61, %60 : index
367     %63 = arith.addi %62, %c1 : index
368     %64 = arith.cmpi sgt, %63, %c0 : index
369     %65 = arith.select %64, %63, %c0 : index
370     %66 = fir.shape %57, %65 : (index, index) -> !fir.shape<2>
371     %67 = hlfir.designate %20#0 (%52:%53:%c1, %60:%61:%c1)  shape %66 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
372     hlfir.assign %49 to %67 : !hlfir.expr<?x?xf32>, !fir.box<!fir.array<?x?xf32>>
373     hlfir.destroy %49 : !hlfir.expr<?x?xf32>
374     %68 = arith.addi %arg4, %26 : index
375     %69 = fir.convert %26 : (index) -> i32
376     %70 = fir.load %3#1 : !fir.ref<i32>
377     %71 = arith.addi %70, %69 : i32
378     fir.result %68, %71 : index, i32
379   }
380   fir.store %28#1 to %3#1 : !fir.ref<i32>
381   return
383 // CHECK-LABEL:   func.func @_QPtest6(
384 // CHECK-NOT: hlfir.elemental
386 // Check that 'x(9,:)=SUM(x(1:8,:),DIM=1)' is optimized
387 // due to the LHS and RHS being disjoint array sections.
388 func.func @test_disjoint_triple_index(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
389   %cst = arith.constant 0.000000e+00 : f32
390   %c9 = arith.constant 9 : index
391   %c0 = arith.constant 0 : index
392   %c8 = arith.constant 8 : index
393   %c1 = arith.constant 1 : index
394   %0 = fir.dummy_scope : !fir.dscope
395   %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
396   %2:3 = fir.box_dims %1#1, %c1 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
397   %3 = arith.cmpi sgt, %2#1, %c0 : index
398   %4 = arith.select %3, %2#1, %c0 : index
399   %5 = fir.shape %c8, %4 : (index, index) -> !fir.shape<2>
400   %6 = hlfir.designate %1#0 (%c1:%c8:%c1, %c1:%2#1:%c1)  shape %5 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<8x?xf32>>
401   %7 = fir.shape %4 : (index) -> !fir.shape<1>
402   %8 = hlfir.elemental %7 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
403   ^bb0(%arg1: index):
404     %10 = fir.alloca f32 {bindc_name = ".sum.reduction"}
405     fir.store %cst to %10 : !fir.ref<f32>
406     fir.do_loop %arg2 = %c1 to %c8 step %c1 unordered {
407       %12 = fir.load %10 : !fir.ref<f32>
408       %13 = hlfir.designate %6 (%arg2, %arg1)  : (!fir.box<!fir.array<8x?xf32>>, index, index) -> !fir.ref<f32>
409       %14 = fir.load %13 : !fir.ref<f32>
410       %15 = arith.addf %12, %14 fastmath<fast> : f32
411       fir.store %15 to %10 : !fir.ref<f32>
412     }
413     %11 = fir.load %10 : !fir.ref<f32>
414     hlfir.yield_element %11 : f32
415   }
416   %9 = hlfir.designate %1#0 (%c9, %c1:%2#1:%c1)  shape %7 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
417   hlfir.assign %8 to %9 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
418   hlfir.destroy %8 : !hlfir.expr<?xf32>
419   return
421 // CHECK-LABEL:   func.func @test_disjoint_triple_index(
422 // CHECK-NOT: hlfir.elemental
424 // Check that 'x(9,:)=SUM(x(9:9,:),DIM=1)' is not optimized.
425 func.func @test_overlapping_triple_index(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
426   %cst = arith.constant 0.000000e+00 : f32
427   %c9 = arith.constant 9 : index
428   %c0 = arith.constant 0 : index
429   %c8 = arith.constant 8 : index
430   %c1 = arith.constant 1 : index
431   %0 = fir.dummy_scope : !fir.dscope
432   %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
433   %2:3 = fir.box_dims %1#1, %c1 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
434   %3 = arith.cmpi sgt, %2#1, %c0 : index
435   %4 = arith.select %3, %2#1, %c0 : index
436   %5 = fir.shape %c8, %4 : (index, index) -> !fir.shape<2>
437   %6 = hlfir.designate %1#0 (%c9:%c9:%c1, %c1:%2#1:%c1)  shape %5 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<8x?xf32>>
438   %7 = fir.shape %4 : (index) -> !fir.shape<1>
439   %8 = hlfir.elemental %7 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
440   ^bb0(%arg1: index):
441     %10 = fir.alloca f32 {bindc_name = ".sum.reduction"}
442     fir.store %cst to %10 : !fir.ref<f32>
443     fir.do_loop %arg2 = %c1 to %c8 step %c1 unordered {
444       %12 = fir.load %10 : !fir.ref<f32>
445       %13 = hlfir.designate %6 (%arg2, %arg1)  : (!fir.box<!fir.array<8x?xf32>>, index, index) -> !fir.ref<f32>
446       %14 = fir.load %13 : !fir.ref<f32>
447       %15 = arith.addf %12, %14 fastmath<fast> : f32
448       fir.store %15 to %10 : !fir.ref<f32>
449     }
450     %11 = fir.load %10 : !fir.ref<f32>
451     hlfir.yield_element %11 : f32
452   }
453   %9 = hlfir.designate %1#0 (%c9, %c1:%2#1:%c1)  shape %7 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
454   hlfir.assign %8 to %9 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
455   hlfir.destroy %8 : !hlfir.expr<?xf32>
456   return
458 // CHECK-LABEL:   func.func @test_overlapping_triple_index(
459 // CHECK: hlfir.elemental
461 // Check that 'x(9:ub) = x(lb:6) + 1' is optimized,
462 // even though the lb and ub are unknown.
463 func.func @test_disjoint_unknown_bounds(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "lb"}, %arg2: !fir.ref<i32> {fir.bindc_name = "ub"}) {
464   %c-8 = arith.constant -8 : index
465   %c7 = arith.constant 7 : index
466   %c9 = arith.constant 9 : index
467   %cst = arith.constant 1.000000e+00 : f32
468   %c0 = arith.constant 0 : index
469   %c1 = arith.constant 1 : index
470   %c6 = arith.constant 6 : index
471   %0 = fir.dummy_scope : !fir.dscope
472   %1:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestElb"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
473   %2:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
474   %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
475   %4 = fir.load %1#0 : !fir.ref<i32>
476   %5 = fir.convert %4 : (i32) -> index
477   %6 = arith.subi %c7, %5 : index
478   %7 = arith.cmpi sgt, %6, %c0 : index
479   %8 = arith.select %7, %6, %c0 : index
480   %9 = fir.shape %8 : (index) -> !fir.shape<1>
481   %10 = hlfir.designate %3#0 (%5:%c6:%c1)  shape %9 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
482   %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
483   ^bb0(%arg3: index):
484     %19 = hlfir.designate %10 (%arg3)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
485     %20 = fir.load %19 : !fir.ref<f32>
486     %21 = arith.addf %20, %cst fastmath<fast> : f32
487     hlfir.yield_element %21 : f32
488   }
489   %12 = fir.load %2#0 : !fir.ref<i32>
490   %13 = fir.convert %12 : (i32) -> index
491   %14 = arith.addi %13, %c-8 : index
492   %15 = arith.cmpi sgt, %14, %c0 : index
493   %16 = arith.select %15, %14, %c0 : index
494   %17 = fir.shape %16 : (index) -> !fir.shape<1>
495   %18 = hlfir.designate %3#0 (%c9:%13:%c1)  shape %17 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
496   hlfir.assign %11 to %18 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
497   hlfir.destroy %11 : !hlfir.expr<?xf32>
498   return
500 // CHECK-LABEL:   func.func @test_disjoint_unknown_bounds(
501 // CHECK-NOT: hlfir.elemental
503 // Check that 'x(lb1:14) = x(lb2:15:-1) + 1' is optimized,
504 // even though lb1 and lb2 are unknown.
505 func.func @test_disjoint_unknown_bounds_negative_stride(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "lb1"}, %arg2: !fir.ref<i32> {fir.bindc_name = "lb2"}) {
506   %c1 = arith.constant 1 : index
507   %c14 = arith.constant 14 : index
508   %cst = arith.constant 1.000000e+00 : f32
509   %c0 = arith.constant 0 : index
510   %c-1 = arith.constant -1 : index
511   %c15 = arith.constant 15 : index
512   %0 = fir.dummy_scope : !fir.dscope
513   %1:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestElb1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
514   %2:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestElb2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
515   %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
516   %4 = fir.load %2#0 : !fir.ref<i32>
517   %5 = fir.convert %4 : (i32) -> index
518   %6 = arith.subi %c14, %5 : index
519   %7 = arith.divsi %6, %c-1 : index
520   %8 = arith.cmpi sgt, %7, %c0 : index
521   %9 = arith.select %8, %7, %c0 : index
522   %10 = fir.shape %9 : (index) -> !fir.shape<1>
523   %11 = hlfir.designate %3#0 (%5:%c15:%c-1)  shape %10 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
524   %12 = hlfir.elemental %10 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
525   ^bb0(%arg3: index):
526     %20 = hlfir.designate %11 (%arg3)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
527     %21 = fir.load %20 : !fir.ref<f32>
528     %22 = arith.addf %21, %cst fastmath<fast> : f32
529     hlfir.yield_element %22 : f32
530   }
531   %13 = fir.load %1#0 : !fir.ref<i32>
532   %14 = fir.convert %13 : (i32) -> index
533   %15 = arith.subi %c15, %14 : index
534   %16 = arith.cmpi sgt, %15, %c0 : index
535   %17 = arith.select %16, %15, %c0 : index
536   %18 = fir.shape %17 : (index) -> !fir.shape<1>
537   %19 = hlfir.designate %3#0 (%14:%c14:%c1)  shape %18 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
538   hlfir.assign %12 to %19 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
539   hlfir.destroy %12 : !hlfir.expr<?xf32>
540   return
542 // CHECK-LABEL:   func.func @test_disjoint_unknown_bounds_negative_stride(
543 // CHECK-NOT: hlfir.elemental
545 // Check that 'x(1:5) = x(5:1:-1) + 1' is not optimized.
546 func.func @test_overlap_known_triplets_negative_stride(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}) {
547   %cst = arith.constant 1.000000e+00 : f32
548   %c-1 = arith.constant -1 : index
549   %c1 = arith.constant 1 : index
550   %c5 = arith.constant 5 : index
551   %0 = fir.dummy_scope : !fir.dscope
552   %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
553   %2 = fir.shape %c5 : (index) -> !fir.shape<1>
554   %3 = hlfir.designate %1#0 (%c5:%c1:%c-1)  shape %2 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<5xf32>>
555   %4 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<5xf32> {
556   ^bb0(%arg1: index):
557     %6 = hlfir.designate %3 (%arg1)  : (!fir.box<!fir.array<5xf32>>, index) -> !fir.ref<f32>
558     %7 = fir.load %6 : !fir.ref<f32>
559     %8 = arith.addf %7, %cst fastmath<fast> : f32
560     hlfir.yield_element %8 : f32
561   }
562   %5 = hlfir.designate %1#0 (%c1:%c5:%c1)  shape %2 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<5xf32>>
563   hlfir.assign %4 to %5 : !hlfir.expr<5xf32>, !fir.box<!fir.array<5xf32>>
564   hlfir.destroy %4 : !hlfir.expr<5xf32>
565   return
567 // CHECK-LABEL:   func.func @test_overlap_known_triplets_negative_stride(
568 // CHECK: hlfir.elemental
570 // Check that 'x(1:5) = x(6:ub:-1) + 1' is not optimized.
571 func.func @test_overlap_unknown_bound_negative_stride(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "ub"}) {
572   %c-7 = arith.constant -7 : index
573   %c5 = arith.constant 5 : index
574   %c1 = arith.constant 1 : index
575   %cst = arith.constant 1.000000e+00 : f32
576   %c0 = arith.constant 0 : index
577   %c-1 = arith.constant -1 : index
578   %c6 = arith.constant 6 : index
579   %0 = fir.dummy_scope : !fir.dscope
580   %1:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
581   %2:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
582   %3 = fir.load %1#0 : !fir.ref<i32>
583   %4 = fir.convert %3 : (i32) -> index
584   %5 = arith.addi %4, %c-7 : index
585   %6 = arith.divsi %5, %c-1 : index
586   %7 = arith.cmpi sgt, %6, %c0 : index
587   %8 = arith.select %7, %6, %c0 : index
588   %9 = fir.shape %8 : (index) -> !fir.shape<1>
589   %10 = hlfir.designate %2#0 (%c6:%4:%c-1)  shape %9 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
590   %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
591   ^bb0(%arg2: index):
592     %14 = hlfir.designate %10 (%arg2)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
593     %15 = fir.load %14 : !fir.ref<f32>
594     %16 = arith.addf %15, %cst fastmath<fast> : f32
595     hlfir.yield_element %16 : f32
596   }
597   %12 = fir.shape %c5 : (index) -> !fir.shape<1>
598   %13 = hlfir.designate %2#0 (%c1:%c5:%c1)  shape %12 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<5xf32>>
599   hlfir.assign %11 to %13 : !hlfir.expr<?xf32>, !fir.box<!fir.array<5xf32>>
600   hlfir.destroy %11 : !hlfir.expr<?xf32>
601   return
603 // CHECK-LABEL:   func.func @test_overlap_unknown_bound_negative_stride(
604 // CHECK: hlfir.elemental
606 // Check that 'x(1:5) = x(6:ub:stride) + 1' is not optimized.
607 func.func @test_overlap_unknown_bound_and_stride(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "ub"}, %arg2: !fir.ref<i32> {fir.bindc_name = "stride"}) {
608   %c5 = arith.constant 5 : index
609   %c1 = arith.constant 1 : index
610   %cst = arith.constant 1.000000e+00 : f32
611   %c0 = arith.constant 0 : index
612   %c6 = arith.constant 6 : index
613   %0 = fir.dummy_scope : !fir.dscope
614   %1:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEstride"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
615   %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
616   %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
617   %4 = fir.load %2#0 : !fir.ref<i32>
618   %5 = fir.convert %4 : (i32) -> index
619   %6 = fir.load %1#0 : !fir.ref<i32>
620   %7 = fir.convert %6 : (i32) -> index
621   %8 = arith.subi %5, %c6 : index
622   %9 = arith.addi %8, %7 : index
623   %10 = arith.divsi %9, %7 : index
624   %11 = arith.cmpi sgt, %10, %c0 : index
625   %12 = arith.select %11, %10, %c0 : index
626   %13 = fir.shape %12 : (index) -> !fir.shape<1>
627   %14 = hlfir.designate %3#0 (%c6:%5:%7)  shape %13 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
628   %15 = hlfir.elemental %13 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
629   ^bb0(%arg3: index):
630     %18 = hlfir.designate %14 (%arg3)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
631     %19 = fir.load %18 : !fir.ref<f32>
632     %20 = arith.addf %19, %cst fastmath<fast> : f32
633     hlfir.yield_element %20 : f32
634   }
635   %16 = fir.shape %c5 : (index) -> !fir.shape<1>
636   %17 = hlfir.designate %3#0 (%c1:%c5:%c1)  shape %16 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<5xf32>>
637   hlfir.assign %15 to %17 : !hlfir.expr<?xf32>, !fir.box<!fir.array<5xf32>>
638   hlfir.destroy %15 : !hlfir.expr<?xf32>
639   return
641 // CHECK-LABEL:   func.func @test_overlap_unknown_bound_and_stride(
642 // CHECK: hlfir.elemental
644 // Check that 'a(2:2:s1) = a(2:2:s2) + 1' is optimized,
645 // even though the strides are unknown.
646 func.func @test_identical_1element_unknown_strides(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "s1"}, %arg2: !fir.ref<i32> {fir.bindc_name = "s2"}) {
647   %c1_i32 = arith.constant 1 : i32
648   %c0 = arith.constant 0 : index
649   %c2 = arith.constant 2 : index
650   %0 = fir.dummy_scope : !fir.dscope
651   %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
652   %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEs1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
653   %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEs2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
654   %4 = fir.load %3#0 : !fir.ref<i32>
655   %5 = fir.convert %4 : (i32) -> index
656   %6 = arith.divsi %5, %5 : index
657   %7 = arith.cmpi sgt, %6, %c0 : index
658   %8 = arith.select %7, %6, %c0 : index
659   %9 = fir.shape %8 : (index) -> !fir.shape<1>
660   %10 = hlfir.designate %1#0 (%c2:%c2:%5)  shape %9 : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
661   %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
662   ^bb0(%arg3: index):
663     %19 = hlfir.designate %10 (%arg3)  : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
664     %20 = fir.load %19 : !fir.ref<i32>
665     %21 = arith.addi %20, %c1_i32 : i32
666     hlfir.yield_element %21 : i32
667   }
668   %12 = fir.load %2#0 : !fir.ref<i32>
669   %13 = fir.convert %12 : (i32) -> index
670   %14 = arith.divsi %13, %13 : index
671   %15 = arith.cmpi sgt, %14, %c0 : index
672   %16 = arith.select %15, %14, %c0 : index
673   %17 = fir.shape %16 : (index) -> !fir.shape<1>
674   %18 = hlfir.designate %1#0 (%c2:%c2:%13)  shape %17 : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
675   hlfir.assign %11 to %18 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
676   hlfir.destroy %11 : !hlfir.expr<?xi32>
677   return
679 // CHECK-LABEL:   func.func @test_identical_1element_unknown_strides(
680 // CHECK-NOT: hlfir.elemental
682 func.func @test_disjoint_1element_unknown_strides(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "s1"}, %arg2: !fir.ref<i32> {fir.bindc_name = "s2"}) {
683   %c2 = arith.constant 2 : index
684   %c1_i32 = arith.constant 1 : i32
685   %c0 = arith.constant 0 : index
686   %c3 = arith.constant 3 : index
687   %0 = fir.dummy_scope : !fir.dscope
688   %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
689   %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEs1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
690   %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEs2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
691   %4 = fir.load %3#0 : !fir.ref<i32>
692   %5 = fir.convert %4 : (i32) -> index
693   %6 = arith.divsi %5, %5 : index
694   %7 = arith.cmpi sgt, %6, %c0 : index
695   %8 = arith.select %7, %6, %c0 : index
696   %9 = fir.shape %8 : (index) -> !fir.shape<1>
697   %10 = hlfir.designate %1#0 (%c3:%c3:%5)  shape %9 : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
698   %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
699   ^bb0(%arg3: index):
700     %19 = hlfir.designate %10 (%arg3)  : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
701     %20 = fir.load %19 : !fir.ref<i32>
702     %21 = arith.addi %20, %c1_i32 : i32
703     hlfir.yield_element %21 : i32
704   }
705   %12 = fir.load %2#0 : !fir.ref<i32>
706   %13 = fir.convert %12 : (i32) -> index
707   %14 = arith.divsi %13, %13 : index
708   %15 = arith.cmpi sgt, %14, %c0 : index
709   %16 = arith.select %15, %14, %c0 : index
710   %17 = fir.shape %16 : (index) -> !fir.shape<1>
711   %18 = hlfir.designate %1#0 (%c2:%c2:%13)  shape %17 : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
712   hlfir.assign %11 to %18 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
713   hlfir.destroy %11 : !hlfir.expr<?xi32>
714   return
716 // CHECK-LABEL:   func.func @test_disjoint_1element_unknown_strides(
717 // CHECK-NOT: hlfir.elemental
719 // Check that 'a(x:y:1) = a(z:x-1:-1) + 1' is not optimized.
720 // The bounds are like in Polyhedron/nf, but the second
721 // stride is negative, so it cannot be optimized.
722 func.func @test_overlap_sub1_negative_stride(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "x"}, %arg2: !fir.ref<i32> {fir.bindc_name = "y"}, %arg3: !fir.ref<i32> {fir.bindc_name = "z"}) {
723   %c1 = arith.constant 1 : index
724   %c0 = arith.constant 0 : index
725   %c-1 = arith.constant -1 : index
726   %c1_i32 = arith.constant 1 : i32
727   %0 = fir.dummy_scope : !fir.dscope
728   %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
729   %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
730   %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEy"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
731   %4:2 = hlfir.declare %arg3 dummy_scope %0 {uniq_name = "_QFtestEz"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
732   %5 = fir.load %4#0 : !fir.ref<i32>
733   %6 = fir.load %2#0 : !fir.ref<i32>
734   %7 = arith.subi %6, %c1_i32 overflow<nsw> : i32
735   %8 = fir.convert %5 : (i32) -> index
736   %9 = fir.convert %7 : (i32) -> index
737   %10 = arith.subi %9, %8 : index
738   %11 = arith.addi %10, %c-1 : index
739   %12 = arith.divsi %11, %c-1 : index
740   %13 = arith.cmpi sgt, %12, %c0 : index
741   %14 = arith.select %13, %12, %c0 : index
742   %15 = fir.shape %14 : (index) -> !fir.shape<1>
743   %16 = hlfir.designate %1#0 (%8:%9:%c-1)  shape %15 : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
744   %17 = hlfir.elemental %15 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
745   ^bb0(%arg4: index):
746     %27 = hlfir.designate %16 (%arg4)  : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
747     %28 = fir.load %27 : !fir.ref<i32>
748     %29 = arith.addi %28, %c1_i32 : i32
749     hlfir.yield_element %29 : i32
750   }
751   %18 = fir.load %3#0 : !fir.ref<i32>
752   %19 = fir.convert %6 : (i32) -> index
753   %20 = fir.convert %18 : (i32) -> index
754   %21 = arith.subi %20, %19 : index
755   %22 = arith.addi %21, %c1 : index
756   %23 = arith.cmpi sgt, %22, %c0 : index
757   %24 = arith.select %23, %22, %c0 : index
758   %25 = fir.shape %24 : (index) -> !fir.shape<1>
759   %26 = hlfir.designate %1#0 (%19:%20:%c1)  shape %25 : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
760   hlfir.assign %17 to %26 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
761   hlfir.destroy %17 : !hlfir.expr<?xi32>
762   return
764 // CHECK-LABEL:   func.func @test_overlap_sub1_negative_stride(
765 // CHECK: hlfir.elemental
767 // Check that 'x(1:5) = x(16:8:stride) + 1' is not optimized.
768 // TODO: because the bounds are known, we can still deduce
769 // no overlap:
770 //   * If stride is negative, then (1:5) does not overlap
771 //     with (8:16).
772 //   * If stride is positive, then (16:8:stride) is an empty
773 //     slice, thus it does not overlap with (1:5).
774 func.func @test_disjoint_known_bounds_unknown_stride(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "ub"}, %arg2: !fir.ref<i32> {fir.bindc_name = "stride"}) {
775   %c-8 = arith.constant -8 : index
776   %c5 = arith.constant 5 : index
777   %c1 = arith.constant 1 : index
778   %cst = arith.constant 1.000000e+00 : f32
779   %c0 = arith.constant 0 : index
780   %c8 = arith.constant 8 : index
781   %c16 = arith.constant 16 : index
782   %0 = fir.dummy_scope : !fir.dscope
783   %1:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEstride"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
784   %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
785   %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
786   %4 = fir.load %1#0 : !fir.ref<i32>
787   %5 = fir.convert %4 : (i32) -> index
788   %6 = arith.addi %5, %c-8 : index
789   %7 = arith.divsi %6, %5 : index
790   %8 = arith.cmpi sgt, %7, %c0 : index
791   %9 = arith.select %8, %7, %c0 : index
792   %10 = fir.shape %9 : (index) -> !fir.shape<1>
793   %11 = hlfir.designate %3#0 (%c16:%c8:%5)  shape %10 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
794   %12 = hlfir.elemental %10 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
795   ^bb0(%arg3: index):
796     %15 = hlfir.designate %11 (%arg3)  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
797     %16 = fir.load %15 : !fir.ref<f32>
798     %17 = arith.addf %16, %cst fastmath<fast> : f32
799     hlfir.yield_element %17 : f32
800   }
801   %13 = fir.shape %c5 : (index) -> !fir.shape<1>
802   %14 = hlfir.designate %3#0 (%c1:%c5:%c1)  shape %13 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<5xf32>>
803   hlfir.assign %12 to %14 : !hlfir.expr<?xf32>, !fir.box<!fir.array<5xf32>>
804   hlfir.destroy %12 : !hlfir.expr<?xf32>
805   return
807 // CHECK-LABEL:   func.func @test_disjoint_known_bounds_unknown_stride(
808 // CHECK: hlfir.elemental