https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/143260
This change adds a folder for the VecShuffleOp Issue https://github.com/llvm/llvm-project/issues/136487 >From 14ffd458c4896bd4d5fb73f97c5745db70c8360e Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sat, 7 Jun 2025 14:43:16 +0200 Subject: [PATCH] [CIR] Implement folder for VecShuffleOp --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 38 ++++++++++++++++-- .../Dialect/Transforms/CIRCanonicalize.cpp | 2 +- .../CIR/Transforms/vector-shuffle-fold.cir | 39 +++++++++++++++++++ 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 clang/test/CIR/Transforms/vector-shuffle-fold.cir 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> +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits