Skip to content

Commit 9642d52

Browse files
authored
[CIR] Backport VecShuffleOp folder (#1707)
Backporting the VecShuffleOp folder
1 parent 48c2115 commit 9642d52

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-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
@@ -3291,7 +3291,9 @@ def VecShuffleOp : CIR_Op<"vec.shuffle",
32913291
`(` $vec1 `,` $vec2 `:` qualified(type($vec1)) `)` $indices `:`
32923292
qualified(type($result)) attr-dict
32933293
}];
3294+
32943295
let hasVerifier = 1;
3296+
let hasFolder = 1;
32953297
}
32963298

32973299
//===----------------------------------------------------------------------===//

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,40 @@ LogicalResult cir::VecTernaryOp::verify() {
10961096
// VecShuffle
10971097
//===----------------------------------------------------------------------===//
10981098

1099+
OpFoldResult cir::VecShuffleOp::fold(FoldAdaptor adaptor) {
1100+
auto vec1Attr =
1101+
mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getVec1());
1102+
auto vec2Attr =
1103+
mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getVec2());
1104+
if (!vec1Attr || !vec2Attr)
1105+
return {};
1106+
1107+
mlir::Type vec1ElemTy =
1108+
mlir::cast<cir::VectorType>(vec1Attr.getType()).getElementType();
1109+
1110+
mlir::ArrayAttr vec1Elts = vec1Attr.getElts();
1111+
mlir::ArrayAttr vec2Elts = vec2Attr.getElts();
1112+
mlir::ArrayAttr indicesElts = adaptor.getIndices();
1113+
1114+
SmallVector<mlir::Attribute, 16> elements;
1115+
elements.reserve(indicesElts.size());
1116+
1117+
uint64_t vec1Size = vec1Elts.size();
1118+
for (const auto &idxAttr : indicesElts.getAsRange<cir::IntAttr>()) {
1119+
if (idxAttr.getSInt() == -1) {
1120+
elements.push_back(cir::UndefAttr::get(vec1ElemTy));
1121+
continue;
1122+
}
1123+
1124+
uint64_t idxValue = idxAttr.getUInt();
1125+
elements.push_back(idxValue < vec1Size ? vec1Elts[idxValue]
1126+
: vec2Elts[idxValue - vec1Size]);
1127+
}
1128+
1129+
return cir::ConstVectorAttr::get(
1130+
getType(), mlir::ArrayAttr::get(getContext(), elements));
1131+
}
1132+
10991133
LogicalResult cir::VecShuffleOp::verify() {
11001134
// The number of elements in the indices array must match the number of
11011135
// elements in the result type.

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, VecTernaryOp>(op))
183+
VecExtractOp, VecShuffleOp, VecTernaryOp>(op))
184184
ops.push_back(op);
185185
});
186186

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// RUN: cir-opt %s -cir-canonicalize -o - -split-input-file | FileCheck %s
2+
3+
!s32i = !cir.int<s, 32>
4+
!s64i = !cir.int<s, 64>
5+
6+
module {
7+
cir.func @fold_shuffle_vector_op_test() -> !cir.vector<!s32i x 4> {
8+
%vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<!s32i x 4>
9+
%vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<!s32i x 4>
10+
%new_vec = cir.vec.shuffle(%vec_1, %vec_2 : !cir.vector<!s32i x 4>) [#cir.int<0> : !s64i, #cir.int<4> : !s64i,
11+
#cir.int<1> : !s64i, #cir.int<5> : !s64i] : !cir.vector<!s32i x 4>
12+
cir.return %new_vec : !cir.vector<!s32i x 4>
13+
}
14+
15+
// CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<!s32i x 4> {
16+
// CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i,
17+
// CHECK-SAME: #cir.int<4> : !s32i]> : !cir.vector<!s32i x 4>
18+
// CHECK-NEXT: cir.return %[[RES]] : !cir.vector<!s32i x 4>
19+
}
20+
21+
// -----
22+
23+
!s32i = !cir.int<s, 32>
24+
!s64i = !cir.int<s, 64>
25+
26+
module {
27+
cir.func @fold_shuffle_vector_op_test() -> !cir.vector<!s32i x 6> {
28+
%vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<!s32i x 4>
29+
%vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<!s32i x 4>
30+
%new_vec = cir.vec.shuffle(%vec_1, %vec_2 : !cir.vector<!s32i x 4>) [#cir.int<0> : !s64i, #cir.int<4> : !s64i,
31+
#cir.int<1> : !s64i, #cir.int<5> : !s64i, #cir.int<2> : !s64i, #cir.int<6> : !s64i] : !cir.vector<!s32i x 6>
32+
cir.return %new_vec : !cir.vector<!s32i x 6>
33+
}
34+
35+
// CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<!s32i x 6> {
36+
// CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i,
37+
// CHECK-SAME: #cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i]> : !cir.vector<!s32i x 6>
38+
// CHECK-NEXT: cir.return %[[RES]] : !cir.vector<!s32i x 6>
39+
}
40+
41+
// -----
42+
43+
!s32i = !cir.int<s, 32>
44+
!s64i = !cir.int<s, 64>
45+
46+
module {
47+
cir.func @fold_shuffle_vector_op_test() -> !cir.vector<!s32i x 4> {
48+
%vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<!s32i x 4>
49+
%vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<!s32i x 4>
50+
%new_vec = cir.vec.shuffle(%vec_1, %vec_2 : !cir.vector<!s32i x 4>) [#cir.int<-1> : !s64i, #cir.int<4> : !s64i,
51+
#cir.int<1> : !s64i, #cir.int<5> : !s64i] : !cir.vector<!s32i x 4>
52+
cir.return %new_vec : !cir.vector<!s32i x 4>
53+
}
54+
55+
// CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<!s32i x 4> {
56+
// CHECK: cir.const #cir.const_vector<[#cir.undef : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i,
57+
// CHECK-SAME: #cir.int<4> : !s32i]> : !cir.vector<!s32i x 4>
58+
// CHECK-NEXT: cir.return %[[RES]] : !cir.vector<!s32i x 4>
59+
}

0 commit comments

Comments
 (0)