[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 21 11:22:52 PDT 2025
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/136488
>From 5d07a639dc6c933f6f171e501e4ec20d731553e3 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Sat, 19 Apr 2025 21:03:07 +0200
Subject: [PATCH 1/4] [CIR] Upstream initial support for fixed size VectorType
---
.../CIR/Dialect/Builder/CIRBaseBuilder.h | 2 +
.../include/clang/CIR/Dialect/IR/CIRTypes.td | 22 +++++-
clang/lib/CIR/CodeGen/CIRGenBuilder.h | 3 +
clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 9 +++
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 2 +-
clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 19 ++++-
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 5 ++
clang/test/CIR/CodeGen/vector-ext.cpp | 73 +++++++++++++++++++
clang/test/CIR/CodeGen/vector.cpp | 60 +++++++++++++++
clang/test/CIR/IR/vector.cir | 40 ++++++++++
10 files changed, 232 insertions(+), 3 deletions(-)
create mode 100644 clang/test/CIR/CodeGen/vector-ext.cpp
create mode 100644 clang/test/CIR/CodeGen/vector.cpp
create mode 100644 clang/test/CIR/IR/vector.cir
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..9c3fdb0b9c31b
--- /dev/null
+++ b/clang/test/CIR/CodeGen/vector-ext.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_D:.*]] = #cir.zero : !cir.vector<!cir.double x 2>
+
+// LLVM: @[[VEC_D:.*]] = dso_local global <2 x double> zeroinitialize
+
+// OGCG: @[[VEC_D:.*]] = 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/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp
new file mode 100644
index 0000000000000..155a00667e9b9
--- /dev/null
+++ b/clang/test/CIR/CodeGen/vector.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/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: }
+
+}
>From a7834c7060c40b5f50d2970fc31395a62ad43581 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Mon, 21 Apr 2025 13:13:19 +0200
Subject: [PATCH 2/4] Address code review comment
---
.../include/clang/CIR/Dialect/IR/CIRTypes.td | 23 +++++++++++++--
clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 3 +-
clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 19 +++++++++++++
clang/test/CIR/CodeGen/vector-ext.cpp | 20 ++++++-------
clang/test/CIR/CodeGen/vector.cpp | 16 +++++------
clang/test/CIR/IR/vector.cir | 28 +++++++++----------
6 files changed, 72 insertions(+), 37 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 8fb46cea618a3..e85f98c23613a 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -316,15 +316,32 @@ def CIR_VectorType : CIR_Type<"Vector", "vector",
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.
+ `!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>
+ ```
}];
let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);
let assemblyFormat = [{
- `<` $eltType `x` $size `>`
+ `<` $size `x` $eltType `>`
}];
+
+ let builders = [
+ TypeBuilderWithInferredContext<(ins
+ "mlir::Type":$eltType, "uint64_t":$size
+ ), [{
+ return $_get(eltType.getContext(), eltType, size);
+ }]>,
+ ];
+
+ let genVerifyDecl = 1;
}
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 01e8f3576fbe3..fb5434123ca6b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -403,8 +403,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
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());
+ resultType = cir::VectorType::get(elemTy, vec->getNumElements());
break;
}
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index f4ec524b65129..f085c33c3d78d 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -654,6 +654,25 @@ cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*this));
}
+mlir::LogicalResult cir::VectorType::verify(
+ 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";
+
+ // Check if it a valid FixedVectorType
+ if (mlir::isa<cir::PointerType, cir::FP128Type>(eltType))
+ return success();
+
+ // Check if it a valid VectorType
+ if (mlir::isa<cir::IntType>(eltType) || isAnyFloatingPointType(eltType))
+ return success();
+
+ eltType.dump();
+ return emitError() << "expected LLVM-compatible fixed-vector type "
+ "to be either builtin or LLVM dialect type";
+}
+
//===----------------------------------------------------------------------===//
// PointerType Definitions
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp
index 9c3fdb0b9c31b..13726edf3d259 100644
--- a/clang/test/CIR/CodeGen/vector-ext.cpp
+++ b/clang/test/CIR/CodeGen/vector-ext.cpp
@@ -11,21 +11,21 @@ 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>
+// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<4 x !s32i>
// 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>
+// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<3 x !s32i>
// 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>
+// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<2 x !s32i>
// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i32> zeroinitializer
@@ -33,7 +33,7 @@ vi2 vec_c;
vd2 d;
-// CIR: cir.global external @[[VEC_D:.*]] = #cir.zero : !cir.vector<!cir.double x 2>
+// CIR: cir.global external @[[VEC_D:.*]] = #cir.zero : !cir.vector<2 x !cir.double>
// LLVM: @[[VEC_D:.*]] = dso_local global <2 x double> zeroinitialize
@@ -46,10 +46,10 @@ void foo() {
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"]
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
+// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<3 x !s32i>, !cir.ptr<!cir.vector<3 x !s32i>>, ["b"]
+// CIR: %[[VEC_C:.*]] = cir.alloca !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>, ["c"]
+// CIR: %[[VEC_D:.*]] = cir.alloca !cir.vector<2 x !cir.double>, !cir.ptr<!cir.vector<2 x !cir.double>>, ["d"]
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
// LLVM: %[[VEC_B:.*]] = alloca <3 x i32>, i64 1, align 16
@@ -63,8 +63,8 @@ void foo() {
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>>
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["p", init]
+// CIR: cir.store %{{.*}}, %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
// LLVM: 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
index 155a00667e9b9..8f9e98fb6b3c0 100644
--- a/clang/test/CIR/CodeGen/vector.cpp
+++ b/clang/test/CIR/CodeGen/vector.cpp
@@ -10,21 +10,21 @@ 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>
+// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<4 x !s32i>
// 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>
+// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<2 x !cir.double>
// 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>
+// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<2 x !s64i>
// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i64> zeroinitialize
@@ -36,9 +36,9 @@ void vec_int_test() {
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"]
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
+// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<2 x !cir.double>, !cir.ptr<!cir.vector<2 x !cir.double>>, ["b"]
+// CIR: %[[VEC_C:.*]] = cir.alloca !cir.vector<2 x !s64i>, !cir.ptr<!cir.vector<2 x !s64i>>, ["c"]
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
// LLVM: %[[VEC_B:.*]] = alloca <2 x double>, i64 1, align 16
@@ -50,8 +50,8 @@ void vec_int_test() {
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>>
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["p", init]
+// CIR: cir.store %{{.*}}, %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
// LLVM: 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
index 6eb0a269ad5ef..74ddf7691e7d4 100644
--- a/clang/test/CIR/IR/vector.cir
+++ b/clang/test/CIR/IR/vector.cir
@@ -4,36 +4,36 @@
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_a = #cir.zero : !cir.vector<4 x !s32i>
+// CHECK: cir.global external @vec_a = #cir.zero : !cir.vector<4 x !s32i>
-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_b = #cir.zero : !cir.vector<3 x !s32i>
+// CHECK: cir.global external @vec_b = #cir.zero : !cir.vector<3 x !s32i>
-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.global external @vec_c = #cir.zero : !cir.vector<2 x !s32i>
+// CHECK: cir.global external @vec_c = #cir.zero : !cir.vector<2 x !s32i>
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"]
+ %0 = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
+ %1 = cir.alloca !cir.vector<3 x !s32i>, !cir.ptr<!cir.vector<3 x !s32i>>, ["b"]
+ %2 = cir.alloca !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>, ["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: %0 = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
+// CHECK: %1 = cir.alloca !cir.vector<3 x !s32i>, !cir.ptr<!cir.vector<3 x !s32i>>, ["b"]
+// CHECK: %2 = cir.alloca !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>, ["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"]
+ %0 = cir.alloca !cir.vector<2 x !cir.double>, !cir.ptr<!cir.vector<2 x !cir.double>>, ["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: %0 = cir.alloca !cir.vector<2 x !cir.double>, !cir.ptr<!cir.vector<2 x !cir.double>>, ["a"]
// CHECK: cir.return
// CHECK: }
>From 035b1ef728541742da24c0c09f6a9085579247de Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Mon, 21 Apr 2025 16:13:37 +0200
Subject: [PATCH 3/4] Address code review comment
---
clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index f085c33c3d78d..e58eeefa8ece0 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -658,7 +658,7 @@ mlir::LogicalResult cir::VectorType::verify(
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";
+ return emitError() << "the number of vector elements must be non-zero";
// Check if it a valid FixedVectorType
if (mlir::isa<cir::PointerType, cir::FP128Type>(eltType))
@@ -668,7 +668,6 @@ mlir::LogicalResult cir::VectorType::verify(
if (mlir::isa<cir::IntType>(eltType) || isAnyFloatingPointType(eltType))
return success();
- eltType.dump();
return emitError() << "expected LLVM-compatible fixed-vector type "
"to be either builtin or LLVM dialect type";
}
>From c1ef82d0c46d1a6ea61301e0ce19585d1911f9e7 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Mon, 21 Apr 2025 20:22:25 +0200
Subject: [PATCH 4/4] Align to 80 col
---
clang/include/clang/CIR/Dialect/IR/CIRTypes.td | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index e85f98c23613a..acf32f9d2b5d4 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -567,8 +567,8 @@ def CIRRecordType : Type<
//===----------------------------------------------------------------------===//
def CIR_AnyType : AnyTypeOf<[
- CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, CIR_AnyFloat,
- CIR_PointerType, CIR_FuncType, CIR_RecordType
+ CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType,
+ CIR_AnyFloat, CIR_PointerType, CIR_FuncType, CIR_RecordType
]>;
#endif // MLIR_CIR_DIALECT_CIR_TYPES
More information about the cfe-commits
mailing list