@@ -43,20 +43,27 @@ func.func @cond_branch(%cond: i1, %tile: vector<[4]x[4]xf32>) {
43
43
// Reduction of a real world example that shows why we must split conditional branches.
44
44
45
45
// CHECK-LABEL: @cond_branch_with_backedge(
46
- // CHECK-SAME: %{{[[: alnum:]]+}} : vector<[4]x[4]xf32>, %[[TILEB:[[:alnum:]]+]]: vector<[4]x[4]xf32>,
46
+ // CHECK-SAME: %[[TILEA:[[: alnum:]]+]] : vector<[4]x[4]xf32>, %[[TILEB:[[:alnum:]]+]]: vector<[4]x[4]xf32>,
47
47
// CHECK-SAME: %[[TILEC:[[:alnum:]]+]]: vector<[4]x[4]xf32>, %[[TILED:[[:alnum:]]+]]: vector<[4]x[4]xf32>,
48
+ // CHECK: %[[BB1_COPY_0:.*]] = arm_sme.copy_tile %[[TILEA]] : vector<[4]x[4]xf32>
49
+ // CHECK: cf.br ^bb1(%{{[[:alnum:]]+}}, %[[BB1_COPY_0]]
48
50
// CHECK: ^bb1(%[[CURRENT_INDEX:.*]]: index, %[[ITER_TILE:.*]]: vector<[4]x[4]xf32>):
49
51
// CHECK: %[[CONTINUE_LOOP:.*]] = arith.cmpi
50
- // CHECK: cf.cond_br %[[CONTINUE_LOOP]], ^[[BB2 :[[:alnum:]]+]], ^[[BB3_COPIES:[[:alnum:]]+]]
52
+ // CHECK: cf.cond_br %[[CONTINUE_LOOP]], ^[[BB2_COPIES :[[:alnum:]]+]], ^[[BB3_COPIES:[[:alnum:]]+]]
51
53
// CHECK: ^[[BB3_COPIES]]:
52
- // CHECK-NEXT: arm_sme.copy_tile %[[ITER_TILE]] : vector<[4]x[4]xf32>
53
- // CHECK-NEXT: arm_sme.copy_tile %[[TILEB]] : vector<[4]x[4]xf32>
54
- // CHECK-NEXT: arm_sme.copy_tile %[[TILEC]] : vector<[4]x[4]xf32>
55
- // CHECK-NEXT: arm_sme.copy_tile %[[TILED]] : vector<[4]x[4]xf32>
56
- // CHECK-NEXT: cf.br ^[[BB3:[[:alnum:]]+]]
54
+ // CHECK-NEXT: %[[BB3_COPY_0:.*]] = arm_sme.copy_tile %[[ITER_TILE]] : vector<[4]x[4]xf32>
55
+ // CHECK-NEXT: %[[BB3_COPY_1:.*]] = arm_sme.copy_tile %[[TILEB]] : vector<[4]x[4]xf32>
56
+ // CHECK-NEXT: %[[BB3_COPY_2:.*]] = arm_sme.copy_tile %[[TILEC]] : vector<[4]x[4]xf32>
57
+ // CHECK-NEXT: %[[BB3_COPY_3:.*]] = arm_sme.copy_tile %[[TILED]] : vector<[4]x[4]xf32>
58
+ // CHECK-NEXT: cf.br ^[[BB3:[[:alnum:]]+]](%[[BB3_COPY_0]], %[[BB3_COPY_1]], %[[BB3_COPY_2]], %[[BB3_COPY_3]]
59
+ // CHECK: ^[[BB2_COPIES]]:
60
+ // CHECK-NEXT: cf.br ^[[BB2:[[:alnum:]]+]]
61
+ // CHECK: ^[[BB2]]:
62
+ // CHECK-NEXT: %[[NEXT_TILE:.*]] = arm_sme.move_vector_to_tile_slice %{{.*}}, %[[ITER_TILE]]
63
+ // CHECK: %[[BB1_COPY_1:.*]] = arm_sme.copy_tile %[[NEXT_TILE]] : vector<[4]x[4]xf32>
64
+ // CHECK: cf.br ^bb1(%{{[[:alnum:]]+}}, %[[BB1_COPY_1]]
57
65
// CHECK: ^[[BB3]](%{{.*}}: vector<[4]x[4]xf32>):
58
66
// CHECK-NEXT: return
59
-
60
67
func.func @cond_branch_with_backedge (%tileA: vector <[4 ]x[4 ]xf32 >, %tileB: vector <[4 ]x[4 ]xf32 >, %tileC: vector <[4 ]x[4 ]xf32 >, %tileD: vector <[4 ]x[4 ]xf32 >, %slice: vector <[4 ]xf32 >) {
61
68
%c0 = arith.constant 0 : index
62
69
%c1 = arith.constant 1 : index
@@ -80,3 +87,73 @@ func.func @cond_branch_with_backedge(%tileA: vector<[4]x[4]xf32>, %tileB: vector
80
87
// Live here: %finalTileA, %finalTileB, %finalTileC, %finalTileD
81
88
return
82
89
}
90
+
91
+ // -----
92
+
93
+ // CHECK-LABEL: @tile_dominance
94
+ // CHECK-NOT: arm_sme.copy_tile
95
+ func.func @tile_dominance (%arg0: vector <[4 ]x[4 ]xf32 >) {
96
+ cf.br ^bb1
97
+ ^bb1 : // 2 preds: ^bb0, ^bb4
98
+ " test.some_use" (%arg0 ) : (vector <[4 ]x[4 ]xf32 >) -> ()
99
+ return
100
+ ^bb2 : // no predecessors
101
+ %0 = arm_sme.get_tile : vector <[4 ]x[4 ]xf32 >
102
+ cf.br ^bb3
103
+ ^bb3 : // pred: ^bb2
104
+ " test.some_use" (%0 ) : (vector <[4 ]x[4 ]xf32 >) -> ()
105
+ return
106
+ ^bb4 : // no predecessors
107
+ cf.br ^bb1
108
+ ^bb5 : // no predecessors
109
+ return
110
+ }
111
+
112
+ // -----
113
+
114
+ // CHECK-LABEL: func.func @cond_branch_true_and_false_tile_args(
115
+ // CHECK-SAME: %[[COND:.*]]: i1, %[[TILE:.*]]: vector<[4]x[4]xf32>
116
+ // CHECK-NEXT: cf.cond_br %[[COND]], ^[[BB1_COPIES:[[:alnum:]]+]], ^[[BB2_COPIES:[[:alnum:]]+]]
117
+ // CHECK: ^[[BB2_COPIES]]:
118
+ // CHECK-NEXT: %[[COPY_0:.*]] = arm_sme.copy_tile %[[TILE]] : vector<[4]x[4]xf32>
119
+ // CHECK-NEXT: cf.br ^[[BB2:[[:alnum:]]+]](%[[COPY_0]]
120
+ // CHECK: ^[[BB1_COPIES]]:
121
+ // CHECK-NEXT: %[[COPY_1:.*]] = arm_sme.copy_tile %[[TILE]] : vector<[4]x[4]xf32>
122
+ // CHECK-NEXT: cf.br ^[[BB1:[[:alnum:]]+]](%[[COPY_1]]
123
+ // CHECK: ^[[BB1]]{{.*}}:
124
+ // CHECK-NEXT: return
125
+ // CHECK: ^[[BB2]]{{.*}}:
126
+ // CHECK-NEXT: return
127
+ func.func @cond_branch_true_and_false_tile_args (%cond: i1 , %tile: vector <[4 ]x[4 ]xf32 >) {
128
+ cf.cond_br %cond , ^bb1 (%tile: vector <[4 ]x[4 ]xf32 >), ^bb2 (%tile: vector <[4 ]x[4 ]xf32 >)
129
+ ^bb1 (%blockArg0: vector <[4 ]x[4 ]xf32 >):
130
+ return
131
+ ^bb2 (%blockArg1: vector <[4 ]x[4 ]xf32 >):
132
+ return
133
+ }
134
+
135
+ // -----
136
+
137
+ // CHECK-LABEL: @multiple_predecessors
138
+ // CHECK: ^bb1:
139
+ // CHECK-NEXT: %[[TILE:.*]] = arm_sme.get_tile : vector<[4]x[4]xf32>
140
+ // CHECK-NEXT: %[[COPY_0:.*]] = arm_sme.copy_tile %[[TILE]] : vector<[4]x[4]xf32>
141
+ // CHECK-NEXT: cf.br ^bb3(%[[COPY_0]] : vector<[4]x[4]xf32>)
142
+ // CHECK: ^bb2:
143
+ // CHECK-NEXT: %[[ZERO:.*]] = arm_sme.zero : vector<[4]x[4]xf32>
144
+ // CHECK-NEXT: %[[COPY_1:.*]] = arm_sme.copy_tile %[[ZERO]] : vector<[4]x[4]xf32>
145
+ // CHECK-NEXT: cf.br ^bb3(%[[COPY_1]] : vector<[4]x[4]xf32>)
146
+ // CHECK: ^bb3({{.*}}):
147
+ // CHECK-NEXT: return
148
+ func.func @multiple_predecessors (%cond: i1 )
149
+ {
150
+ cf.cond_br %cond , ^bb1 , ^bb2
151
+ ^bb1 :
152
+ %tile = arm_sme.get_tile : vector <[4 ]x[4 ]xf32 >
153
+ cf.br ^bb3 (%tile : vector <[4 ]x[4 ]xf32 >)
154
+ ^bb2 :
155
+ %zero = arm_sme.zero : vector <[4 ]x[4 ]xf32 >
156
+ cf.br ^bb3 (%zero : vector <[4 ]x[4 ]xf32 >)
157
+ ^bb3 (%blockArg: vector <[4 ]x[4 ]xf32 >): // pred: ^bb1, ^bb2
158
+ return
159
+ }
0 commit comments