@@ -756,3 +756,74 @@ transform.sequence failures(propagate) {
756
756
transform.structured.hoist_redundant_vector_transfers %0
757
757
: (!transform.any_op ) -> !transform.any_op
758
758
}
759
+
760
+ // -----
761
+
762
+ // Regression test - `vector.transfer_read` below should not be hoisted.
763
+ // Indeed, %collapse_shape (written to by `vector.transfer_write`) and %alloca
764
+ // (read by `vector.transfer_read`) alias.
765
+
766
+ // CHECK-LABEL: func.func @no_hoisting_collapse_shape
767
+ // CHECK: scf.for {{.*}} {
768
+ // CHECK: vector.transfer_write
769
+ // CHECK: vector.transfer_read
770
+ // CHECK: vector.transfer_write
771
+ // CHECK: }
772
+
773
+ func.func @no_hoisting_collapse_shape (%in_0: memref <1 x20 x1 xi32 >, %1: memref <9 x1 xi32 >, %vec: vector <4 xi32 >) {
774
+ %c0_i32 = arith.constant 0 : i32
775
+ %c0 = arith.constant 0 : index
776
+ %c4 = arith.constant 4 : index
777
+ %c20 = arith.constant 20 : index
778
+ %alloca = memref.alloca () {alignment = 64 : i64 } : memref <1 x4 x1 xi32 >
779
+ scf.for %arg0 = %c0 to %c20 step %c4 {
780
+ %subview = memref.subview %in_0 [0 , %arg0 , 0 ] [1 , 4 , 1 ] [1 , 1 , 1 ] : memref <1 x20 x1 xi32 > to memref <1 x4 x1 xi32 , strided <[20 , 1 , 1 ], offset : ?>>
781
+ %collapse_shape = memref.collapse_shape %alloca [[0 , 1 , 2 ]] : memref <1 x4 x1 xi32 > into memref <4 xi32 >
782
+ vector.transfer_write %vec , %collapse_shape [%c0 ] {in_bounds = [true ]} : vector <4 xi32 >, memref <4 xi32 >
783
+ %read = vector.transfer_read %alloca [%c0 , %c0 , %c0 ], %c0_i32 {in_bounds = [true , true , true ]} : memref <1 x4 x1 xi32 >, vector <1 x4 x1 xi32 >
784
+ vector.transfer_write %read , %subview [%c0 , %c0 , %c0 ] {in_bounds = [true , true , true ]} : vector <1 x4 x1 xi32 >, memref <1 x4 x1 xi32 , strided <[20 , 1 , 1 ], offset : ?>>
785
+ }
786
+ return
787
+ }
788
+
789
+ transform.sequence failures (propagate ) {
790
+ ^bb1 (%arg1: !transform.any_op ):
791
+ %0 = transform.structured.match ops {[" func.func" ]} in %arg1
792
+ : (!transform.any_op ) -> !transform.any_op
793
+ transform.structured.hoist_redundant_vector_transfers %0
794
+ : (!transform.any_op ) -> !transform.any_op
795
+ }
796
+
797
+ // -----
798
+
799
+ // Regression test - `vector.transfer_read` below should not be hoisted.
800
+ // Indeed, %collapse_shape (read by `vector.transfer_read`) and %alloca
801
+ // (written to by `vector.transfer_write`) alias.
802
+
803
+ // CHECK-LABEL: func.func @no_hoisting_collapse_shape_2
804
+ // CHECK: scf.for {{.*}} {
805
+ // CHECK: vector.transfer_write
806
+ // CHECK: vector.transfer_read
807
+
808
+ func.func @no_hoisting_collapse_shape_2 (%vec: vector <1 x12 x1 xi32 >) {
809
+ %c0_i32 = arith.constant 0 : i32
810
+ %c0 = arith.constant 0 : index
811
+ %c4 = arith.constant 4 : index
812
+ %c20 = arith.constant 20 : index
813
+ %alloca = memref.alloca () {alignment = 64 : i64 } : memref <1 x12 x1 xi32 >
814
+ scf.for %arg0 = %c0 to %c20 step %c4 {
815
+ %collapse_shape = memref.collapse_shape %alloca [[0 , 1 , 2 ]] : memref <1 x12 x1 xi32 > into memref <12 xi32 >
816
+ vector.transfer_write %vec , %alloca [%c0 , %c0 , %c0 ] {in_bounds = [true , true , true ]} : vector <1 x12 x1 xi32 >, memref <1 x12 x1 xi32 >
817
+ %read = vector.transfer_read %collapse_shape [%c0 ], %c0_i32 {in_bounds = [true ]} : memref <12 xi32 >, vector <12 xi32 >
818
+ " prevent.dce" (%read ) : (vector <12 xi32 >) ->()
819
+ }
820
+ return
821
+ }
822
+
823
+ transform.sequence failures (propagate ) {
824
+ ^bb1 (%arg1: !transform.any_op ):
825
+ %0 = transform.structured.match ops {[" func.func" ]} in %arg1
826
+ : (!transform.any_op ) -> !transform.any_op
827
+ transform.structured.hoist_redundant_vector_transfers %0
828
+ : (!transform.any_op ) -> !transform.any_op
829
+ }
0 commit comments