Skip to content

Commit b252be7

Browse files
AmrDeveloperrorth
authored andcommitted
[CIR] Implement folder for VecShuffleDynamicOp (llvm#142315)
This change adds a folder for the VecShuffleDynamicOp Issue llvm#136487
1 parent d2daead commit b252be7

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,7 @@ def VecShuffleDynamicOp : CIR_Op<"vec.shuffle.dynamic",
21922192
}];
21932193

21942194
let hasVerifier = 1;
2195+
let hasFolder = 1;
21952196
}
21962197

21972198
//===----------------------------------------------------------------------===//

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc"
2222
#include "clang/CIR/Dialect/IR/CIROpsEnums.cpp.inc"
2323
#include "clang/CIR/MissingFeatures.h"
24+
2425
#include <numeric>
2526

2627
using namespace mlir;
@@ -1579,6 +1580,37 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) {
15791580
// VecShuffleDynamicOp
15801581
//===----------------------------------------------------------------------===//
15811582

1583+
OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) {
1584+
mlir::Attribute vec = adaptor.getVec();
1585+
mlir::Attribute indices = adaptor.getIndices();
1586+
if (mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec) &&
1587+
mlir::isa_and_nonnull<cir::ConstVectorAttr>(indices)) {
1588+
auto vecAttr = mlir::cast<cir::ConstVectorAttr>(vec);
1589+
auto indicesAttr = mlir::cast<cir::ConstVectorAttr>(indices);
1590+
auto vecTy = mlir::cast<cir::VectorType>(vecAttr.getType());
1591+
1592+
mlir::ArrayAttr vecElts = vecAttr.getElts();
1593+
mlir::ArrayAttr indicesElts = indicesAttr.getElts();
1594+
1595+
const uint64_t numElements = vecElts.size();
1596+
1597+
SmallVector<mlir::Attribute, 16> elements;
1598+
elements.reserve(numElements);
1599+
1600+
const uint64_t maskBits = llvm::NextPowerOf2(numElements - 1) - 1;
1601+
for (const auto &idxAttr : indicesElts.getAsRange<cir::IntAttr>()) {
1602+
uint64_t idxValue = idxAttr.getUInt();
1603+
uint64_t newIdx = idxValue & maskBits;
1604+
elements.push_back(vecElts[newIdx]);
1605+
}
1606+
1607+
return cir::ConstVectorAttr::get(
1608+
vecTy, mlir::ArrayAttr::get(getContext(), elements));
1609+
}
1610+
1611+
return {};
1612+
}
1613+
15821614
LogicalResult cir::VecShuffleDynamicOp::verify() {
15831615
// The number of elements in the two input vectors must match.
15841616
if (getVec().getType().getSize() !=

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ void CIRCanonicalizePass::runOnOperation() {
138138
assert(!cir::MissingFeatures::complexRealOp());
139139
assert(!cir::MissingFeatures::complexImagOp());
140140
assert(!cir::MissingFeatures::callOp());
141-
// CastOp, UnaryOp and VecExtractOp are here to perform a manual `fold` in
142-
// applyOpPatternsGreedily.
141+
// CastOp, UnaryOp, VecExtractOp and VecShuffleDynamicOp are here to perform
142+
// a manual `fold` in applyOpPatternsGreedily.
143143
if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp,
144-
VecExtractOp>(op))
144+
VecExtractOp, VecShuffleDynamicOp>(op))
145145
ops.push_back(op);
146146
});
147147

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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<4 x !s32i> {
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<4 x !s32i>
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<4 x !s32i>
9+
%new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<4 x !s32i>, %indices : !cir.vector<4 x !s32i>
10+
cir.return %new_vec : !cir.vector<4 x !s32i>
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<4 x !s32i> {
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<4 x !s32i>
16+
// CHECK-NEXT: cir.return %[[NEW_VEC:.*]] : !cir.vector<4 x !s32i>
17+
18+
cir.func @fold_shuffle_dynamic_vector_op_test_2() -> !cir.vector<4 x !s32i> {
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<4 x !s32i>
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<4 x !s32i>
21+
%new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<4 x !s32i>, %indices : !cir.vector<4 x !s32i>
22+
cir.return %new_vec : !cir.vector<4 x !s32i>
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<4 x !s32i> {
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<4 x !s32i>
28+
// CHECK-NEXT: cir.return %[[NEW_VEC:.*]] : !cir.vector<4 x !s32i>
29+
}
30+
31+

0 commit comments

Comments
 (0)