220 lines · plain
1// Test affine promotion pass2 3// RUN: fir-opt --split-input-file --promote-to-affine --affine-loop-invariant-code-motion --cse %s | FileCheck %s4 5!arr_d1 = !fir.ref<!fir.array<?xf32>>6#arr_len = affine_map<()[j1,k1] -> (k1 - j1 + 1)>7 8func.func @loop_with_load_and_store(%a1: !arr_d1, %a2: !arr_d1, %a3: !arr_d1) {9 %c1 = arith.constant 1 : index10 %c0 = arith.constant 0 : index11 %len = arith.constant 100 : index12 %dims = fir.shape %len : (index) -> !fir.shape<1>13 %siz = affine.apply #arr_len()[%c1,%len]14 %t1 = fir.alloca !fir.array<?xf32>, %siz15 16 fir.do_loop %i = %c1 to %len step %c1 {17 %a1_idx = fir.array_coor %a1(%dims) %i18 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>19 %a1_v = fir.load %a1_idx : !fir.ref<f32>20 21 %a2_idx = fir.array_coor %a2(%dims) %i22 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>23 %a2_v = fir.load %a2_idx : !fir.ref<f32>24 25 %v = arith.addf %a1_v, %a2_v : f3226 %t1_idx = fir.array_coor %t1(%dims) %i27 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>28 29 fir.store %v to %t1_idx : !fir.ref<f32>30 }31 fir.do_loop %i = %c1 to %len step %c1 {32 %t1_idx = fir.array_coor %t1(%dims) %i33 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>34 %t1_v = fir.load %t1_idx : !fir.ref<f32>35 36 %a2_idx = fir.array_coor %a2(%dims) %i37 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>38 %a2_v = fir.load %a2_idx : !fir.ref<f32>39 40 %v = arith.mulf %t1_v, %a2_v : f3241 %a3_idx = fir.array_coor %a3(%dims) %i42 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>43 44 fir.store %v to %a3_idx : !fir.ref<f32>45 }46 return47}48 49// CHECK: func @loop_with_load_and_store(%[[VAL_0:.*]]: !fir.ref<!fir.array<?xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<?xf32>>, %[[VAL_2:.*]]: !fir.ref<!fir.array<?xf32>>) {50// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index51// CHECK: %[[VAL_4:.*]] = arith.constant 100 : index52// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>53// CHECK: %[[VAL_6:.*]] = affine.apply #{{.*}}(){{\[}}%[[VAL_3]], %[[VAL_4]]]54// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<?xf32>, %[[VAL_6]]55// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<?xf32>>) -> memref<?xf32>56// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<?xf32>>) -> memref<?xf32>57// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.array<?xf32>>) -> memref<?xf32>58// CHECK: affine.for %[[VAL_11:.*]] = %[[VAL_3]] to #{{.*}}(){{\[}}%[[VAL_4]]] {59// CHECK: %[[VAL_12:.*]] = affine.apply #{{.*}}(%[[VAL_11]]){{\[}}%[[VAL_3]], %[[VAL_4]], %[[VAL_3]]]60// CHECK: %[[VAL_13:.*]] = affine.load %[[VAL_8]]{{\[}}%[[VAL_12]]] : memref<?xf32>61// CHECK: %[[VAL_14:.*]] = affine.load %[[VAL_9]]{{\[}}%[[VAL_12]]] : memref<?xf32>62// CHECK: %[[VAL_15:.*]] = arith.addf %[[VAL_13]], %[[VAL_14]] : f3263// CHECK: affine.store %[[VAL_15]], %[[VAL_10]]{{\[}}%[[VAL_12]]] : memref<?xf32>64// CHECK: }65// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.array<?xf32>>) -> memref<?xf32>66// CHECK: affine.for %[[VAL_17:.*]] = %[[VAL_3]] to #{{.*}}(){{\[}}%[[VAL_4]]] {67// CHECK: %[[VAL_18:.*]] = affine.apply #{{.*}}(%[[VAL_17]]){{\[}}%[[VAL_3]], %[[VAL_4]], %[[VAL_3]]]68// CHECK: %[[VAL_19:.*]] = affine.load %[[VAL_10]]{{\[}}%[[VAL_18]]] : memref<?xf32>69// CHECK: %[[VAL_20:.*]] = affine.load %[[VAL_9]]{{\[}}%[[VAL_18]]] : memref<?xf32>70// CHECK: %[[VAL_21:.*]] = arith.mulf %[[VAL_19]], %[[VAL_20]] : f3271// CHECK: affine.store %[[VAL_21]], %[[VAL_16]]{{\[}}%[[VAL_18]]] : memref<?xf32>72// CHECK: }73// CHECK: return74// CHECK: }75 76// -----77 78!arr_d1 = !fir.ref<!fir.array<?xf32>>79#arr_len = affine_map<()[j1,k1] -> (k1 - j1 + 1)>80 81func.func @loop_with_if(%a: !arr_d1, %v: f32) {82 %c0 = arith.constant 0 : index83 %c1 = arith.constant 1 : index84 %c2 = arith.constant 2 : index85 %len = arith.constant 100 : index86 %dims = fir.shape %len : (index) -> !fir.shape<1>87 88 fir.do_loop %i = %c1 to %len step %c1 {89 fir.do_loop %j = %c1 to %len step %c1 {90 fir.do_loop %k = %c1 to %len step %c1 {91 %im2 = arith.subi %i, %c2 : index92 %cond = arith.cmpi "sgt", %im2, %c0 : index93 fir.if %cond {94 %a_idx = fir.array_coor %a(%dims) %i95 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>96 fir.store %v to %a_idx : !fir.ref<f32>97 }98 %aj_idx = fir.array_coor %a(%dims) %j99 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>100 fir.store %v to %aj_idx : !fir.ref<f32>101 %ak_idx = fir.array_coor %a(%dims) %k102 : (!arr_d1, !fir.shape<1>, index) -> !fir.ref<f32>103 fir.store %v to %ak_idx : !fir.ref<f32>104 }105 }106 }107 return108}109 110// CHECK: func @loop_with_if(%[[VAL_0:.*]]: !fir.ref<!fir.array<?xf32>>, %[[VAL_1:.*]]: f32) {111// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index112// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index113// CHECK: %[[VAL_4:.*]] = arith.constant 2 : index114// CHECK: %[[VAL_5:.*]] = arith.constant 100 : index115// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>116// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<?xf32>>) -> memref<?xf32>117// CHECK: affine.for %[[VAL_8:.*]] = %[[VAL_3]] to #{{.*}}(){{\[}}%[[VAL_5]]] {118// CHECK: %[[VAL_9:.*]] = affine.apply #{{.*}}(%[[VAL_8]]){{\[}}%[[VAL_3]], %[[VAL_5]], %[[VAL_3]]]119// CHECK: affine.store %[[VAL_1]], %[[VAL_7]]{{\[}}%[[VAL_9]]] : memref<?xf32>120// CHECK: }121// CHECK: affine.for %[[VAL_10:.*]] = %[[VAL_3]] to #{{.*}}(){{\[}}%[[VAL_5]]] {122// CHECK: %[[VAL_11:.*]] = affine.apply #{{.*}}(%[[VAL_10]]){{\[}}%[[VAL_3]], %[[VAL_5]], %[[VAL_3]]]123// CHECK: affine.store %[[VAL_1]], %[[VAL_7]]{{\[}}%[[VAL_11]]] : memref<?xf32>124// CHECK: }125// CHECK: affine.for %[[VAL_12:.*]] = %[[VAL_3]] to #{{.*}}(){{\[}}%[[VAL_5]]] {126// CHECK: %[[VAL_13:.*]] = arith.subi %[[VAL_12]], %[[VAL_4]] : index127// CHECK: affine.if #set(%[[VAL_12]]) {128// CHECK: %[[VAL_14:.*]] = affine.apply #{{.*}}(%[[VAL_12]]){{\[}}%[[VAL_3]], %[[VAL_5]], %[[VAL_3]]]129// CHECK: affine.store %[[VAL_1]], %[[VAL_7]]{{\[}}%[[VAL_14]]] : memref<?xf32>130// CHECK: }131// CHECK: }132// CHECK: return133// CHECK: }134 135func.func @loop_with_result(%arg0: !fir.ref<!fir.array<100xf32>>, %arg1: !fir.ref<!fir.array<100x100xf32>>, %arg2: !fir.ref<!fir.array<100xf32>>) -> f32 {136 %c1 = arith.constant 1 : index137 %cst = arith.constant 0.000000e+00 : f32138 %c100 = arith.constant 100 : index139 %0 = fir.shape %c100 : (index) -> !fir.shape<1>140 %1 = fir.shape %c100, %c100 : (index, index) -> !fir.shape<2>141 %2 = fir.alloca i32142 %3:2 = fir.do_loop %arg3 = %c1 to %c100 step %c1 iter_args(%arg4 = %cst) -> (index, f32) {143 %8 = fir.array_coor %arg0(%0) %arg3 : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>144 %9 = fir.load %8 : !fir.ref<f32>145 %10 = arith.addf %arg4, %9 fastmath<contract> : f32146 %11 = arith.addi %arg3, %c1 overflow<nsw> : index147 fir.result %11, %10 : index, f32148 }149 %4:2 = fir.do_loop %arg3 = %c1 to %c100 step %c1 iter_args(%arg4 = %3#1) -> (index, f32) {150 %8 = fir.array_coor %arg1(%1) %c1, %arg3 : (!fir.ref<!fir.array<100x100xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>151 %9 = fir.convert %8 : (!fir.ref<f32>) -> !fir.ref<!fir.array<100xf32>>152 %10 = fir.do_loop %arg5 = %c1 to %c100 step %c1 iter_args(%arg6 = %arg4) -> (f32) {153 %12 = fir.array_coor %9(%0) %arg5 : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>154 %13 = fir.load %12 : !fir.ref<f32>155 %14 = arith.addf %arg6, %13 fastmath<contract> : f32156 fir.result %14 : f32157 }158 %11 = arith.addi %arg3, %c1 overflow<nsw> : index159 fir.result %11, %10 : index, f32160 }161 %5:2 = fir.do_loop %arg3 = %c1 to %c100 step %c1 iter_args(%arg4 = %4#1, %arg5 = %cst) -> (f32, f32) {162 %8 = fir.array_coor %arg0(%0) %arg3 : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>163 %9 = fir.load %8 : !fir.ref<f32>164 %10 = arith.addf %arg4, %9 fastmath<contract> : f32165 %11 = fir.array_coor %arg2(%0) %arg3 : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>166 %12 = fir.load %11 : !fir.ref<f32>167 %13 = arith.addf %arg5, %12 fastmath<contract> : f32168 fir.result %10, %13 : f32, f32169 }170 %6 = arith.addf %5#0, %5#1 fastmath<contract> : f32171 %7 = fir.convert %4#0 : (index) -> i32172 fir.store %7 to %2 : !fir.ref<i32>173 return %6 : f32174}175 176// CHECK-LABEL: func.func @loop_with_result(177// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<100xf32>>,178// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.array<100x100xf32>>,179// CHECK-SAME: %[[ARG2:.*]]: !fir.ref<!fir.array<100xf32>>) -> f32 {180// CHECK: %[[VAL_0:.*]] = arith.constant 1 : index181// CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32182// CHECK: %[[VAL_2:.*]] = arith.constant 100 : index183// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>184// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shape<2>185// CHECK: %[[VAL_5:.*]] = fir.alloca i32186// CHECK: %[[VAL_6:.*]] = fir.convert %[[ARG0]] : (!fir.ref<!fir.array<100xf32>>) -> memref<?xf32>187// CHECK: %[[VAL_7:.*]] = affine.for %[[VAL_8:.*]] = %[[VAL_0]] to #{{.*}}(){{\[}}%[[VAL_2]]] iter_args(%[[VAL_9:.*]] = %[[VAL_1]]) -> (f32) {188// CHECK: %[[VAL_10:.*]] = affine.apply #{{.*}}(%[[VAL_8]]){{\[}}%[[VAL_0]], %[[VAL_2]], %[[VAL_0]]]189// CHECK: %[[VAL_11:.*]] = affine.load %[[VAL_6]]{{\[}}%[[VAL_10]]] : memref<?xf32>190// CHECK: %[[VAL_12:.*]] = arith.addf %[[VAL_9]], %[[VAL_11]] fastmath<contract> : f32191// CHECK: affine.yield %[[VAL_12]] : f32192// CHECK: }193// CHECK: %[[VAL_13:.*]]:2 = fir.do_loop %[[VAL_14:.*]] = %[[VAL_0]] to %[[VAL_2]] step %[[VAL_0]] iter_args(%[[VAL_15:.*]] = %[[VAL_7]]) -> (index, f32) {194// CHECK: %[[VAL_16:.*]] = fir.array_coor %[[ARG1]](%[[VAL_4]]) %[[VAL_0]], %[[VAL_14]] : (!fir.ref<!fir.array<100x100xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>195// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<f32>) -> !fir.ref<!fir.array<100xf32>>196// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (!fir.ref<!fir.array<100xf32>>) -> memref<?xf32>197// CHECK: %[[VAL_19:.*]] = affine.for %[[VAL_20:.*]] = %[[VAL_0]] to #{{.*}}(){{\[}}%[[VAL_2]]] iter_args(%[[VAL_21:.*]] = %[[VAL_15]]) -> (f32) {198// CHECK: %[[VAL_22:.*]] = affine.apply #{{.*}}(%[[VAL_20]]){{\[}}%[[VAL_0]], %[[VAL_2]], %[[VAL_0]]]199// CHECK: %[[VAL_23:.*]] = affine.load %[[VAL_18]]{{\[}}%[[VAL_22]]] : memref<?xf32>200// CHECK: %[[VAL_24:.*]] = arith.addf %[[VAL_21]], %[[VAL_23]] fastmath<contract> : f32201// CHECK: affine.yield %[[VAL_24]] : f32202// CHECK: }203// CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_14]], %[[VAL_0]] overflow<nsw> : index204// CHECK: fir.result %[[VAL_25]], %[[VAL_19]] : index, f32205// CHECK: }206// CHECK: %[[VAL_26:.*]] = fir.convert %[[ARG2]] : (!fir.ref<!fir.array<100xf32>>) -> memref<?xf32>207// CHECK: %[[VAL_27:.*]]:2 = affine.for %[[VAL_28:.*]] = %[[VAL_0]] to #{{.*}}(){{\[}}%[[VAL_2]]] iter_args(%[[VAL_29:.*]] = %[[VAL_30:.*]]#1, %[[VAL_31:.*]] = %[[VAL_1]]) -> (f32, f32) {208// CHECK: %[[VAL_32:.*]] = affine.apply #{{.*}}(%[[VAL_28]]){{\[}}%[[VAL_0]], %[[VAL_2]], %[[VAL_0]]]209// CHECK: %[[VAL_33:.*]] = affine.load %[[VAL_6]]{{\[}}%[[VAL_32]]] : memref<?xf32>210// CHECK: %[[VAL_34:.*]] = arith.addf %[[VAL_29]], %[[VAL_33]] fastmath<contract> : f32211// CHECK: %[[VAL_35:.*]] = affine.load %[[VAL_26]]{{\[}}%[[VAL_32]]] : memref<?xf32>212// CHECK: %[[VAL_36:.*]] = arith.addf %[[VAL_31]], %[[VAL_35]] fastmath<contract> : f32213// CHECK: affine.yield %[[VAL_34]], %[[VAL_36]] : f32, f32214// CHECK: }215// CHECK: %[[VAL_37:.*]] = arith.addf %[[VAL_38:.*]]#0, %[[VAL_38]]#1 fastmath<contract> : f32216// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_40:.*]]#0 : (index) -> i32217// CHECK: fir.store %[[VAL_39]] to %[[VAL_5]] : !fir.ref<i32>218// CHECK: return %[[VAL_37]] : f32219// CHECK: }220