[clang] [CIR] Upstream unary operators for VectorType (PR #139444)

2025-05-13 Thread Bruno Cardoso Lopes via cfe-commits

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)

2025-05-13 Thread Bruno Cardoso Lopes via cfe-commits


@@ -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)

2025-05-13 Thread Bruno Cardoso Lopes via cfe-commits

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)

2025-05-11 Thread via cfe-commits

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)

2025-05-11 Thread Amr Hesham via cfe-commits

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