Skip to content

Commit 22f1159

Browse files
authored
[mlir][ArmSME] Propagate pad and mask in vector.transfer_read lowering (llvm#70814)
This extends the lowering of vector.transfer_read -> arm_sme.tile_load lowering to propagate pad and mask. The restriction on the transfer_read being a transposition is also removed, identity maps are lowered to normal horizontal loads.
1 parent c1b55ae commit 22f1159

File tree

2 files changed

+109
-88
lines changed

2 files changed

+109
-88
lines changed

mlir/lib/Conversion/VectorToArmSME/VectorToArmSME.cpp

+35-22
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,30 @@ getSMETileAndCastToVector(PatternRewriter &rewriter, Location loc,
6060

6161
namespace {
6262

63-
/// Conversion pattern for vector.transfer_read op with transpose permutation
64-
/// map to vertical arm_sme.tile_load (in-flight transpose).
63+
/// Conversion pattern for vector.transfer_read.
64+
///
65+
/// ---
66+
///
67+
/// Example 1: op with identity permutation map to horizontal
68+
/// arm_sme.tile_load:
69+
///
70+
/// vector.transfer_read ... permutation_map: (d0, d1) -> (d0, d1)
71+
///
72+
/// is converted to:
73+
///
74+
/// arm_sme.tile_load ...
75+
///
76+
/// ---
77+
///
78+
/// Example 2: op with transpose permutation map to vertical arm_sme.tile_load
79+
/// (in-flight transpose):
6580
///
6681
/// vector.transfer_read ... permutation_map: (d0, d1) -> (d1, d0)
6782
///
6883
/// is converted to:
6984
///
7085
/// arm_sme.tile_load ... layout<vertical>
71-
struct TransferReadPermutationToArmSMELowering
86+
struct TransferReadToArmSMELowering
7287
: public OpRewritePattern<vector::TransferReadOp> {
7388
using OpRewritePattern<vector::TransferReadOp>::OpRewritePattern;
7489

@@ -79,15 +94,6 @@ struct TransferReadPermutationToArmSMELowering
7994
return rewriter.notifyMatchFailure(transferReadOp,
8095
"not a 2 result permutation map");
8196

82-
AffineMap map = transferReadOp.getPermutationMap();
83-
84-
// Permutation map doesn't perform permutation, can be lowered to
85-
// vector.load by TransferReadToVectorLoadLowering and then
86-
// arm_sme.tile_load by VectorLoadToArmSMELowering.
87-
if (map.isIdentity())
88-
return rewriter.notifyMatchFailure(
89-
transferReadOp, "map is an identity, apply another pattern");
90-
9197
auto vectorType = transferReadOp.getVectorType();
9298
if (!arm_sme::isValidSMETileVectorType(vectorType))
9399
return rewriter.notifyMatchFailure(transferReadOp,
@@ -96,26 +102,33 @@ struct TransferReadPermutationToArmSMELowering
96102
if (!llvm::isa<MemRefType>(transferReadOp.getSource().getType()))
97103
return rewriter.notifyMatchFailure(transferReadOp, "not a memref source");
98104

99-
if (transferReadOp.getMask())
100-
// TODO: support masking.
101-
return rewriter.notifyMatchFailure(transferReadOp,
102-
"masking not yet supported");
103-
104105
// Out-of-bounds dims are not supported.
105106
if (transferReadOp.hasOutOfBoundsDim())
106107
return rewriter.notifyMatchFailure(transferReadOp,
107108
"not inbounds transfer read");
108109

110+
arm_sme::TileSliceLayout layout;
111+
109112
AffineExpr d0, d1;
110113
bindDims(transferReadOp.getContext(), d0, d1);
111-
if (map != AffineMap::get(map.getNumDims(), 0, {d1, d0},
112-
transferReadOp.getContext()))
114+
AffineMap map = transferReadOp.getPermutationMap();
115+
if (map.isIdentity())
116+
layout = arm_sme::TileSliceLayout::Horizontal;
117+
else if (map == AffineMap::get(map.getNumDims(), 0, {d1, d0},
118+
transferReadOp.getContext()))
119+
layout = arm_sme::TileSliceLayout::Vertical;
120+
else
113121
return rewriter.notifyMatchFailure(transferReadOp,
114-
"not true 2-D matrix transpose");
122+
"unsupported permutation map");
115123

124+
// Padding isn't optional for transfer_read, but is only used in the case
125+
// of out-of-bounds accesses (not supported here) and/or masking. Mask is
126+
// optional, if it's not present don't pass padding.
127+
auto mask = transferReadOp.getMask();
128+
auto padding = mask ? transferReadOp.getPadding() : nullptr;
116129
rewriter.replaceOpWithNewOp<arm_sme::TileLoadOp>(
117130
transferReadOp, vectorType, transferReadOp.getSource(),
118-
transferReadOp.getIndices(), arm_sme::TileSliceLayout::Vertical);
131+
transferReadOp.getIndices(), padding, mask, layout);
119132

120133
return success();
121134
}
@@ -531,7 +544,7 @@ struct VectorOuterProductToArmSMELowering
531544
void mlir::populateVectorToArmSMEPatterns(RewritePatternSet &patterns,
532545
MLIRContext &ctx) {
533546
patterns.add<BroadcastOpToArmSMELowering, ConstantOpToArmSMELowering,
534-
SplatOpToArmSMELowering, TransferReadPermutationToArmSMELowering,
547+
SplatOpToArmSMELowering, TransferReadToArmSMELowering,
535548
TransferWriteToArmSMELowering, TransposeOpToArmSMELowering,
536549
VectorLoadToArmSMELowering, VectorStoreToArmSMELowering,
537550
VectorOuterProductToArmSMELowering>(&ctx);

mlir/test/Dialect/ArmSME/vector-ops-to-sme.mlir

+74-66
Original file line numberDiff line numberDiff line change
@@ -1,181 +1,189 @@
11
// RUN: mlir-opt %s -convert-vector-to-arm-sme -split-input-file -allow-unregistered-dialect | FileCheck %s
22

33
//===----------------------------------------------------------------------===//
4-
// vector.transfer_read (with in-flight transpose)
4+
// vector.transfer_read
55
//===----------------------------------------------------------------------===//
66

7-
// CHECK-LABEL: @transfer_read_2d_transpose_i8
8-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xi8>, vector<[16]x[16]xi8>
9-
func.func @transfer_read_2d_transpose_i8(%src : memref<?x?xi8>) {
7+
// CHECK-LABEL: @transfer_read_2d_i8
8+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xi8>, vector<[16]x[16]xi8>
9+
func.func @transfer_read_2d_i8(%src : memref<?x?xi8>) {
1010
%c0 = arith.constant 0 : index
1111
%pad = arith.constant 0 : i8
12-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xi8>, vector<[16]x[16]xi8>
12+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xi8>, vector<[16]x[16]xi8>
1313
"prevent.dce"(%0) : (vector<[16]x[16]xi8>) -> ()
1414
return
1515
}
1616

1717
// -----
1818

19-
// CHECK-LABEL: @transfer_read_2d_transpose_i16
20-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xi16>, vector<[8]x[8]xi16>
21-
func.func @transfer_read_2d_transpose_i16(%src : memref<?x?xi16>) {
19+
// CHECK-LABEL: @transfer_read_2d_i16
20+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xi16>, vector<[8]x[8]xi16>
21+
func.func @transfer_read_2d_i16(%src : memref<?x?xi16>) {
2222
%c0 = arith.constant 0 : index
2323
%pad = arith.constant 0 : i16
24-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xi16>, vector<[8]x[8]xi16>
24+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xi16>, vector<[8]x[8]xi16>
2525
"prevent.dce"(%0) : (vector<[8]x[8]xi16>) -> ()
2626
return
2727
}
2828

2929
// -----
3030

31-
// CHECK-LABEL: @transfer_read_2d_transpose_i32
32-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xi32>, vector<[4]x[4]xi32>
33-
func.func @transfer_read_2d_transpose_i32(%src : memref<?x?xi32>) {
31+
// CHECK-LABEL: @transfer_read_2d_i32
32+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xi32>, vector<[4]x[4]xi32>
33+
func.func @transfer_read_2d_i32(%src : memref<?x?xi32>) {
3434
%c0 = arith.constant 0 : index
3535
%pad = arith.constant 0 : i32
36-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xi32>, vector<[4]x[4]xi32>
36+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xi32>, vector<[4]x[4]xi32>
3737
"prevent.dce"(%0) : (vector<[4]x[4]xi32>) -> ()
3838
return
3939
}
4040

4141
// -----
4242

43-
// CHECK-LABEL: @transfer_read_2d_transpose_i64
44-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xi64>, vector<[2]x[2]xi64>
45-
func.func @transfer_read_2d_transpose_i64(%src : memref<?x?xi64>) {
43+
// CHECK-LABEL: @transfer_read_2d_i64
44+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xi64>, vector<[2]x[2]xi64>
45+
func.func @transfer_read_2d_i64(%src : memref<?x?xi64>) {
4646
%c0 = arith.constant 0 : index
4747
%pad = arith.constant 0 : i64
48-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xi64>, vector<[2]x[2]xi64>
48+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xi64>, vector<[2]x[2]xi64>
4949
"prevent.dce"(%0) : (vector<[2]x[2]xi64>) -> ()
5050
return
5151
}
5252

5353
// -----
5454

55-
// CHECK-LABEL: @transfer_read_2d_transpose_i128
56-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xi128>, vector<[1]x[1]xi128>
57-
func.func @transfer_read_2d_transpose_i128(%src : memref<?x?xi128>) {
55+
// CHECK-LABEL: @transfer_read_2d_i128
56+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xi128>, vector<[1]x[1]xi128>
57+
func.func @transfer_read_2d_i128(%src : memref<?x?xi128>) {
5858
%c0 = arith.constant 0 : index
5959
%pad = arith.constant 0 : i128
60-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xi128>, vector<[1]x[1]xi128>
60+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xi128>, vector<[1]x[1]xi128>
6161
"prevent.dce"(%0) : (vector<[1]x[1]xi128>) -> ()
6262
return
6363
}
6464

6565
// -----
6666

67-
// CHECK-LABEL: @transfer_read_2d_transpose_f16
68-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xf16>, vector<[8]x[8]xf16>
69-
func.func @transfer_read_2d_transpose_f16(%src : memref<?x?xf16>) {
67+
// CHECK-LABEL: @transfer_read_2d_f16
68+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xf16>, vector<[8]x[8]xf16>
69+
func.func @transfer_read_2d_f16(%src : memref<?x?xf16>) {
7070
%c0 = arith.constant 0 : index
7171
%pad = arith.constant 0.0 : f16
72-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xf16>, vector<[8]x[8]xf16>
72+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xf16>, vector<[8]x[8]xf16>
7373
"prevent.dce"(%0) : (vector<[8]x[8]xf16>) -> ()
7474
return
7575
}
7676

7777
// -----
7878

79-
// CHECK-LABEL: @transfer_read_2d_transpose_bf16
80-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xbf16>, vector<[8]x[8]xbf16>
81-
func.func @transfer_read_2d_transpose_bf16(%src : memref<?x?xbf16>) {
79+
// CHECK-LABEL: @transfer_read_2d_bf16
80+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xbf16>, vector<[8]x[8]xbf16>
81+
func.func @transfer_read_2d_bf16(%src : memref<?x?xbf16>) {
8282
%c0 = arith.constant 0 : index
8383
%pad = arith.constant 0.0 : bf16
84-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xbf16>, vector<[8]x[8]xbf16>
84+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xbf16>, vector<[8]x[8]xbf16>
8585
"prevent.dce"(%0) : (vector<[8]x[8]xbf16>) -> ()
8686
return
8787
}
8888

8989
// -----
9090

91-
// CHECK-LABEL: @transfer_read_2d_transpose_f32
92-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xf32>, vector<[4]x[4]xf32>
93-
func.func @transfer_read_2d_transpose_f32(%src : memref<?x?xf32>) {
91+
// CHECK-LABEL: @transfer_read_2d_f32
92+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xf32>, vector<[4]x[4]xf32>
93+
func.func @transfer_read_2d_f32(%src : memref<?x?xf32>) {
9494
%c0 = arith.constant 0 : index
9595
%pad = arith.constant 0.0 : f32
96-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xf32>, vector<[4]x[4]xf32>
96+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xf32>, vector<[4]x[4]xf32>
9797
"prevent.dce"(%0) : (vector<[4]x[4]xf32>) -> ()
9898
return
9999
}
100100

101101
// -----
102102

103-
// CHECK-LABEL: @transfer_read_2d_transpose_f64
104-
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xf64>, vector<[2]x[2]xf64>
105-
func.func @transfer_read_2d_transpose_f64(%src : memref<?x?xf64>) {
103+
// CHECK-LABEL: @transfer_read_2d_f64
104+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}] : memref<?x?xf64>, vector<[2]x[2]xf64>
105+
func.func @transfer_read_2d_f64(%src : memref<?x?xf64>) {
106106
%c0 = arith.constant 0 : index
107107
%pad = arith.constant 0.0 : f64
108-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xf64>, vector<[2]x[2]xf64>
108+
%0 = vector.transfer_read %src[%c0, %c0], %pad {in_bounds = [true, true]} : memref<?x?xf64>, vector<[2]x[2]xf64>
109109
"prevent.dce"(%0) : (vector<[2]x[2]xf64>) -> ()
110110
return
111111
}
112112

113113
// -----
114114

115-
// CHECK-LABEL: @transfer_read_2d__bad_type
116-
// CHECK-NOT: arm_sme.tile_load
117-
// CHECK: vector.transfer_read
118-
func.func @transfer_read_2d__bad_type(%src : memref<?x?xf64>) {
115+
// CHECK-LABEL: @transfer_read_2d_with_mask_i16
116+
// CHECK: arm_sme.tile_load %{{.*}}[{{.*}}], {{.*}}, {{.*}} : memref<?x?xi16>, vector<[8]x[8]xi16>
117+
func.func @transfer_read_2d_with_mask_i16(%src : memref<?x?xi16>, %mask : vector<[8]x[8]xi1>) {
119118
%c0 = arith.constant 0 : index
120-
%pad = arith.constant 0.0 : f64
121-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [false, false]} : memref<?x?xf64>, vector<[4]x[4]xf64>
122-
"prevent.dce"(%0) : (vector<[4]x[4]xf64>) -> ()
119+
%pad = arith.constant 0 : i16
120+
%0 = vector.transfer_read %src[%c0, %c0], %pad, %mask {in_bounds = [true, true]} : memref<?x?xi16>, vector<[8]x[8]xi16>
121+
"prevent.dce"(%0) : (vector<[8]x[8]xi16>) -> ()
123122
return
124123
}
125124

126125
// -----
127126

128-
// CHECK-LABEL: @transfer_read_2d__non_memref_type
129-
// CHECK-NOT: arm_sme.tile_load
130-
// CHECK: vector.transfer_read
131-
func.func @transfer_read_2d__non_memref_type(%src : tensor<?x?xf64>) {
127+
/// in-flight transpose
128+
129+
// CHECK-LABEL: @transfer_read_2d_transpose_i8
130+
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xi8>, vector<[16]x[16]xi8>
131+
func.func @transfer_read_2d_transpose_i8(%src : memref<?x?xi8>) {
132132
%c0 = arith.constant 0 : index
133-
%pad = arith.constant 0.0 : f64
134-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : tensor<?x?xf64>, vector<[2]x[2]xf64>
135-
"prevent.dce"(%0) : (vector<[2]x[2]xf64>) -> ()
133+
%pad = arith.constant 0 : i8
134+
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xi8>, vector<[16]x[16]xi8>
135+
"prevent.dce"(%0) : (vector<[16]x[16]xi8>) -> ()
136136
return
137137
}
138138

139139
// -----
140140

141-
// CHECK-LABEL: @transfer_read_2d__bad_transfer_rank
141+
// CHECK-LABEL: @transfer_read_2d_transpose_with_mask_f32
142+
// CHECK: arm_sme.tile_load {{.*}} layout<vertical> : memref<?x?xf32>, vector<[4]x[4]xf32>
143+
func.func @transfer_read_2d_transpose_with_mask_f32(%src : memref<?x?xf32>, %mask : vector<[4]x[4]xi1>) {
144+
%c0 = arith.constant 0 : index
145+
%pad = arith.constant 0.0 : f32
146+
%0 = vector.transfer_read %src[%c0, %c0], %pad, %mask {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xf32>, vector<[4]x[4]xf32>
147+
"prevent.dce"(%0) : (vector<[4]x[4]xf32>) -> ()
148+
return
149+
}
150+
151+
// -----
152+
153+
// CHECK-LABEL: @transfer_read_2d__bad_type
142154
// CHECK-NOT: arm_sme.tile_load
143155
// CHECK: vector.transfer_read
144-
func.func @transfer_read_2d__bad_transfer_rank(%src : memref<?x?xf64>) {
156+
func.func @transfer_read_2d__bad_type(%src : memref<?x?xf64>) {
145157
%c0 = arith.constant 0 : index
146158
%pad = arith.constant 0.0 : f64
147-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d0)>, in_bounds = [true]} : memref<?x?xf64>, vector<[2]xf64>
148-
"prevent.dce"(%0) : (vector<[2]xf64>) -> ()
159+
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [false, false]} : memref<?x?xf64>, vector<[4]x[4]xf64>
160+
"prevent.dce"(%0) : (vector<[4]x[4]xf64>) -> ()
149161
return
150162
}
151163

152164
// -----
153165

154-
// CHECK-LABEL: @transfer_read_2d__unsupported_mask
166+
// CHECK-LABEL: @transfer_read_2d__non_memref_type
155167
// CHECK-NOT: arm_sme.tile_load
156168
// CHECK: vector.transfer_read
157-
func.func @transfer_read_2d__unsupported_mask(%src : memref<?x?xf64>, %mask : vector<[2]x[2]xi1>) {
169+
func.func @transfer_read_2d__non_memref_type(%src : tensor<?x?xf64>) {
158170
%c0 = arith.constant 0 : index
159171
%pad = arith.constant 0.0 : f64
160-
%0 = vector.transfer_read %src[%c0, %c0], %pad, %mask {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : memref<?x?xf64>, vector<[2]x[2]xf64>
172+
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d1, d0)>, in_bounds = [true, true]} : tensor<?x?xf64>, vector<[2]x[2]xf64>
161173
"prevent.dce"(%0) : (vector<[2]x[2]xf64>) -> ()
162174
return
163175
}
164176

165177
// -----
166178

167-
/// transfer_read with identity map should be lowered to vector.load by
168-
/// TransferReadToVectorLoadLowering and then arm_sme.tile_load by
169-
/// VectorLoadToArmSMELowering.
170-
171-
// CHECK-LABEL: @transfer_read_2d__non_permuting_map
179+
// CHECK-LABEL: @transfer_read_2d__bad_transfer_rank
172180
// CHECK-NOT: arm_sme.tile_load
173181
// CHECK: vector.transfer_read
174-
func.func @transfer_read_2d__non_permuting_map(%src : memref<?x?xf64>) {
182+
func.func @transfer_read_2d__bad_transfer_rank(%src : memref<?x?xf64>) {
175183
%c0 = arith.constant 0 : index
176184
%pad = arith.constant 0.0 : f64
177-
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d0, d1)>, in_bounds = [true, true]} : memref<?x?xf64>, vector<[2]x[2]xf64>
178-
"prevent.dce"(%0) : (vector<[2]x[2]xf64>) -> ()
185+
%0 = vector.transfer_read %src[%c0, %c0], %pad {permutation_map = affine_map<(d0, d1) -> (d0)>, in_bounds = [true]} : memref<?x?xf64>, vector<[2]xf64>
186+
"prevent.dce"(%0) : (vector<[2]xf64>) -> ()
179187
return
180188
}
181189

0 commit comments

Comments
 (0)