-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
[CIR] Upstream initial support for fixed size VectorType #136488
Conversation
@llvm/pr-subscribers-clangir @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesThis change adds the initial support for VectorType Issue #136487 Full diff: https://github.com/llvm/llvm-project/pull/136488.diff 10 Files Affected:
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: }
+
+}
|
160d171
to
5d07a63
Compare
resultType = cir::VectorType::get(builder.getContext(), elemTy, | ||
vec->getNumElements()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reflect changes to builders:
resultType = cir::VectorType::get(builder.getContext(), elemTy, | |
vec->getNumElements()); | |
resultType = cir::VectorType::get(elemTy, vec->getNumElements()); |
`cir.vector' represents fixed-size vector types. The parameters are the | ||
element type and the number of elements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`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); |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 `>` |
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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(); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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()); |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) 🤔
There was a problem hiding this comment.
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 " |
There was a problem hiding this comment.
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"?
1f11895
to
78309ef
Compare
78309ef
to
4976855
Compare
There was a problem hiding this 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This change adds the initial support for VectorType Issue llvm#136487
This change adds the initial support for VectorType Issue llvm#136487
This change adds the initial support for VectorType Issue llvm#136487
This change adds the initial support for VectorType Issue llvm#136487
This change adds the initial support for VectorType Issue llvm#136487
This change adds the initial support for VectorType
Issue #136487