brintos

brintos / llvm-project-archived public Read only

0
0
Text · 45.3 KiB · 3db47b1 Raw
809 lines · plain
1// Test optimized bufferization for hlfir.assign of array2// 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 identical5// or completely disjoint. In case they are identical, we still6// need to make sure that the one-based indices are used7// uniformly for both LHS and RHS.8// RUN: fir-opt --opt-bufferization %s | FileCheck %s9 10func.func @_QPtest1(%arg0: !fir.ref<!fir.array<8000x120x3xf32>> {fir.bindc_name = "x"}) {11  %c7998 = arith.constant 7998 : index12  %c1 = arith.constant 1 : index13  %c7999 = arith.constant 7999 : index14  %c2 = arith.constant 2 : index15  %c3 = arith.constant 3 : index16  %c120 = arith.constant 120 : index17  %c8000 = arith.constant 8000 : index18  %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) -> i6426  %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 : f3233    hlfir.yield_element %16 : f3234  }35  %11 = fir.load %1#0 : !fir.ref<i32>36  %12 = fir.convert %11 : (i32) -> i6437  %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  return41}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]] : f3248// 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:           }52 53func.func @_QPtest2(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>> {fir.bindc_name = "x"}) {54  %c120 = arith.constant 120 : index55  %c7998 = arith.constant 7998 : index56  %c1 = arith.constant 1 : index57  %c7999 = arith.constant 7999 : index58  %c2 = arith.constant 2 : index59  %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 : f3268    hlfir.yield_element %8 : f3269  }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  return74}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]] : f3281// 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:           }85 86func.func @_QPtest3(%arg0: !fir.ref<!fir.array<10x!fir.type<_QMtypesTt{x:!fir.array<8000x120x3xf32>}>>> {fir.bindc_name = "x"}) {87  %c7998 = arith.constant 7998 : index88  %c7999 = arith.constant 7999 : index89  %c2 = arith.constant 2 : index90  %c3 = arith.constant 3 : index91  %c120 = arith.constant 120 : index92  %c8000 = arith.constant 8000 : index93  %c1 = arith.constant 1 : index94  %c10 = arith.constant 10 : index95  %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) -> i64105  %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 : f32112    hlfir.yield_element %18 : f32113  }114  %13 = fir.load %1#0 : !fir.ref<i32>115  %14 = fir.convert %13 : (i32) -> i64116  %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  return120}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]] : f32127// 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:           }131 132// ! ub == lb - 1133// subroutine test4(x, i1, i2, nx)134//   real :: x(i2), f135//   do i=i1,i2,nx136//      x(i:i+nx-1) = (x(i-nx:i-1))137//   end do138// end subroutine test4139func.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 : index141  %c1_i32 = arith.constant 1 : i32142  %c0 = arith.constant 0 : index143  %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) -> index152  %9 = arith.cmpi sgt, %8, %c0 : index153  %10 = arith.select %9, %8, %c0 : index154  %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) -> index158  %15 = fir.load %5#0 : !fir.ref<i32>159  %16 = fir.convert %15 : (i32) -> index160  %17 = fir.load %6#0 : !fir.ref<i32>161  %18 = fir.convert %17 : (i32) -> index162  %19 = fir.convert %14 : (index) -> i32163  %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 : i32168    %24 = arith.subi %21, %c1_i32 : i32169    %25 = fir.convert %23 : (i32) -> index170    %26 = fir.convert %24 : (i32) -> index171    %27 = arith.subi %26, %25 : index172    %28 = arith.addi %27, %c1 : index173    %29 = arith.cmpi sgt, %28, %c0 : index174    %30 = arith.select %29, %28, %c0 : index175    %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 : f32182      hlfir.yield_element %50 : f32183    }184    %34 = arith.addi %21, %22 : i32185    %35 = arith.subi %34, %c1_i32 : i32186    %36 = fir.convert %21 : (i32) -> index187    %37 = fir.convert %35 : (i32) -> index188    %38 = arith.subi %37, %36 : index189    %39 = arith.addi %38, %c1 : index190    %40 = arith.cmpi sgt, %39, %c0 : index191    %41 = arith.select %40, %39, %c0 : index192    %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 : index197    %45 = fir.convert %18 : (index) -> i32198    %46 = fir.load %3#1 : !fir.ref<i32>199    %47 = arith.addi %46, %45 : i32200    fir.result %44, %47 : index, i32201  }202  fir.store %20#1 to %3#1 : !fir.ref<i32>203  return204}205// CHECK-LABEL:   func.func @_QPtest4(206// CHECK-NOT: hlfir.elemental207 208// ! lb == ub + 1209// subroutine test5(x, i1, i2, nx)210//   real :: x(i2), f211//   do i=i1,i2,nx212//      x(i+1:i+nx-1) = (x(i-nx:i))213//   end do214// end subroutine test5215func.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 : i32217  %c1 = arith.constant 1 : index218  %c0 = arith.constant 0 : index219  %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) -> index228  %9 = arith.cmpi sgt, %8, %c0 : index229  %10 = arith.select %9, %8, %c0 : index230  %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) -> index234  %15 = fir.load %5#0 : !fir.ref<i32>235  %16 = fir.convert %15 : (i32) -> index236  %17 = fir.load %6#0 : !fir.ref<i32>237  %18 = fir.convert %17 : (i32) -> index238  %19 = fir.convert %14 : (index) -> i32239  %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 : i32244    %24 = fir.convert %23 : (i32) -> index245    %25 = fir.convert %21 : (i32) -> index246    %26 = arith.subi %25, %24 : index247    %27 = arith.addi %26, %c1 : index248    %28 = arith.cmpi sgt, %27, %c0 : index249    %29 = arith.select %28, %27, %c0 : index250    %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 : f32257      hlfir.yield_element %50 : f32258    }259    %33 = arith.addi %21, %c1_i32 : i32260    %34 = arith.addi %21, %22 : i32261    %35 = arith.subi %34, %c1_i32 : i32262    %36 = fir.convert %33 : (i32) -> index263    %37 = fir.convert %35 : (i32) -> index264    %38 = arith.subi %37, %36 : index265    %39 = arith.addi %38, %c1 : index266    %40 = arith.cmpi sgt, %39, %c0 : index267    %41 = arith.select %40, %39, %c0 : index268    %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 : index273    %45 = fir.convert %18 : (index) -> i32274    %46 = fir.load %3#1 : !fir.ref<i32>275    %47 = arith.addi %46, %45 : i32276    fir.result %44, %47 : index, i32277  }278  fir.store %20#1 to %3#1 : !fir.ref<i32>279  return280}281// CHECK-LABEL:   func.func @_QPtest5(282// CHECK-NOT: hlfir.elemental283 284// ! ub = lb - 1 and dim1 is unknown285// ! FIR lowering produces a temp.286// subroutine test6(x, i1, i2, nx)287//   real :: x(i2,i2), f288//   integer n1, n2, n3, n4289//   do i=i1,i2,nx290//      x(i:i+nx-1,n1:n2) = (x(i-nx:i-1,n3:n4))291//   end do292// end subroutine test6293func.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 : index295  %c1_i32 = arith.constant 1 : i32296  %c0 = arith.constant 0 : index297  %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) -> index314  %17 = arith.cmpi sgt, %16, %c0 : index315  %18 = arith.select %17, %16, %c0 : index316  %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) -> index320  %23 = fir.load %5#0 : !fir.ref<i32>321  %24 = fir.convert %23 : (i32) -> index322  %25 = fir.load %14#0 : !fir.ref<i32>323  %26 = fir.convert %25 : (i32) -> index324  %27 = fir.convert %22 : (index) -> i32325  %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 : i32330    %32 = arith.subi %29, %c1_i32 : i32331    %33 = fir.convert %31 : (i32) -> index332    %34 = fir.convert %32 : (i32) -> index333    %35 = arith.subi %34, %33 : index334    %36 = arith.addi %35, %c1 : index335    %37 = arith.cmpi sgt, %36, %c0 : index336    %38 = arith.select %37, %36, %c0 : index337    %39 = fir.load %11#0 : !fir.ref<i32>338    %40 = fir.load %13#0 : !fir.ref<i32>339    %41 = fir.convert %39 : (i32) -> index340    %42 = fir.convert %40 : (i32) -> index341    %43 = arith.subi %42, %41 : index342    %44 = arith.addi %43, %c1 : index343    %45 = arith.cmpi sgt, %44, %c0 : index344    %46 = arith.select %45, %44, %c0 : index345    %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 : f32352      hlfir.yield_element %74 : f32353    }354    %50 = arith.addi %29, %30 : i32355    %51 = arith.subi %50, %c1_i32 : i32356    %52 = fir.convert %29 : (i32) -> index357    %53 = fir.convert %51 : (i32) -> index358    %54 = arith.subi %53, %52 : index359    %55 = arith.addi %54, %c1 : index360    %56 = arith.cmpi sgt, %55, %c0 : index361    %57 = arith.select %56, %55, %c0 : index362    %58 = fir.load %7#0 : !fir.ref<i32>363    %59 = fir.load %9#0 : !fir.ref<i32>364    %60 = fir.convert %58 : (i32) -> index365    %61 = fir.convert %59 : (i32) -> index366    %62 = arith.subi %61, %60 : index367    %63 = arith.addi %62, %c1 : index368    %64 = arith.cmpi sgt, %63, %c0 : index369    %65 = arith.select %64, %63, %c0 : index370    %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 : index375    %69 = fir.convert %26 : (index) -> i32376    %70 = fir.load %3#1 : !fir.ref<i32>377    %71 = arith.addi %70, %69 : i32378    fir.result %68, %71 : index, i32379  }380  fir.store %28#1 to %3#1 : !fir.ref<i32>381  return382}383// CHECK-LABEL:   func.func @_QPtest6(384// CHECK-NOT: hlfir.elemental385 386// Check that 'x(9,:)=SUM(x(1:8,:),DIM=1)' is optimized387// due to the LHS and RHS being disjoint array sections.388func.func @test_disjoint_triple_index(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {389  %cst = arith.constant 0.000000e+00 : f32390  %c9 = arith.constant 9 : index391  %c0 = arith.constant 0 : index392  %c8 = arith.constant 8 : index393  %c1 = arith.constant 1 : index394  %0 = fir.dummy_scope : !fir.dscope395  %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 : index398  %4 = arith.select %3, %2#1, %c0 : index399  %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> : f32411      fir.store %15 to %10 : !fir.ref<f32>412    }413    %11 = fir.load %10 : !fir.ref<f32>414    hlfir.yield_element %11 : f32415  }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  return420}421// CHECK-LABEL:   func.func @test_disjoint_triple_index(422// CHECK-NOT: hlfir.elemental423 424// Check that 'x(9,:)=SUM(x(9:9,:),DIM=1)' is not optimized.425func.func @test_overlapping_triple_index(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {426  %cst = arith.constant 0.000000e+00 : f32427  %c9 = arith.constant 9 : index428  %c0 = arith.constant 0 : index429  %c8 = arith.constant 8 : index430  %c1 = arith.constant 1 : index431  %0 = fir.dummy_scope : !fir.dscope432  %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 : index435  %4 = arith.select %3, %2#1, %c0 : index436  %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> : f32448      fir.store %15 to %10 : !fir.ref<f32>449    }450    %11 = fir.load %10 : !fir.ref<f32>451    hlfir.yield_element %11 : f32452  }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  return457}458// CHECK-LABEL:   func.func @test_overlapping_triple_index(459// CHECK: hlfir.elemental460 461// Check that 'x(9:ub) = x(lb:6) + 1' is optimized,462// even though the lb and ub are unknown.463func.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 : index465  %c7 = arith.constant 7 : index466  %c9 = arith.constant 9 : index467  %cst = arith.constant 1.000000e+00 : f32468  %c0 = arith.constant 0 : index469  %c1 = arith.constant 1 : index470  %c6 = arith.constant 6 : index471  %0 = fir.dummy_scope : !fir.dscope472  %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) -> index477  %6 = arith.subi %c7, %5 : index478  %7 = arith.cmpi sgt, %6, %c0 : index479  %8 = arith.select %7, %6, %c0 : index480  %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> : f32487    hlfir.yield_element %21 : f32488  }489  %12 = fir.load %2#0 : !fir.ref<i32>490  %13 = fir.convert %12 : (i32) -> index491  %14 = arith.addi %13, %c-8 : index492  %15 = arith.cmpi sgt, %14, %c0 : index493  %16 = arith.select %15, %14, %c0 : index494  %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  return499}500// CHECK-LABEL:   func.func @test_disjoint_unknown_bounds(501// CHECK-NOT: hlfir.elemental502 503// Check that 'x(lb1:14) = x(lb2:15:-1) + 1' is optimized,504// even though lb1 and lb2 are unknown.505func.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 : index507  %c14 = arith.constant 14 : index508  %cst = arith.constant 1.000000e+00 : f32509  %c0 = arith.constant 0 : index510  %c-1 = arith.constant -1 : index511  %c15 = arith.constant 15 : index512  %0 = fir.dummy_scope : !fir.dscope513  %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) -> index518  %6 = arith.subi %c14, %5 : index519  %7 = arith.divsi %6, %c-1 : index520  %8 = arith.cmpi sgt, %7, %c0 : index521  %9 = arith.select %8, %7, %c0 : index522  %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> : f32529    hlfir.yield_element %22 : f32530  }531  %13 = fir.load %1#0 : !fir.ref<i32>532  %14 = fir.convert %13 : (i32) -> index533  %15 = arith.subi %c15, %14 : index534  %16 = arith.cmpi sgt, %15, %c0 : index535  %17 = arith.select %16, %15, %c0 : index536  %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  return541}542// CHECK-LABEL:   func.func @test_disjoint_unknown_bounds_negative_stride(543// CHECK-NOT: hlfir.elemental544 545// Check that 'x(1:5) = x(5:1:-1) + 1' is not optimized.546func.func @test_overlap_known_triplets_negative_stride(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}) {547  %cst = arith.constant 1.000000e+00 : f32548  %c-1 = arith.constant -1 : index549  %c1 = arith.constant 1 : index550  %c5 = arith.constant 5 : index551  %0 = fir.dummy_scope : !fir.dscope552  %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> : f32560    hlfir.yield_element %8 : f32561  }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  return566}567// CHECK-LABEL:   func.func @test_overlap_known_triplets_negative_stride(568// CHECK: hlfir.elemental569 570// Check that 'x(1:5) = x(6:ub:-1) + 1' is not optimized.571func.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 : index573  %c5 = arith.constant 5 : index574  %c1 = arith.constant 1 : index575  %cst = arith.constant 1.000000e+00 : f32576  %c0 = arith.constant 0 : index577  %c-1 = arith.constant -1 : index578  %c6 = arith.constant 6 : index579  %0 = fir.dummy_scope : !fir.dscope580  %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) -> index584  %5 = arith.addi %4, %c-7 : index585  %6 = arith.divsi %5, %c-1 : index586  %7 = arith.cmpi sgt, %6, %c0 : index587  %8 = arith.select %7, %6, %c0 : index588  %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> : f32595    hlfir.yield_element %16 : f32596  }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  return602}603// CHECK-LABEL:   func.func @test_overlap_unknown_bound_negative_stride(604// CHECK: hlfir.elemental605 606// Check that 'x(1:5) = x(6:ub:stride) + 1' is not optimized.607func.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 : index609  %c1 = arith.constant 1 : index610  %cst = arith.constant 1.000000e+00 : f32611  %c0 = arith.constant 0 : index612  %c6 = arith.constant 6 : index613  %0 = fir.dummy_scope : !fir.dscope614  %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) -> index619  %6 = fir.load %1#0 : !fir.ref<i32>620  %7 = fir.convert %6 : (i32) -> index621  %8 = arith.subi %5, %c6 : index622  %9 = arith.addi %8, %7 : index623  %10 = arith.divsi %9, %7 : index624  %11 = arith.cmpi sgt, %10, %c0 : index625  %12 = arith.select %11, %10, %c0 : index626  %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> : f32633    hlfir.yield_element %20 : f32634  }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  return640}641// CHECK-LABEL:   func.func @test_overlap_unknown_bound_and_stride(642// CHECK: hlfir.elemental643 644// Check that 'a(2:2:s1) = a(2:2:s2) + 1' is optimized,645// even though the strides are unknown.646func.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 : i32648  %c0 = arith.constant 0 : index649  %c2 = arith.constant 2 : index650  %0 = fir.dummy_scope : !fir.dscope651  %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) -> index656  %6 = arith.divsi %5, %5 : index657  %7 = arith.cmpi sgt, %6, %c0 : index658  %8 = arith.select %7, %6, %c0 : index659  %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 : i32666    hlfir.yield_element %21 : i32667  }668  %12 = fir.load %2#0 : !fir.ref<i32>669  %13 = fir.convert %12 : (i32) -> index670  %14 = arith.divsi %13, %13 : index671  %15 = arith.cmpi sgt, %14, %c0 : index672  %16 = arith.select %15, %14, %c0 : index673  %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  return678}679// CHECK-LABEL:   func.func @test_identical_1element_unknown_strides(680// CHECK-NOT: hlfir.elemental681 682func.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 : index684  %c1_i32 = arith.constant 1 : i32685  %c0 = arith.constant 0 : index686  %c3 = arith.constant 3 : index687  %0 = fir.dummy_scope : !fir.dscope688  %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) -> index693  %6 = arith.divsi %5, %5 : index694  %7 = arith.cmpi sgt, %6, %c0 : index695  %8 = arith.select %7, %6, %c0 : index696  %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 : i32703    hlfir.yield_element %21 : i32704  }705  %12 = fir.load %2#0 : !fir.ref<i32>706  %13 = fir.convert %12 : (i32) -> index707  %14 = arith.divsi %13, %13 : index708  %15 = arith.cmpi sgt, %14, %c0 : index709  %16 = arith.select %15, %14, %c0 : index710  %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  return715}716// CHECK-LABEL:   func.func @test_disjoint_1element_unknown_strides(717// CHECK-NOT: hlfir.elemental718 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 second721// stride is negative, so it cannot be optimized.722func.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 : index724  %c0 = arith.constant 0 : index725  %c-1 = arith.constant -1 : index726  %c1_i32 = arith.constant 1 : i32727  %0 = fir.dummy_scope : !fir.dscope728  %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> : i32735  %8 = fir.convert %5 : (i32) -> index736  %9 = fir.convert %7 : (i32) -> index737  %10 = arith.subi %9, %8 : index738  %11 = arith.addi %10, %c-1 : index739  %12 = arith.divsi %11, %c-1 : index740  %13 = arith.cmpi sgt, %12, %c0 : index741  %14 = arith.select %13, %12, %c0 : index742  %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 : i32749    hlfir.yield_element %29 : i32750  }751  %18 = fir.load %3#0 : !fir.ref<i32>752  %19 = fir.convert %6 : (i32) -> index753  %20 = fir.convert %18 : (i32) -> index754  %21 = arith.subi %20, %19 : index755  %22 = arith.addi %21, %c1 : index756  %23 = arith.cmpi sgt, %22, %c0 : index757  %24 = arith.select %23, %22, %c0 : index758  %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  return763}764// CHECK-LABEL:   func.func @test_overlap_sub1_negative_stride(765// CHECK: hlfir.elemental766 767// Check that 'x(1:5) = x(16:8:stride) + 1' is not optimized.768// TODO: because the bounds are known, we can still deduce769// no overlap:770//   * If stride is negative, then (1:5) does not overlap771//     with (8:16).772//   * If stride is positive, then (16:8:stride) is an empty773//     slice, thus it does not overlap with (1:5).774func.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 : index776  %c5 = arith.constant 5 : index777  %c1 = arith.constant 1 : index778  %cst = arith.constant 1.000000e+00 : f32779  %c0 = arith.constant 0 : index780  %c8 = arith.constant 8 : index781  %c16 = arith.constant 16 : index782  %0 = fir.dummy_scope : !fir.dscope783  %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) -> index788  %6 = arith.addi %5, %c-8 : index789  %7 = arith.divsi %6, %5 : index790  %8 = arith.cmpi sgt, %7, %c0 : index791  %9 = arith.select %8, %7, %c0 : index792  %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> : f32799    hlfir.yield_element %17 : f32800  }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  return806}807// CHECK-LABEL:   func.func @test_disjoint_known_bounds_unknown_stride(808// CHECK: hlfir.elemental809