1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -affine-super-vectorizer-test="forward-slicing=true" 2>&1 | FileCheck %s --check-prefix=FWD 2// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -affine-super-vectorizer-test="backward-slicing=true" 2>&1 | FileCheck %s --check-prefix=BWD 3// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -affine-super-vectorizer-test="slicing=true" 2>&1 | FileCheck %s --check-prefix=FWDBWD 4 5/// 1 2 3 4 6/// |_______| |______| 7/// | | | 8/// | 5 6 9/// |___|_____________| 10/// | | 11/// 7 8 12/// |_______________| 13/// | 14/// 9 15// FWD-LABEL: slicing_test 16// BWD-LABEL: slicing_test 17// FWDBWD-LABEL: slicing_test 18func.func @slicing_test() { 19 // Fake 0 to align on 1 and match ASCII art. 20 %0 = memref.alloc() : memref<1xi32> 21 22 // FWD: matched: %[[v1:.*]] {{.*}} forward static slice: 23 // FWD-NEXT: %[[v5:.*]] {{.*}} -> i5 24 // FWD-DAG: %[[v8:.*]] {{.*}} -> i8 25 // FWD-DAG: %[[v7:.*]] {{.*}} -> i7 26 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 27 // 28 // BWD: matched: %[[v1:.*]] {{.*}} backward static slice: 29 // 30 // FWDBWD: matched: %[[v1:.*]] {{.*}} static slice: 31 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 32 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 33 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 34 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 35 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 36 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 37 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 38 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 39 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 40 41 %1 = "slicing-test-op" () : () -> i1 42 43 // FWD-NEXT: matched: %[[v2:.*]] {{.*}} forward static slice: 44 // FWD-NEXT: %[[v5:.*]] {{.*}} -> i5 45 // FWD-DAG: %[[v8:.*]] {{.*}} -> i8 46 // FWD-DAG: %[[v7:.*]] {{.*}} -> i7 47 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 48 // 49 // BWD: matched: %[[v2:.*]] {{.*}} backward static slice: 50 // 51 // FWDBWD-NEXT: matched: %[[v2:.*]] {{.*}} static slice: 52 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 53 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 54 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 55 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 56 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 57 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 58 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 59 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 60 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 61 62 %2 = "slicing-test-op" () : () -> i2 63 64 // FWD-NEXT: matched: %[[v3:.*]] {{.*}} forward static slice: 65 // FWD-NEXT: %[[v6:.*]] {{.*}} -> i6 66 // FWD-NEXT: %[[v8:.*]] {{.*}} -> i8 67 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 68 // 69 // BWD: matched: %[[v3:.*]] {{.*}} backward static slice: 70 // 71 // FWDBWD-NEXT: matched: %[[v3:.*]] {{.*}} static slice: 72 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 73 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 74 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 75 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 76 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 77 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 78 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 79 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 80 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 81 82 %3 = "slicing-test-op" () : () -> i3 83 84 // FWD-NEXT: matched: %[[v4:.*]] {{.*}} forward static slice: 85 // FWD-NEXT: %[[v6:.*]] {{.*}} -> i6 86 // FWD-NEXT: %[[v8:.*]] {{.*}} -> i8 87 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 88 // 89 // BWD: matched: %[[v4:.*]] {{.*}} backward static slice: 90 // 91 // FWDBWD-NEXT: matched: %[[v4:.*]] {{.*}} static slice: 92 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 93 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 94 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 95 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 96 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 97 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 98 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 99 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 100 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 101 102 %4 = "slicing-test-op" () : () -> i4 103 104 // FWD-NEXT: matched: %[[v5:.*]] {{.*}} forward static slice: 105 // FWD-DAG: %[[v7:.*]] {{.*}} -> i7 106 // FWD-DAG: %[[v8:.*]] {{.*}} -> i8 107 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 108 // 109 // BWD: matched: %[[v5:.*]] {{.*}} backward static slice: 110 // BWD-DAG: %[[v1:.*]] = "slicing-test-op"() : () -> i1 111 // BWD-DAG: %[[v2:.*]] = "slicing-test-op"() : () -> i2 112 // 113 // FWDBWD-NEXT: matched: %[[v5:.*]] {{.*}} static slice: 114 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 115 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 116 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 117 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 118 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 119 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 120 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 121 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 122 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 123 124 %5 = "slicing-test-op" (%1, %2) : (i1, i2) -> i5 125 126 // FWD-NEXT: matched: %[[v6:.*]] {{.*}} forward static slice: 127 // FWD-NEXT: %[[v8:.*]] {{.*}} -> i8 128 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 129 // 130 // BWD: matched: %[[v6:.*]] {{.*}} backward static slice: 131 // BWD-DAG: %[[v3:.*]] = "slicing-test-op"() : () -> i3 132 // BWD-DAG: %[[v4:.*]] = "slicing-test-op"() : () -> i4 133 // 134 // FWDBWD-NEXT: matched: %[[v6:.*]] {{.*}} static slice: 135 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 136 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 137 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 138 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 139 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 140 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 141 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 142 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 143 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 144 145 %6 = "slicing-test-op" (%3, %4) : (i3, i4) -> i6 146 147 // FWD-NEXT: matched: %[[v7:.*]] {{.*}} forward static slice: 148 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 149 // 150 // BWD: matched: %[[v7:.*]] {{.*}} backward static slice: 151 // BWD-DAG: %[[v1:.*]] = "slicing-test-op"() : () -> i1 152 // BWD-DAG: %[[v2:.*]] = "slicing-test-op"() : () -> i2 153 // BWD-NEXT: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 154 // 155 // FWDBWD-NEXT: matched: %[[v7:.*]] {{.*}} static slice: 156 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 157 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 158 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 159 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 160 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 161 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 162 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 163 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 164 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 165 166 %7 = "slicing-test-op" (%1, %5) : (i1, i5) -> i7 167 168 // FWD-NEXT: matched: %[[v8:.*]] {{.*}} forward static slice: 169 // FWD-NEXT: %[[v9:.*]] {{.*}} -> i9 170 // 171 // BWD: matched: %[[v8:.*]] {{.*}} backward static slice: 172 // BWD-DAG: %[[v1:.*]] = "slicing-test-op"() : () -> i1 173 // BWD-DAG: %[[v2:.*]] = "slicing-test-op"() : () -> i2 174 // BWD-NEXT: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 175 // BWD-DAG: %[[v3:.*]] = "slicing-test-op"() : () -> i3 176 // BWD-DAG: %[[v4:.*]] = "slicing-test-op"() : () -> i4 177 // BWD-NEXT: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 178 // 179 // FWDBWD-NEXT: matched: %[[v8:.*]] {{.*}} static slice: 180 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 181 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 182 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 183 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 184 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 185 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 186 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 187 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 188 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 189 190 %8 = "slicing-test-op" (%5, %6) : (i5, i6) -> i8 191 192 // FWD-NEXT: matched: %[[v9:.*]] {{.*}} forward static slice: 193 // 194 // BWD: matched: %[[v9:.*]] {{.*}} backward static slice: 195 // BWD-DAG: %[[v1:.*]] = "slicing-test-op"() : () -> i1 196 // BWD-DAG: %[[v2:.*]] = "slicing-test-op"() : () -> i2 197 // BWD-NEXT: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 198 // BWD-NEXT: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 199 // BWD-DAG: %[[v3:.*]] = "slicing-test-op"() : () -> i3 200 // BWD-DAG: %[[v4:.*]] = "slicing-test-op"() : () -> i4 201 // BWD-NEXT: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 202 // BWD-NEXT: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 203 // 204 // FWDBWD-NEXT: matched: %[[v9:.*]] {{.*}} static slice: 205 // FWDBWD: %[[v1:.*]] = "slicing-test-op"() : () -> i1 206 // FWDBWD: %[[v2:.*]] = "slicing-test-op"() : () -> i2 207 // FWDBWD: %[[v3:.*]] = "slicing-test-op"() : () -> i3 208 // FWDBWD: %[[v4:.*]] = "slicing-test-op"() : () -> i4 209 // FWDBWD: %[[v5:.*]] = "slicing-test-op"(%[[v1]], %[[v2]]) : (i1, i2) -> i5 210 // FWDBWD: %[[v6:.*]] = "slicing-test-op"(%[[v3]], %[[v4]]) : (i3, i4) -> i6 211 // FWDBWD: %[[v7:.*]] = "slicing-test-op"(%[[v1]], %[[v5]]) : (i1, i5) -> i7 212 // FWDBWD: %[[v8:.*]] = "slicing-test-op"(%[[v5]], %[[v6]]) : (i5, i6) -> i8 213 // FWDBWD: %[[v9:.*]] = "slicing-test-op"(%[[v7]], %[[v8]]) : (i7, i8) -> i9 214 215 %9 = "slicing-test-op" (%7, %8) : (i7, i8) -> i9 216 217 return 218} 219 220// ----- 221 222// FWD-LABEL: slicing_test_2 223// BWD-LABEL: slicing_test_2 224// FWDBWD-LABEL: slicing_test_2 225func.func @slicing_test_2() { 226 %c0 = arith.constant 0 : index 227 %c2 = arith.constant 2 : index 228 %c16 = arith.constant 16 : index 229 affine.for %i0 = %c0 to %c16 { 230 affine.for %i1 = affine_map<(i)[] -> (i)>(%i0) to 10 { 231 // BWD: matched: %[[b:.*]] {{.*}} backward static slice: 232 // BWD: affine.for {{.*}} 233 234 // affine.for appears in the body of scf.for 235 // BWD: affine.for {{.*}} 236 237 // affine.for appears as a proper op in the backward slice 238 // BWD: affine.for {{.*}} 239 %b = "slicing-test-op"(%i1): (index) -> index 240 241 // BWD: matched: %[[c:.*]] {{.*}} backward static slice: 242 // BWD: affine.for {{.*}} 243 244 // affine.for appears in the body of scf.for 245 // BWD-NEXT: affine.for {{.*}} 246 247 // affine.for only appears in the body of scf.for 248 // BWD-NOT: affine.for {{.*}} 249 %c = "slicing-test-op"(%i0): (index) -> index 250 } 251 } 252 return 253} 254 255// ----- 256 257// FWD-LABEL: slicing_test_3 258// BWD-LABEL: slicing_test_3 259// FWDBWD-LABEL: slicing_test_3 260func.func @slicing_test_3() { 261 %f = arith.constant 1.0 : f32 262 %c = "slicing-test-op"(%f): (f32) -> index 263 // FWD: matched: {{.*}} (f32) -> index forward static slice: 264 // FWD: scf.for {{.*}} 265 // FWD: matched: {{.*}} (index, index) -> index forward static slice: 266 scf.for %i2 = %c to %c step %c { 267 %d = "slicing-test-op"(%c, %i2): (index, index) -> index 268 } 269 return 270} 271 272// ----- 273 274// FWD-LABEL: slicing_test_function_argument 275// BWD-LABEL: slicing_test_function_argument 276// FWDBWD-LABEL: slicing_test_function_argument 277func.func @slicing_test_function_argument(%arg0: index) -> index { 278 // BWD: matched: {{.*}} (index, index) -> index backward static slice: 279 %0 = "slicing-test-op"(%arg0, %arg0): (index, index) -> index 280 return %0 : index 281} 282 283// ----- 284 285// FWD-LABEL: slicing_test_multiple_return 286// BWD-LABEL: slicing_test_multiple_return 287// FWDBWD-LABEL: slicing_test_multiple_return 288func.func @slicing_test_multiple_return(%arg0: index) -> (index, index) { 289 // BWD: matched: {{.*}} (index, index) -> (index, index) backward static slice: 290 // FWD: matched: %{{.*}}:2 = "slicing-test-op"(%arg0, %arg0) : (index, index) -> (index, index) forward static slice: 291 // FWD: return %{{.*}}#0, %{{.*}}#1 : index, index 292 %0:2 = "slicing-test-op"(%arg0, %arg0): (index, index) -> (index, index) 293 return %0#0, %0#1 : index, index 294} 295