https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/143322
>From 0e26df27ffd6adaeefedfdafd72b565f6648c96f Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sun, 8 Jun 2025 21:08:14 +0200 Subject: [PATCH 1/3] [CIR] Implement folder for VecCmpOp --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 103 ++++++++ .../Dialect/Transforms/CIRCanonicalize.cpp | 3 +- clang/test/CIR/Transforms/vector-cmp-fold.cir | 227 ++++++++++++++++++ 4 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 clang/test/CIR/Transforms/vector-cmp-fold.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 565c0676773e6..9b63716629425 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2154,6 +2154,8 @@ def VecCmpOp : CIR_Op<"vec.cmp", [Pure, SameTypeOperands]> { `(` $kind `,` $lhs `,` $rhs `)` `:` qualified(type($lhs)) `,` qualified(type($result)) attr-dict }]; + + let hasFolder = 1; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index a6cf0a6b5d75e..29bc20498bcce 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1579,6 +1579,109 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) { return elements[index]; } +//===----------------------------------------------------------------------===// +// VecCmpOp +//===----------------------------------------------------------------------===// + +OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { + mlir::Attribute lhs = adaptor.getLhs(); + mlir::Attribute rhs = adaptor.getRhs(); + if (!mlir::isa_and_nonnull<cir::ConstVectorAttr>(lhs) || + !mlir::isa_and_nonnull<cir::ConstVectorAttr>(rhs)) + return {}; + + auto lhsVecAttr = mlir::cast<cir::ConstVectorAttr>(lhs); + auto rhsVecAttr = mlir::cast<cir::ConstVectorAttr>(rhs); + + auto inputElemTy = + mlir::cast<cir::VectorType>(lhsVecAttr.getType()).getElementType(); + if (!mlir::isa<cir::IntType>(inputElemTy) && + !mlir::isa<cir::CIRFPTypeInterface>(inputElemTy)) + return {}; + + cir::CmpOpKind opKind = adaptor.getKind(); + mlir::ArrayAttr lhsVecElhs = lhsVecAttr.getElts(); + mlir::ArrayAttr rhsVecElhs = rhsVecAttr.getElts(); + uint64_t vecSize = lhsVecElhs.size(); + + auto resultVecTy = mlir::cast<cir::VectorType>(getType()); + + SmallVector<mlir::Attribute, 16> elements(vecSize); + for (uint64_t i = 0; i < vecSize; i++) { + mlir::Attribute lhsAttr = lhsVecElhs[i]; + mlir::Attribute rhsAttr = rhsVecElhs[i]; + + int cmpResult = 0; + switch (opKind) { + case cir::CmpOpKind::lt: { + if (mlir::isa<cir::IntAttr>(lhsAttr)) { + cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() < + mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast<cir::FPAttr>(lhsAttr).getValue() < + mlir::cast<cir::FPAttr>(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::le: { + if (mlir::isa<cir::IntAttr>(lhsAttr)) { + cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() <= + mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast<cir::FPAttr>(lhsAttr).getValue() <= + mlir::cast<cir::FPAttr>(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::gt: { + if (mlir::isa<cir::IntAttr>(lhsAttr)) { + cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() > + mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast<cir::FPAttr>(lhsAttr).getValue() > + mlir::cast<cir::FPAttr>(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::ge: { + if (mlir::isa<cir::IntAttr>(lhsAttr)) { + cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() >= + mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast<cir::FPAttr>(lhsAttr).getValue() >= + mlir::cast<cir::FPAttr>(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::eq: { + if (mlir::isa<cir::IntAttr>(lhsAttr)) { + cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() == + mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast<cir::FPAttr>(lhsAttr).getValue() == + mlir::cast<cir::FPAttr>(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::ne: { + if (mlir::isa<cir::IntAttr>(lhsAttr)) { + cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() != + mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast<cir::FPAttr>(lhsAttr).getValue() != + mlir::cast<cir::FPAttr>(rhsAttr).getValue(); + } + break; + } + } + + elements[i] = cir::IntAttr::get(resultVecTy.getElementType(), cmpResult); + } + + return cir::ConstVectorAttr::get( + getType(), mlir::ArrayAttr::get(getContext(), elements)); +} + //===----------------------------------------------------------------------===// // VecShuffleOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp index 29f9942638964..4328e2a53b4f4 100644 --- a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp @@ -142,7 +142,8 @@ void CIRCanonicalizePass::runOnOperation() { // Many operations are here to perform a manual `fold` in // applyOpPatternsGreedily. if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp, - VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecTernaryOp>(op)) + VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecTernaryOp, + VecCmpOp>(op)) ops.push_back(op); }); diff --git a/clang/test/CIR/Transforms/vector-cmp-fold.cir b/clang/test/CIR/Transforms/vector-cmp-fold.cir new file mode 100644 index 0000000000000..b207fc08748e2 --- /dev/null +++ b/clang/test/CIR/Transforms/vector-cmp-fold.cir @@ -0,0 +1,227 @@ +// RUN: cir-opt %s -cir-canonicalize -o - -split-input-file | FileCheck %s + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_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.cmp(eq, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_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.cmp(ne, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_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.cmp(lt, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_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.cmp(le, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_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.cmp(gt, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_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.cmp(gt, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(eq, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(ne, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(lt, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(le, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(gt, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(ge, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} >From c2e3c51b8594f7aa0069f310f7bc06dc2f550756 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Mon, 9 Jun 2025 20:36:31 +0200 Subject: [PATCH 2/3] Address code review comments --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 5 ++--- clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 29bc20498bcce..8aa80594e5e9e 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1593,10 +1593,9 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { auto lhsVecAttr = mlir::cast<cir::ConstVectorAttr>(lhs); auto rhsVecAttr = mlir::cast<cir::ConstVectorAttr>(rhs); - auto inputElemTy = + mlir::Type inputElemTy = mlir::cast<cir::VectorType>(lhsVecAttr.getType()).getElementType(); - if (!mlir::isa<cir::IntType>(inputElemTy) && - !mlir::isa<cir::CIRFPTypeInterface>(inputElemTy)) + if (!isAnyIntegerOrFloatingPointType(inputElemTy)) return {}; cir::CmpOpKind opKind = adaptor.getKind(); diff --git a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp index 4328e2a53b4f4..11aff25f9c11f 100644 --- a/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp @@ -141,9 +141,9 @@ void CIRCanonicalizePass::runOnOperation() { // Many operations are here to perform a manual `fold` in // applyOpPatternsGreedily. - if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp, - VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecTernaryOp, - VecCmpOp>(op)) + if (isa<BrCondOp, BrOp, CastOp, ScopeOp, SelectOp, SwitchOp, UnaryOp, + VecCmpOp, VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, + VecTernaryOp>(op)) ops.push_back(op); }); >From 78af912ee2ed4e5e19d445bae7c5f53ac1d44318 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Tue, 10 Jun 2025 20:54:10 +0200 Subject: [PATCH 3/3] Address code review comments --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 30 +++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 8aa80594e5e9e..ab6aeeb690ad1 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1584,15 +1584,13 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) { //===----------------------------------------------------------------------===// OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { - mlir::Attribute lhs = adaptor.getLhs(); - mlir::Attribute rhs = adaptor.getRhs(); - if (!mlir::isa_and_nonnull<cir::ConstVectorAttr>(lhs) || - !mlir::isa_and_nonnull<cir::ConstVectorAttr>(rhs)) + auto lhsVecAttr = + mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getLhs()); + auto rhsVecAttr = + mlir::dyn_cast_if_present<cir::ConstVectorAttr>(adaptor.getRhs()); + if (!lhsVecAttr || !rhsVecAttr) return {}; - auto lhsVecAttr = mlir::cast<cir::ConstVectorAttr>(lhs); - auto rhsVecAttr = mlir::cast<cir::ConstVectorAttr>(rhs); - mlir::Type inputElemTy = mlir::cast<cir::VectorType>(lhsVecAttr.getType()).getElementType(); if (!isAnyIntegerOrFloatingPointType(inputElemTy)) @@ -1603,17 +1601,15 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { mlir::ArrayAttr rhsVecElhs = rhsVecAttr.getElts(); uint64_t vecSize = lhsVecElhs.size(); - auto resultVecTy = mlir::cast<cir::VectorType>(getType()); - SmallVector<mlir::Attribute, 16> elements(vecSize); + bool isIntAttr = vecSize ? mlir::isa<cir::IntAttr>(lhsVecElhs[0]) : false; for (uint64_t i = 0; i < vecSize; i++) { mlir::Attribute lhsAttr = lhsVecElhs[i]; mlir::Attribute rhsAttr = rhsVecElhs[i]; - int cmpResult = 0; switch (opKind) { case cir::CmpOpKind::lt: { - if (mlir::isa<cir::IntAttr>(lhsAttr)) { + if (isIntAttr) { cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() < mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); } else { @@ -1623,7 +1619,7 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { break; } case cir::CmpOpKind::le: { - if (mlir::isa<cir::IntAttr>(lhsAttr)) { + if (isIntAttr) { cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() <= mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); } else { @@ -1633,7 +1629,7 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { break; } case cir::CmpOpKind::gt: { - if (mlir::isa<cir::IntAttr>(lhsAttr)) { + if (isIntAttr) { cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() > mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); } else { @@ -1643,7 +1639,7 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { break; } case cir::CmpOpKind::ge: { - if (mlir::isa<cir::IntAttr>(lhsAttr)) { + if (isIntAttr) { cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() >= mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); } else { @@ -1653,7 +1649,7 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { break; } case cir::CmpOpKind::eq: { - if (mlir::isa<cir::IntAttr>(lhsAttr)) { + if (isIntAttr) { cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() == mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); } else { @@ -1663,7 +1659,7 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { break; } case cir::CmpOpKind::ne: { - if (mlir::isa<cir::IntAttr>(lhsAttr)) { + if (isIntAttr) { cmpResult = mlir::cast<cir::IntAttr>(lhsAttr).getSInt() != mlir::cast<cir::IntAttr>(rhsAttr).getSInt(); } else { @@ -1674,7 +1670,7 @@ OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { } } - elements[i] = cir::IntAttr::get(resultVecTy.getElementType(), cmpResult); + elements[i] = cir::IntAttr::get(getType().getElementType(), cmpResult); } return cir::ConstVectorAttr::get( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits