[clang] [CIR] Upstream unary operators for VectorType (PR #139444)
https://github.com/bcardosolopes approved this pull request. LGTM after minor nit https://github.com/llvm/llvm-project/pull/139444 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream unary operators for VectorType (PR #139444)
@@ -54,10 +54,10 @@ namespace direct { namespace { /// If the given type is a vector type, return the vector's element type. /// Otherwise return the given type unchanged. -// TODO(cir): Return the vector element type once we have support for vectors -// instead of the identity type. mlir::Type elementTypeIfVector(mlir::Type type) { - assert(!cir::MissingFeatures::vectorType()); + if (const auto vecType = mlir::dyn_cast(type)) { bcardosolopes wrote: we probably don't need the curly braces here! https://github.com/llvm/llvm-project/pull/139444 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream unary operators for VectorType (PR #139444)
https://github.com/bcardosolopes edited https://github.com/llvm/llvm-project/pull/139444 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream unary operators for VectorType (PR #139444)
llvmbot wrote: @llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) Changes This change adds support for unary ops for VectorType Issue https://github.com/llvm/llvm-project/issues/136487 --- Full diff: https://github.com/llvm/llvm-project/pull/139444.diff 3 Files Affected: - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+37-17) - (modified) clang/test/CIR/CodeGen/vector-ext.cpp (+56) - (modified) clang/test/CIR/CodeGen/vector.cpp (+56) ``diff diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 5986655ababe9..fb55b2984daea 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -54,10 +54,10 @@ namespace direct { namespace { /// If the given type is a vector type, return the vector's element type. /// Otherwise return the given type unchanged. -// TODO(cir): Return the vector element type once we have support for vectors -// instead of the identity type. mlir::Type elementTypeIfVector(mlir::Type type) { - assert(!cir::MissingFeatures::vectorType()); + if (const auto vecType = mlir::dyn_cast(type)) { +return vecType.getElementType(); + } return type; } } // namespace @@ -1043,12 +1043,11 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { assert(op.getType() == op.getInput().getType() && "Unary operation's operand type and result type are different"); - mlir::Type type = op.getType(); - mlir::Type elementType = type; - bool isVector = false; - assert(!cir::MissingFeatures::vectorType()); - mlir::Type llvmType = getTypeConverter()->convertType(type); - mlir::Location loc = op.getLoc(); + const mlir::Type type = op.getType(); + const mlir::Type elementType = elementTypeIfVector(type); + const bool isVector = mlir::isa(type); + const mlir::Type llvmType = getTypeConverter()->convertType(type); + const mlir::Location loc = op.getLoc(); // Integer unary operations: + - ~ ++ -- if (mlir::isa(elementType)) { @@ -1076,20 +1075,41 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( rewriter.replaceOp(op, adaptor.getInput()); return mlir::success(); case cir::UnaryOpKind::Minus: { - assert(!isVector && - "Add vector handling when vector types are supported"); - mlir::LLVM::ConstantOp zero = rewriter.create( - loc, llvmType, mlir::IntegerAttr::get(llvmType, 0)); + mlir::Value zero; + if (isVector) +zero = rewriter.create(loc, llvmType); + else +zero = rewriter.create( +loc, llvmType, mlir::IntegerAttr::get(llvmType, 0)); rewriter.replaceOpWithNewOp( op, llvmType, zero, adaptor.getInput(), maybeNSW); return mlir::success(); } case cir::UnaryOpKind::Not: { // bit-wise compliment operator, implemented as an XOR with -1. - assert(!isVector && - "Add vector handling when vector types are supported"); - mlir::LLVM::ConstantOp minusOne = rewriter.create( - loc, llvmType, mlir::IntegerAttr::get(llvmType, -1)); + mlir::Value minusOne; + if (isVector) { +// Creating a vector object with all -1 values is easier said than +// done. It requires a series of insertelement ops. +const mlir::Type llvmElementType = +getTypeConverter()->convertType(elementType); +const mlir::Value minusOneInt = rewriter.create( +loc, llvmElementType, mlir::IntegerAttr::get(llvmElementType, -1)); +minusOne = rewriter.create(loc, llvmType); + +const uint64_t numElements = +mlir::dyn_cast(type).getSize(); +for (uint64_t i = 0; i < numElements; ++i) { + const mlir::Value indexValue = + rewriter.create(loc, + rewriter.getI64Type(), i); + minusOne = rewriter.create( + loc, minusOne, minusOneInt, indexValue); +} + } else { +minusOne = rewriter.create( +loc, llvmType, mlir::IntegerAttr::get(llvmType, -1)); + } rewriter.replaceOpWithNewOp( op, llvmType, adaptor.getInput(), minusOne); return mlir::success(); diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index 0756497bf6b96..005f629b88143 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -213,3 +213,59 @@ void foo4() { // OGCG: %[[TMP2:.*]] = load i32, ptr %[[IDX]], align 4 // OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP1]], i32 %[[TMP2]] // OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +void foo8() { + vi4 a = { 1, 2, 3, 4 }; + vi4 plus_res = +a; + vi4 minus_res = -a; + vi4 not_res = ~a; +} + +// CIR: %[[VEC:.*]] = cir.alloca !cir.vector<4 x !s32i>, !ci
[clang] [CIR] Upstream unary operators for VectorType (PR #139444)
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/139444 This change adds support for unary ops for VectorType Issue https://github.com/llvm/llvm-project/issues/136487 >From 9fd2f92f9122c8c79c4977e00dab93bfaa468787 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 10 May 2025 20:37:05 +0200 Subject: [PATCH] [CIR] Upstream unary operators for VectorType --- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 54 -- clang/test/CIR/CodeGen/vector-ext.cpp | 56 +++ clang/test/CIR/CodeGen/vector.cpp | 56 +++ 3 files changed, 149 insertions(+), 17 deletions(-) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 5986655ababe9..fb55b2984daea 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -54,10 +54,10 @@ namespace direct { namespace { /// If the given type is a vector type, return the vector's element type. /// Otherwise return the given type unchanged. -// TODO(cir): Return the vector element type once we have support for vectors -// instead of the identity type. mlir::Type elementTypeIfVector(mlir::Type type) { - assert(!cir::MissingFeatures::vectorType()); + if (const auto vecType = mlir::dyn_cast(type)) { +return vecType.getElementType(); + } return type; } } // namespace @@ -1043,12 +1043,11 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { assert(op.getType() == op.getInput().getType() && "Unary operation's operand type and result type are different"); - mlir::Type type = op.getType(); - mlir::Type elementType = type; - bool isVector = false; - assert(!cir::MissingFeatures::vectorType()); - mlir::Type llvmType = getTypeConverter()->convertType(type); - mlir::Location loc = op.getLoc(); + const mlir::Type type = op.getType(); + const mlir::Type elementType = elementTypeIfVector(type); + const bool isVector = mlir::isa(type); + const mlir::Type llvmType = getTypeConverter()->convertType(type); + const mlir::Location loc = op.getLoc(); // Integer unary operations: + - ~ ++ -- if (mlir::isa(elementType)) { @@ -1076,20 +1075,41 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( rewriter.replaceOp(op, adaptor.getInput()); return mlir::success(); case cir::UnaryOpKind::Minus: { - assert(!isVector && - "Add vector handling when vector types are supported"); - mlir::LLVM::ConstantOp zero = rewriter.create( - loc, llvmType, mlir::IntegerAttr::get(llvmType, 0)); + mlir::Value zero; + if (isVector) +zero = rewriter.create(loc, llvmType); + else +zero = rewriter.create( +loc, llvmType, mlir::IntegerAttr::get(llvmType, 0)); rewriter.replaceOpWithNewOp( op, llvmType, zero, adaptor.getInput(), maybeNSW); return mlir::success(); } case cir::UnaryOpKind::Not: { // bit-wise compliment operator, implemented as an XOR with -1. - assert(!isVector && - "Add vector handling when vector types are supported"); - mlir::LLVM::ConstantOp minusOne = rewriter.create( - loc, llvmType, mlir::IntegerAttr::get(llvmType, -1)); + mlir::Value minusOne; + if (isVector) { +// Creating a vector object with all -1 values is easier said than +// done. It requires a series of insertelement ops. +const mlir::Type llvmElementType = +getTypeConverter()->convertType(elementType); +const mlir::Value minusOneInt = rewriter.create( +loc, llvmElementType, mlir::IntegerAttr::get(llvmElementType, -1)); +minusOne = rewriter.create(loc, llvmType); + +const uint64_t numElements = +mlir::dyn_cast(type).getSize(); +for (uint64_t i = 0; i < numElements; ++i) { + const mlir::Value indexValue = + rewriter.create(loc, + rewriter.getI64Type(), i); + minusOne = rewriter.create( + loc, minusOne, minusOneInt, indexValue); +} + } else { +minusOne = rewriter.create( +loc, llvmType, mlir::IntegerAttr::get(llvmType, -1)); + } rewriter.replaceOpWithNewOp( op, llvmType, adaptor.getInput(), minusOne); return mlir::success(); diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index 0756497bf6b96..005f629b88143 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -213,3 +213,59 @@ void foo4() { // OGCG: %[[TMP2:.*]] = load i32, ptr %[[IDX]], align 4 // OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP1]], i32 %[[TMP2]] // OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +void