diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index c58d86850c6f..4737afe714ff 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3107,6 +3107,7 @@ def VecCreateOp : CIR_Op<"vec.create", [Pure]> { }]; 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 814a3e2091f6..a1293e093a4b 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1011,6 +1011,16 @@ void cir::StoreOp::setAtomic(cir::MemOrder order) { // VecCreateOp //===----------------------------------------------------------------------===// +OpFoldResult cir::VecCreateOp::fold(FoldAdaptor adaptor) { + if (llvm::any_of(getElements(), [](mlir::Value value) { + return !mlir::isa(value.getDefiningOp()); + })) + return {}; + + return cir::ConstVectorAttr::get( + getType(), mlir::ArrayAttr::get(getContext(), adaptor.getElements())); +} + LogicalResult cir::VecCreateOp::verify() { // Verify that the number of arguments matches the number of elements in the // vector, and that the type of all the arguments matches the type of the diff --git a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp index f849b6cc08f8..7862ae4b34e0 100644 --- a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp @@ -179,7 +179,7 @@ void CIRCanonicalizePass::runOnOperation() { // CastOp, UnaryOp and VecExtractOp are here to perform a manual `fold` in // applyOpPatternsGreedily. if (isa(op)) ops.push_back(op); }); diff --git a/clang/test/CIR/Transforms/vector-create-fold.cir b/clang/test/CIR/Transforms/vector-create-fold.cir new file mode 100644 index 000000000000..65bc51d8c36c --- /dev/null +++ b/clang/test/CIR/Transforms/vector-create-fold.cir @@ -0,0 +1,19 @@ +// RUN: cir-opt %s -cir-canonicalize -o - | FileCheck %s + +!s32i = !cir.int + +module { + cir.func @fold_create_vector_op_test() -> !cir.vector { + %2 = cir.const #cir.int<1> : !s32i + %3 = cir.const #cir.int<2> : !s32i + %4 = cir.const #cir.int<3> : !s32i + %5 = cir.const #cir.int<4> : !s32i + %vec = cir.vec.create(%2, %3, %4, %5 : !s32i, !s32i, !s32i, !s32i) : !cir.vector + cir.return %vec : !cir.vector + } + + // CHECK: cir.func @fold_create_vector_op_test() -> !cir.vector { + // CHECK-NEXT: %[[VEC:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, + // CHECK-SAME: #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector + // CHECK-NEXT: cir.return %[[VEC]] : !cir.vector +}