Skip to content

[CIR] Upstream initial support for fixed size VectorType #136488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 26, 2025

Conversation

AmrDeveloper
Copy link
Member

This change adds the initial support for VectorType

Issue #136487

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Apr 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 20, 2025

@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

Changes

This change adds the initial support for VectorType

Issue #136487


Full diff: https://github.com/llvm/llvm-project/pull/136488.diff

10 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+2)
  • (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.td (+21-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+3)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+9)
  • (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+1-1)
  • (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (+18-1)
  • (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+5)
  • (added) clang/test/CIR/CodeGen/vector-ext.cpp (+60)
  • (added) clang/test/CIR/CodeGen/vector.cpp (+73)
  • (added) clang/test/CIR/IR/vector.cir (+40)
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index d2a241964f34f..04d9fec9f3001 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -93,6 +93,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
       return cir::FPAttr::getZero(ty);
     if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
       return getZeroAttr(arrTy);
+    if (auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
+      return getZeroAttr(vecTy);
     if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
       return getConstNullPtrAttr(ptrTy);
     if (auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index a552b6081f5dc..8fb46cea618a3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array",
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// VectorType (fixed size)
+//===----------------------------------------------------------------------===//
+
+def CIR_VectorType : CIR_Type<"Vector", "vector",
+    [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+
+  let summary = "CIR vector type";
+  let description = [{
+    `cir.vector' represents fixed-size vector types.  The parameters are the
+    element type and the number of elements.
+  }];
+
+  let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);
+
+  let assemblyFormat = [{
+    `<` $eltType `x` $size `>`
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // FuncType
 //===----------------------------------------------------------------------===//
@@ -530,7 +550,7 @@ def CIRRecordType : Type<
 //===----------------------------------------------------------------------===//
 
 def CIR_AnyType : AnyTypeOf<[
-  CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_IntType, CIR_AnyFloat,
+  CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, CIR_AnyFloat,
   CIR_PointerType, CIR_FuncType, CIR_RecordType
 ]>;
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index d98416734b56e..ae4f5c5ebef94 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -82,6 +82,9 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
                   cir::IntType>(ty))
       return true;
 
+    if (mlir::isa<cir::VectorType>(ty))
+      return isSized(mlir::cast<cir::VectorType>(ty).getEltType());
+
     assert(!cir::MissingFeatures::unsizedTypes());
     return false;
   }
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index c286aef360b01..01e8f3576fbe3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -399,6 +399,15 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
     break;
   }
 
+  case Type::ExtVector:
+  case Type::Vector: {
+    const VectorType *vec = cast<VectorType>(ty);
+    const mlir::Type elemTy = convertTypeForMem(vec->getElementType());
+    resultType = cir::VectorType::get(builder.getContext(), elemTy,
+                                      vec->getNumElements());
+    break;
+  }
+
   case Type::FunctionNoProto:
   case Type::FunctionProto:
     resultType = convertFunctionTypeInternal(type);
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index d2313e75870b4..1011f1b76b19b 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -212,7 +212,7 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
   }
 
   if (isa<cir::ZeroAttr>(attrType)) {
-    if (isa<cir::RecordType, cir::ArrayType>(opType))
+    if (isa<cir::RecordType, cir::ArrayType, cir::VectorType>(opType))
       return success();
     return op->emitOpError("zero expects struct or array type");
   }
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 8b5646f339bb3..f4ec524b65129 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -622,7 +622,7 @@ BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
 }
 
 //===----------------------------------------------------------------------===//
-//  Definitions
+//  ArrayType Definitions
 //===----------------------------------------------------------------------===//
 
 llvm::TypeSize
@@ -637,6 +637,23 @@ ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
   return dataLayout.getTypeABIAlignment(getEltType());
 }
 
+//===----------------------------------------------------------------------===//
+// VectorType Definitions
+//===----------------------------------------------------------------------===//
+
+llvm::TypeSize cir::VectorType::getTypeSizeInBits(
+    const ::mlir::DataLayout &dataLayout,
+    ::mlir::DataLayoutEntryListRef params) const {
+  return llvm::TypeSize::getFixed(getSize() *
+                                  dataLayout.getTypeSizeInBits(getEltType()));
+}
+
+uint64_t
+cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
+                                 ::mlir::DataLayoutEntryListRef params) const {
+  return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*this));
+}
+
 //===----------------------------------------------------------------------===//
 // PointerType Definitions
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 8c4a67258df3f..9c35327e43215 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -19,6 +19,7 @@
 #include "mlir/Dialect/DLTI/DLTI.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
 #include "mlir/IR/BuiltinDialect.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/Types.h"
@@ -1308,6 +1309,10 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
         convertTypeForMemory(converter, dataLayout, type.getEltType());
     return mlir::LLVM::LLVMArrayType::get(ty, type.getSize());
   });
+  converter.addConversion([&](cir::VectorType type) -> mlir::Type {
+    const mlir::Type ty = converter.convertType(type.getEltType());
+    return mlir::VectorType::get(type.getSize(), ty);
+  });
   converter.addConversion([&](cir::BoolType type) -> mlir::Type {
     return mlir::IntegerType::get(type.getContext(), 1,
                                   mlir::IntegerType::Signless);
diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp
new file mode 100644
index 0000000000000..155a00667e9b9
--- /dev/null
+++ b/clang/test/CIR/CodeGen/vector-ext.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+typedef int vi4 __attribute__((vector_size(16)));
+typedef double vd2 __attribute__((vector_size(16)));
+typedef long long vll2 __attribute__((vector_size(16)));
+
+vi4 vec_a;
+// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<!s32i x 4>
+
+// LLVM: @[[VEC_A:.*]] = dso_local global <4 x i32> zeroinitializer
+
+// OGCG: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
+
+vd2 b;
+// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<!cir.double x 2>
+
+// LLVM: @[[VEC_B:.*]] = dso_local global <2 x double> zeroinitialize
+
+// OGCG: @[[VEC_B:.*]] = global <2 x double> zeroinitializer
+
+vll2 c;
+// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<!s64i x 2>
+
+// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i64> zeroinitialize
+
+// OGCG: @[[VEC_C:.*]] = global <2 x i64> zeroinitializer
+
+void vec_int_test() {
+  vi4 a;
+  vd2 b;
+  vll2 c;
+}
+
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
+// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["b"]
+// CIR: %[[VEC_C:.*]] = cir.alloca !cir.vector<!s64i x 2>, !cir.ptr<!cir.vector<!s64i x 2>>, ["c"]
+
+// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
+// LLVM: %[[VEC_B:.*]] = alloca <2 x double>, i64 1, align 16
+// LLVM: %[[VEC_C:.*]] = alloca <2 x i64>, i64 1, align 16
+
+// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
+// OGCG: %[[VEC_B:.*]] = alloca <2 x double>, align 16
+// OGCG: %[[VEC_C:.*]] = alloca <2 x i64>, align 16
+
+void foo2(vi4 p) {}
+
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["p", init]
+// CIR: cir.store %{{.*}}, %[[VEC_A]] : !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>
+
+// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
+// LLVM: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16
+
+// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
+// OGCG: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16
diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp
new file mode 100644
index 0000000000000..762e502832f2d
--- /dev/null
+++ b/clang/test/CIR/CodeGen/vector.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+typedef int vi4 __attribute__((ext_vector_type(4)));
+typedef int vi3 __attribute__((ext_vector_type(3)));
+typedef int vi2 __attribute__((ext_vector_type(2)));
+typedef double vd2 __attribute__((ext_vector_type(2)));
+
+vi4 vec_a;
+// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<!s32i x 4>
+
+// LLVM: @[[VEC_A:.*]] = dso_local global <4 x i32> zeroinitializer
+
+// OGCG: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
+
+vi3 vec_b;
+// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<!s32i x 3>
+
+// LLVM: @[[VEC_B:.*]] = dso_local global <3 x i32> zeroinitializer
+
+// OGCG: @[[VEC_B:.*]] = global <3 x i32> zeroinitializer
+
+vi2 vec_c;
+// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<!s32i x 2>
+
+// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i32> zeroinitializer
+
+// OGCG: @[[VEC_C:.*]] = global <2 x i32> zeroinitializer
+
+vd2 d;
+
+// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<!cir.double x 2>
+
+// LLVM: @[[VEC_B:.*]] = dso_local global <2 x double> zeroinitialize
+
+// OGCG: @[[VEC_B:.*]] = global <2 x double> zeroinitializer
+
+void foo() {
+  vi4 a;
+  vi3 b;
+  vi2 c;
+  vd2 d;
+}
+
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
+// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<!s32i x 3>, !cir.ptr<!cir.vector<!s32i x 3>>, ["b"]
+// CIR: %[[VEC_C:.*]] = cir.alloca !cir.vector<!s32i x 2>, !cir.ptr<!cir.vector<!s32i x 2>>, ["c"]
+// CIR: %[[VEC_D:.*]] = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["d"]
+
+// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
+// LLVM: %[[VEC_B:.*]] = alloca <3 x i32>, i64 1, align 16
+// LLVM: %[[VEC_C:.*]] = alloca <2 x i32>, i64 1, align 8
+// LLVM: %[[VEC_D:.*]] = alloca <2 x double>, i64 1, align 16
+
+// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
+// OGCG: %[[VEC_B:.*]] = alloca <3 x i32>, align 16
+// OGCG: %[[VEC_C:.*]] = alloca <2 x i32>, align 8
+// OGCG: %[[VEC_D:.*]] = alloca <2 x double>, align 16
+
+void foo2(vi4 p) {}
+
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["p", init]
+// CIR: cir.store %{{.*}}, %[[VEC_A]] : !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>
+
+// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
+// LLVM: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16
+
+// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
+// OGCG: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16
diff --git a/clang/test/CIR/IR/vector.cir b/clang/test/CIR/IR/vector.cir
new file mode 100644
index 0000000000000..6eb0a269ad5ef
--- /dev/null
+++ b/clang/test/CIR/IR/vector.cir
@@ -0,0 +1,40 @@
+// RUN: cir-opt %s | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+
+module  {
+
+cir.global external @vec_a = #cir.zero : !cir.vector<!s32i x 4>
+// CHECK: cir.global external @vec_a = #cir.zero : !cir.vector<!s32i x 4>
+
+cir.global external @vec_b = #cir.zero : !cir.vector<!s32i x 3>
+// CHECK: cir.global external @vec_b = #cir.zero : !cir.vector<!s32i x 3>
+
+cir.global external @vec_c = #cir.zero : !cir.vector<!s32i x 2>
+// CHECK: cir.global external @vec_c = #cir.zero : !cir.vector<!s32i x 2>
+
+cir.func @vec_int_test() {
+  %0 = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
+  %1 = cir.alloca !cir.vector<!s32i x 3>, !cir.ptr<!cir.vector<!s32i x 3>>, ["b"]
+  %2 = cir.alloca !cir.vector<!s32i x 2>, !cir.ptr<!cir.vector<!s32i x 2>>, ["c"]
+  cir.return
+}
+
+// CHECK: cir.func @vec_int_test() {
+// CHECK:  %0 = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
+// CHECK:  %1 = cir.alloca !cir.vector<!s32i x 3>, !cir.ptr<!cir.vector<!s32i x 3>>, ["b"]
+// CHECK:  %2 = cir.alloca !cir.vector<!s32i x 2>, !cir.ptr<!cir.vector<!s32i x 2>>, ["c"]
+// CHECK:  cir.return
+// CHECK: }
+
+cir.func @vec_double_test() {
+  %0 = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["a"]
+  cir.return
+}
+
+// CHECK: cir.func @vec_double_test() {
+// CHECK:  %0 = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["a"]
+// CHECK:  cir.return
+// CHECK: }
+
+}

@AmrDeveloper AmrDeveloper force-pushed the cir_upstream_vector_type branch 2 times, most recently from 160d171 to 5d07a63 Compare April 20, 2025 13:47
Comment on lines 406 to 407
resultType = cir::VectorType::get(builder.getContext(), elemTy,
vec->getNumElements());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflect changes to builders:

Suggested change
resultType = cir::VectorType::get(builder.getContext(), elemTy,
vec->getNumElements());
resultType = cir::VectorType::get(elemTy, vec->getNumElements());

Comment on lines 319 to 320
`cir.vector' represents fixed-size vector types. The parameters are the
element type and the number of elements.
Copy link
Contributor

@xlauko xlauko Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`cir.vector' represents fixed-size vector types. The parameters are the
element type and the number of elements.
`!cir.vector' represents fixed-size vector types, parameterized
by the element type and the number of elements.
Example:
```mlir
!cir.vector<!u64i x 2>
!cir.vector<!cir.float x 4>
```

element type and the number of elements.
}];

let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CIR uses mix of eltType, elementTy. Can we standardize one? tbf, I would prefer third option elementType to mirror similar options in other dialects (llvm, builtin, tosa)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can agree on which one will be standardised and i will use it in this PR, and in the follow up PR I can update the other places to use that one

@xlauko @bcardosolopes @andykaylor

Copy link
Member

@bcardosolopes bcardosolopes Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since @xlauko is doing a lot of work on making things nice and consistent, I'm all in for his suggestions. Also probably worth encoding in https://llvm.github.io/clangir/Dialect/cir-style-guide.html so we can point people to it.

let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);

let assemblyFormat = [{
`<` $eltType `x` $size `>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: also to be more consistent with the rest of mlir, shaped types usually use format in reverse order shape x size (see llvm vector types and builtin tensors)

llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
mlir::Type eltType, uint64_t size) {
if (size == 0)
return emitError() << "the number of vector elements must be positive";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return emitError() << "the number of vector elements must be positive";
return emitError() << "the number of vector elements must be non-zero";

if (mlir::isa<cir::IntType>(eltType) || isAnyFloatingPointType(eltType))
return success();

eltType.dump();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be here?

element type and the number of elements.
}];

let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);
Copy link
Member

@bcardosolopes bcardosolopes Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since @xlauko is doing a lot of work on making things nice and consistent, I'm all in for his suggestions. Also probably worth encoding in https://llvm.github.io/clangir/Dialect/cir-style-guide.html so we can point people to it.

@@ -530,7 +567,7 @@ def CIRRecordType : Type<
//===----------------------------------------------------------------------===//

def CIR_AnyType : AnyTypeOf<[
CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_IntType, CIR_AnyFloat,
CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, CIR_AnyFloat,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please align this to 80-col


mlir::LogicalResult cir::VectorType::verify(
llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
mlir::Type eltType, uint64_t size) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this, note you also need to add tests for the invalid inputs!

@@ -82,6 +82,9 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
cir::IntType>(ty))
return true;

if (mlir::isa<cir::VectorType>(ty))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (mlir::isa<cir::VectorType>(ty))
if (auto vt = mlir::dyn_cast<cir::VectorType>(ty))

Then this would replace the mlir::cast in the statement below.

case Type::ExtVector:
case Type::Vector: {
const VectorType *vec = cast<VectorType>(ty);
const mlir::Type elemTy = convertTypeForMem(vec->getElementType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure convertTypeForMem is what we want here. Specifically, I don't think we want a vector of bools to end up as a vector of i8. I tried this with the incubator, but it seems vectors of bool are not yet implemented there.


// Check if it a valid VectorType
if (mlir::isa<cir::IntType>(elementType) ||
isAnyFloatingPointType(elementType))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this check in mlir::LLVM::isCompatibleVectorType():

    if (auto intType = llvm::dyn_cast<IntegerType>(elementType))
      return intType.isSignless();
    return llvm::isa<BFloat16Type, Float16Type, Float32Type, Float64Type,
                     Float80Type, Float128Type>(elementType);

So that's not necessarily compatible with isAnyFloatingPointType to match the error message below. I don't know if we want to form an LLVM type here and call that function directly, but it seems like we otherwise run the risk of this getting out of sync.

On the other hand, I'd like to be able to create CIR vectors of other types like float8 without requiring that the LLVM dialect support them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmmmmm maybe we should put our checks like it isa (Int, Index, Ptr, Float) 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if we want to form an LLVM type here and call that function directly, but it seems like we otherwise run the risk of this getting out of sync.

My suggestion is to stay out of using LLVM dialect directly besides lowering, my reasons include:

  • LLVM dialect changes frequently, and since CIR doesn't yet build by default, it's a maintenance burden for us (while in this phase).
  • Staying out of sync could be a good thing here since it forces us to write tests for what we support.
  • The thing you mentioned about being able to support other things not necessarily LLVM related.

isAnyFloatingPointType(elementType))
return success();

return emitError() << "expected LLVM-compatible fixed-vector type "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message seems wrong, but I'm not sure what it should say. We're expecting a vector of a CIR type, right? Maybe this should say, "unsupported element type for CIR vector"?

@AmrDeveloper AmrDeveloper force-pushed the cir_upstream_vector_type branch from 1f11895 to 78309ef Compare April 22, 2025 17:56
@AmrDeveloper AmrDeveloper force-pushed the cir_upstream_vector_type branch from 78309ef to 4976855 Compare April 24, 2025 17:20
Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me if @xlauko is satisfied with the new changes.

Copy link
Contributor

@xlauko xlauko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@AmrDeveloper AmrDeveloper merged commit d591630 into llvm:main Apr 26, 2025
11 checks passed
jyli0116 pushed a commit to jyli0116/llvm-project that referenced this pull request Apr 28, 2025
This change adds the initial support for VectorType

Issue llvm#136487
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
This change adds the initial support for VectorType

Issue llvm#136487
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
This change adds the initial support for VectorType

Issue llvm#136487
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
This change adds the initial support for VectorType

Issue llvm#136487
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
This change adds the initial support for VectorType

Issue llvm#136487
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants