-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[CIR] Implement folder for VecShuffleOp #143260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clangir @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesThis change adds a folder for the VecShuffleOp Issue #136487 Full diff: https://github.com/llvm/llvm-project/pull/143260.diff 4 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 038a59b8ff4eb..568861cea9f92 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2199,7 +2199,9 @@ def VecShuffleOp : CIR_Op<"vec.shuffle",
`(` $vec1 `,` $vec2 `:` qualified(type($vec1)) `)` $indices `:`
qualified(type($result)) attr-dict
}];
+
let hasVerifier = 1;
+ let hasFolder = 1;
}
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index bfd3a0a62a8e7..0eae0494eafd5 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -1580,9 +1580,42 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) {
}
//===----------------------------------------------------------------------===//
-// VecShuffle
+// VecShuffleOp
//===----------------------------------------------------------------------===//
+OpFoldResult cir::VecShuffleOp::fold(FoldAdaptor adaptor) {
+ mlir::Attribute vec1 = adaptor.getVec1();
+ mlir::Attribute vec2 = adaptor.getVec2();
+
+ if (!mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec1) ||
+ !mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec2)) {
+ return {};
+ }
+
+ auto vec1Attr = mlir::cast<cir::ConstVectorAttr>(vec1);
+ auto vec2Attr = mlir::cast<cir::ConstVectorAttr>(vec2);
+
+ mlir::ArrayAttr vec1Elts = vec1Attr.getElts();
+ mlir::ArrayAttr vec2Elts = vec2Attr.getElts();
+ mlir::ArrayAttr indicesElts = adaptor.getIndices();
+
+ SmallVector<mlir::Attribute, 16> elements;
+ elements.reserve(indicesElts.size());
+
+ uint64_t vec1Size = vec1Elts.size();
+ for (const auto &idxAttr : indicesElts.getAsRange<cir::IntAttr>()) {
+ uint64_t idxValue = idxAttr.getUInt();
+ if (idxValue < vec1Size) {
+ elements.push_back(vec1Elts[idxValue]);
+ } else {
+ elements.push_back(vec2Elts[idxValue - vec1Size]);
+ }
+ }
+
+ return cir::ConstVectorAttr::get(
+ getType(), mlir::ArrayAttr::get(getContext(), elements));
+}
+
LogicalResult cir::VecShuffleOp::verify() {
// The number of elements in the indices array must match the number of
// elements in the result type.
@@ -1613,7 +1646,6 @@ OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) {
mlir::isa_and_nonnull<cir::ConstVectorAttr>(indices)) {
auto vecAttr = mlir::cast<cir::ConstVectorAttr>(vec);
auto indicesAttr = mlir::cast<cir::ConstVectorAttr>(indices);
- auto vecTy = mlir::cast<cir::VectorType>(vecAttr.getType());
mlir::ArrayAttr vecElts = vecAttr.getElts();
mlir::ArrayAttr indicesElts = indicesAttr.getElts();
@@ -1631,7 +1663,7 @@ OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) {
}
return cir::ConstVectorAttr::get(
- vecTy, mlir::ArrayAttr::get(getContext(), elements));
+ getType(), mlir::ArrayAttr::get(getContext(), elements));
}
return {};
diff --git a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp
index 33881c69eec5f..29f9942638964 100644
--- a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp
@@ -142,7 +142,7 @@ void CIRCanonicalizePass::runOnOperation() {
// Many operations are here to perform a manual `fold` in
// applyOpPatternsGreedily.
if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp,
- VecExtractOp, VecShuffleDynamicOp, VecTernaryOp>(op))
+ VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecTernaryOp>(op))
ops.push_back(op);
});
diff --git a/clang/test/CIR/Transforms/vector-shuffle-fold.cir b/clang/test/CIR/Transforms/vector-shuffle-fold.cir
new file mode 100644
index 0000000000000..a6b43b6f2951d
--- /dev/null
+++ b/clang/test/CIR/Transforms/vector-shuffle-fold.cir
@@ -0,0 +1,39 @@
+// RUN: cir-opt %s -cir-canonicalize -o - -split-input-file | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+!s64i = !cir.int<s, 64>
+
+module {
+ cir.func @fold_shuffle_vector_op_test() -> !cir.vector<4 x !s32i> {
+ %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<4 x !s32i>
+ %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<4 x !s32i>
+ %new_vec = cir.vec.shuffle(%vec_1, %vec_2 : !cir.vector<4 x !s32i>) [#cir.int<0> : !s64i, #cir.int<4> : !s64i,
+ #cir.int<1> : !s64i, #cir.int<5> : !s64i] : !cir.vector<4 x !s32i>
+ cir.return %new_vec : !cir.vector<4 x !s32i>
+ }
+
+ // CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<4 x !s32i> {
+ // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i,
+ // CHECK-SAME: #cir.int<4> : !s32i]> : !cir.vector<4 x !s32i>
+ // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i>
+}
+
+// -----
+
+!s32i = !cir.int<s, 32>
+!s64i = !cir.int<s, 64>
+
+module {
+ cir.func @fold_shuffle_vector_op_test() -> !cir.vector<6 x !s32i> {
+ %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<4 x !s32i>
+ %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<4 x !s32i>
+ %new_vec = cir.vec.shuffle(%vec_1, %vec_2 : !cir.vector<4 x !s32i>) [#cir.int<0> : !s64i, #cir.int<4> : !s64i,
+ #cir.int<1> : !s64i, #cir.int<5> : !s64i, #cir.int<2> : !s64i, #cir.int<6> : !s64i] : !cir.vector<6 x !s32i>
+ cir.return %new_vec : !cir.vector<6 x !s32i>
+ }
+
+ // CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<6 x !s32i> {
+ // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i,
+ // CHECK-SAME: #cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i]> : !cir.vector<6 x !s32i>
+ // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<6 x !s32i>
+}
|
mlir::Attribute vec1 = adaptor.getVec1(); | ||
mlir::Attribute vec2 = adaptor.getVec2(); | ||
|
||
if (!mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec1) || | ||
!mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec2)) { | ||
return {}; | ||
} | ||
|
||
auto vec1Attr = mlir::cast<cir::ConstVectorAttr>(vec1); | ||
auto vec2Attr = mlir::cast<cir::ConstVectorAttr>(vec2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mlir::Attribute vec1 = adaptor.getVec1(); | |
mlir::Attribute vec2 = adaptor.getVec2(); | |
if (!mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec1) || | |
!mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec2)) { | |
return {}; | |
} | |
auto vec1Attr = mlir::cast<cir::ConstVectorAttr>(vec1); | |
auto vec2Attr = mlir::cast<cir::ConstVectorAttr>(vec2); | |
auto vec1Attr = mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getVec1()); | |
auto vec2Attr = mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getVec2())); | |
if (!vec1Attr || !vec2Attr) | |
return {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this folder, one nit and good to go
if (idxValue < vec1Size) { | ||
elements.push_back(vec1Elts[idxValue]); | ||
} else { | ||
elements.push_back(vec2Elts[idxValue - vec1Size]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elements.push_back(idxValue < vec1Size ? vec1Elts[idxValue] : vec2Elts[idxValue - vec1Size])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This change adds a folder for the VecShuffleOp
Issue #136487