https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/142315
>From 12c9d3f76360c28efc8ba07ac959af6cf45a6f10 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sun, 1 Jun 2025 19:07:56 +0200 Subject: [PATCH 1/4] [CIR] Implement folder for VecShuffleDynamicOp --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 1 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 32 +++++++++++++++++++ .../Dialect/Transforms/CIRCanonicalize.cpp | 6 ++-- .../vector-shuffle-dynamic-fold.cir | 18 +++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 237daed32532a..7db6725afb80c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2192,6 +2192,7 @@ def VecShuffleDynamicOp : CIR_Op<"vec.shuffle.dynamic", }]; let hasVerifier = 1; + let hasFolder = 1; } #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 36f050de9f8bb..90b32950e4774 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1579,6 +1579,38 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) { // VecShuffleDynamicOp //===----------------------------------------------------------------------===// +OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) { + mlir::Attribute vec = adaptor.getVec(); + mlir::Attribute indices = adaptor.getIndices(); + if (mlir::isa_and_nonnull<cir::ConstVectorAttr>(vec) && + mlir::isa_and_nonnull<cir::ConstVectorAttr>(indices)) { + auto vecAttr = mlir::cast<cir::ConstVectorAttr>(vec); + auto indicesAttr = mlir::cast<cir::ConstVectorAttr>(indices); + auto vecTy = cast<cir::VectorType>(vecAttr.getType()); + + mlir::ArrayAttr vecElts = vecAttr.getElts(); + mlir::ArrayAttr indicesElts = indicesAttr.getElts(); + + const uint64_t numElements = vecElts.size(); + + SmallVector<mlir::Attribute, 16> elements; + elements.reserve(numElements); + + const uint64_t maskBits = llvm::NextPowerOf2(numElements - 1) - 1; + for (uint64_t i = 0; i < numElements; i++) { + cir::IntAttr idxAttr = mlir::cast<cir::IntAttr>(indicesElts[i]); + uint64_t idxValue = idxAttr.getUInt(); + uint64_t newIdx = idxValue & maskBits; + elements.push_back(vecElts[newIdx]); + } + + return cir::ConstVectorAttr::get( + vecTy, mlir::ArrayAttr::get(getContext(), elements)); + } + + return {}; +} + LogicalResult cir::VecShuffleDynamicOp::verify() { // The number of elements in the two input vectors must match. if (getVec().getType().getSize() != diff --git a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp index fb000adee04c6..7d03e374c27e8 100644 --- a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp @@ -138,10 +138,10 @@ void CIRCanonicalizePass::runOnOperation() { assert(!cir::MissingFeatures::complexRealOp()); assert(!cir::MissingFeatures::complexImagOp()); assert(!cir::MissingFeatures::callOp()); - // CastOp, UnaryOp and VecExtractOp are here to perform a manual `fold` in - // applyOpPatternsGreedily. + // CastOp, UnaryOp, VecExtractOp and VecShuffleDynamicOp are here to perform + // a manual `fold` in applyOpPatternsGreedily. if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp, - VecExtractOp>(op)) + VecExtractOp, VecShuffleDynamicOp>(op)) ops.push_back(op); }); diff --git a/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir b/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir new file mode 100644 index 0000000000000..db5d6bff04d5b --- /dev/null +++ b/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir @@ -0,0 +1,18 @@ +// RUN: cir-opt %s -cir-canonicalize -o - | FileCheck %s + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_shuffle_dynamic_vector_op_test() { + %alloca = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["r", init] + %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> + %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> + %new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<4 x !s32i>, %indices : !cir.vector<4 x !s32i> + cir.store align(16) %new_vec, %alloca : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> + cir.return + } + + // CHECK: %[[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> +} + + >From 959bf9c766bb56ff5dc6e7d6c26a94a7cfae5d01 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Mon, 2 Jun 2025 21:59:54 +0200 Subject: [PATCH 2/4] Address code review comments --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 90b32950e4774..15c76f0755dda 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -21,6 +21,7 @@ #include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" #include "clang/CIR/Dialect/IR/CIROpsEnums.cpp.inc" #include "clang/CIR/MissingFeatures.h" + #include <numeric> using namespace mlir; @@ -1597,9 +1598,9 @@ OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) { elements.reserve(numElements); const uint64_t maskBits = llvm::NextPowerOf2(numElements - 1) - 1; - for (uint64_t i = 0; i < numElements; i++) { - cir::IntAttr idxAttr = mlir::cast<cir::IntAttr>(indicesElts[i]); - uint64_t idxValue = idxAttr.getUInt(); + for (const mlir::APInt &idxAttr : + indicesElts.getAsValueRange<cir::IntAttr, mlir::APInt>()) { + uint64_t idxValue = idxAttr.getZExtValue(); uint64_t newIdx = idxValue & maskBits; elements.push_back(vecElts[newIdx]); } >From ec7d646c052d9cbe30617f2cdb4da48ac059bfce Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Mon, 2 Jun 2025 23:11:01 +0200 Subject: [PATCH 3/4] Use getAsRange in for range --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 15c76f0755dda..26ebe6c1dbcd1 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1587,7 +1587,7 @@ 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 = cast<cir::VectorType>(vecAttr.getType()); + auto vecTy = mlir::cast<cir::VectorType>(vecAttr.getType()); mlir::ArrayAttr vecElts = vecAttr.getElts(); mlir::ArrayAttr indicesElts = indicesAttr.getElts(); @@ -1598,9 +1598,8 @@ OpFoldResult cir::VecShuffleDynamicOp::fold(FoldAdaptor adaptor) { elements.reserve(numElements); const uint64_t maskBits = llvm::NextPowerOf2(numElements - 1) - 1; - for (const mlir::APInt &idxAttr : - indicesElts.getAsValueRange<cir::IntAttr, mlir::APInt>()) { - uint64_t idxValue = idxAttr.getZExtValue(); + for (const auto &idxAttr : indicesElts.getAsRange<cir::IntAttr>()) { + uint64_t idxValue = idxAttr.getUInt(); uint64_t newIdx = idxValue & maskBits; elements.push_back(vecElts[newIdx]); } >From 2a58fc9df5f91671dfe308ffab561b6fa1f2fad6 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Wed, 4 Jun 2025 21:23:33 +0200 Subject: [PATCH 4/4] Extend the folding test --- .../vector-shuffle-dynamic-fold.cir | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir b/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir index db5d6bff04d5b..46ab04502afec 100644 --- a/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir +++ b/clang/test/CIR/Transforms/vector-shuffle-dynamic-fold.cir @@ -3,16 +3,29 @@ !s32i = !cir.int<s, 32> module { - cir.func @fold_shuffle_dynamic_vector_op_test() { - %alloca = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["r", init] + cir.func @fold_shuffle_dynamic_vector_op_test() -> !cir.vector<4 x !s32i> { %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> %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> %new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<4 x !s32i>, %indices : !cir.vector<4 x !s32i> - cir.store align(16) %new_vec, %alloca : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> - cir.return + cir.return %new_vec : !cir.vector<4 x !s32i> } - // CHECK: %[[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> + // Masking indices [8, 7, 6, 5] AND 3 = [0, 3, 2, 1] + // CHECK: cir.func @fold_shuffle_dynamic_vector_op_test() -> !cir.vector<4 x !s32i> { + // 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> + // CHECK-NEXT: cir.return %[[NEW_VEC:.*]] : !cir.vector<4 x !s32i> + + cir.func @fold_shuffle_dynamic_vector_op_test_2() -> !cir.vector<4 x !s32i> { + %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> + %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> + %new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<4 x !s32i>, %indices : !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // Masking indices [3, 2, 1, 0] AND 3 = [3, 2, 1, 0] + // CHECK: cir.func @fold_shuffle_dynamic_vector_op_test_2() -> !cir.vector<4 x !s32i> { + // 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> + // CHECK-NEXT: cir.return %[[NEW_VEC:.*]] : !cir.vector<4 x !s32i> } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits