Skip to content

Commit 4b45e3b

Browse files
authored
[CIR] Backport VecShuffleDynamicOp folder (#1708)
Backporting the VecShuffleDynamicOp folder
1 parent 7b07102 commit 4b45e3b

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3320,7 +3320,9 @@ def VecShuffleDynamicOp : CIR_Op<"vec.shuffle.dynamic",
33203320
$vec `:` qualified(type($vec)) `,` $indices `:` qualified(type($indices))
33213321
attr-dict
33223322
}];
3323+
33233324
let hasVerifier = 1;
3325+
let hasFolder = 1;
33243326
}
33253327

33263328
//===----------------------------------------------------------------------===//

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,34 @@ LogicalResult cir::VecShuffleOp::verify() {
11651165
// VecShuffleDynamic
11661166
//===----------------------------------------------------------------------===//
11671167

1168+
OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) {
1169+
auto vecAttr =
1170+
mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getVec());
1171+
auto indicesAttr =
1172+
mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getIndices());
1173+
if (!vecAttr || !indicesAttr)
1174+
return {};
1175+
1176+
mlir::ArrayAttr vecElts = vecAttr.getElts();
1177+
mlir::ArrayAttr indicesElts = indicesAttr.getElts();
1178+
1179+
const uint64_t numElements = vecElts.size();
1180+
1181+
SmallVector<mlir::Attribute, 16> elements;
1182+
elements.reserve(numElements);
1183+
1184+
const uint64_t maskBits = llvm::NextPowerOf2(numElements - 1) - 1;
1185+
for (const auto &idxAttr : indicesElts.getAsRange<cir::IntAttr>()) {
1186+
uint64_t idxValue = idxAttr.getUInt();
1187+
uint64_t newIdx = idxValue & maskBits;
1188+
elements.push_back(vecElts[newIdx]);
1189+
}
1190+
1191+
auto vecTy = mlir::cast<cir::VectorType>(vecAttr.getType());
1192+
return cir::ConstVectorAttr::get(
1193+
vecTy, mlir::ArrayAttr::get(getContext(), elements));
1194+
}
1195+
11681196
LogicalResult cir::VecShuffleDynamicOp::verify() {
11691197
// The number of elements in the two input vectors must match.
11701198
if (getVec().getType().getSize() !=

clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ void CIRCanonicalizePass::runOnOperation() {
180180
// applyOpPatternsGreedily.
181181
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp, TryOp, UnaryOp, SelectOp,
182182
ComplexCreateOp, ComplexRealOp, ComplexImagOp, CallOp, VecCreateOp,
183-
VecExtractOp, VecShuffleOp, VecTernaryOp>(op))
183+
VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecTernaryOp>(op))
184184
ops.push_back(op);
185185
});
186186

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: cir-opt %s -cir-canonicalize -o - | FileCheck %s
2+
3+
!s32i = !cir.int<s, 32>
4+
5+
module {
6+
cir.func @fold_shuffle_dynamic_vector_op_test() -> !cir.vector<!s32i x 4> {
7+
%vec = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector<!s32i x 4>
8+
%indices = cir.const #cir.const_vector<[#cir.int<8> : !s32i, #cir.int<7> : !s32i, #cir.int<6> : !s32i, #cir.int<5> : !s32i]> : !cir.vector<!s32i x 4>
9+
%new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<!s32i x 4>, %indices : !cir.vector<!s32i x 4>
10+
cir.return %new_vec : !cir.vector<!s32i x 4>
11+
}
12+
13+
// Masking indices [8, 7, 6, 5] AND 3 = [0, 3, 2, 1]
14+
// CHECK: cir.func @fold_shuffle_dynamic_vector_op_test() -> !cir.vector<!s32i x 4> {
15+
// CHECK-NEXT: %[[NEW_VEC:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<4> : !s32i, #cir.int<3> : !s32i, #cir.int<2> : !s32i]> : !cir.vector<!s32i x 4>
16+
// CHECK-NEXT: cir.return %[[NEW_VEC:.*]] : !cir.vector<!s32i x 4>
17+
18+
cir.func @fold_shuffle_dynamic_vector_op_test_2() -> !cir.vector<!s32i x 4> {
19+
%vec = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector<!s32i x 4>
20+
%indices = cir.const #cir.const_vector<[#cir.int<3> : !s32i, #cir.int<2> : !s32i, #cir.int<1> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<!s32i x 4>
21+
%new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<!s32i x 4>, %indices : !cir.vector<!s32i x 4>
22+
cir.return %new_vec : !cir.vector<!s32i x 4>
23+
}
24+
25+
// Masking indices [3, 2, 1, 0] AND 3 = [3, 2, 1, 0]
26+
// CHECK: cir.func @fold_shuffle_dynamic_vector_op_test_2() -> !cir.vector<!s32i x 4> {
27+
// CHECK-NEXT: %[[NEW_VEC:.*]] = cir.const #cir.const_vector<[#cir.int<4> : !s32i, #cir.int<3> : !s32i, #cir.int<2> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<!s32i x 4>
28+
// CHECK-NEXT: cir.return %[[NEW_VEC:.*]] : !cir.vector<!s32i x 4>
29+
}
30+

0 commit comments

Comments
 (0)