Skip to content

Commit 160d171

Browse files
committed
[CIR] Upstream initial support for fixed size VectorType
1 parent 19c708c commit 160d171

File tree

10 files changed

+232
-3
lines changed

10 files changed

+232
-3
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
9393
return cir::FPAttr::getZero(ty);
9494
if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
9595
return getZeroAttr(arrTy);
96+
if (auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
97+
return getZeroAttr(vecTy);
9698
if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
9799
return getConstNullPtrAttr(ptrTy);
98100
if (auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array",
307307
}];
308308
}
309309

310+
//===----------------------------------------------------------------------===//
311+
// VectorType (fixed size)
312+
//===----------------------------------------------------------------------===//
313+
314+
def CIR_VectorType : CIR_Type<"Vector", "vector",
315+
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
316+
317+
let summary = "CIR vector type";
318+
let description = [{
319+
`cir.vector' represents fixed-size vector types. The parameters are the
320+
element type and the number of elements.
321+
}];
322+
323+
let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);
324+
325+
let assemblyFormat = [{
326+
`<` $eltType `x` $size `>`
327+
}];
328+
}
329+
310330
//===----------------------------------------------------------------------===//
311331
// FuncType
312332
//===----------------------------------------------------------------------===//
@@ -530,7 +550,7 @@ def CIRRecordType : Type<
530550
//===----------------------------------------------------------------------===//
531551

532552
def CIR_AnyType : AnyTypeOf<[
533-
CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_IntType, CIR_AnyFloat,
553+
CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, CIR_AnyFloat,
534554
CIR_PointerType, CIR_FuncType, CIR_RecordType
535555
]>;
536556

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
8282
cir::IntType>(ty))
8383
return true;
8484

85+
if (mlir::isa<cir::VectorType>(ty))
86+
return isSized(mlir::cast<cir::VectorType>(ty).getEltType());
87+
8588
assert(!cir::MissingFeatures::unsizedTypes());
8689
return false;
8790
}

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,15 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
399399
break;
400400
}
401401

402+
case Type::ExtVector:
403+
case Type::Vector: {
404+
const VectorType *vec = cast<VectorType>(ty);
405+
const mlir::Type elemTy = convertTypeForMem(vec->getElementType());
406+
resultType = cir::VectorType::get(builder.getContext(), elemTy,
407+
vec->getNumElements());
408+
break;
409+
}
410+
402411
case Type::FunctionNoProto:
403412
case Type::FunctionProto:
404413
resultType = convertFunctionTypeInternal(type);

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
212212
}
213213

214214
if (isa<cir::ZeroAttr>(attrType)) {
215-
if (isa<cir::RecordType, cir::ArrayType>(opType))
215+
if (isa<cir::RecordType, cir::ArrayType, cir::VectorType>(opType))
216216
return success();
217217
return op->emitOpError("zero expects struct or array type");
218218
}

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
622622
}
623623

624624
//===----------------------------------------------------------------------===//
625-
// Definitions
625+
// ArrayType Definitions
626626
//===----------------------------------------------------------------------===//
627627

628628
llvm::TypeSize
@@ -637,6 +637,23 @@ ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
637637
return dataLayout.getTypeABIAlignment(getEltType());
638638
}
639639

640+
//===----------------------------------------------------------------------===//
641+
// VectorType Definitions
642+
//===----------------------------------------------------------------------===//
643+
644+
llvm::TypeSize cir::VectorType::getTypeSizeInBits(
645+
const ::mlir::DataLayout &dataLayout,
646+
::mlir::DataLayoutEntryListRef params) const {
647+
return llvm::TypeSize::getFixed(getSize() *
648+
dataLayout.getTypeSizeInBits(getEltType()));
649+
}
650+
651+
uint64_t
652+
cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
653+
::mlir::DataLayoutEntryListRef params) const {
654+
return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*this));
655+
}
656+
640657
//===----------------------------------------------------------------------===//
641658
// PointerType Definitions
642659
//===----------------------------------------------------------------------===//

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "mlir/Dialect/DLTI/DLTI.h"
2020
#include "mlir/Dialect/Func/IR/FuncOps.h"
2121
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
22+
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
2223
#include "mlir/IR/BuiltinDialect.h"
2324
#include "mlir/IR/BuiltinOps.h"
2425
#include "mlir/IR/Types.h"
@@ -1308,6 +1309,10 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
13081309
convertTypeForMemory(converter, dataLayout, type.getEltType());
13091310
return mlir::LLVM::LLVMArrayType::get(ty, type.getSize());
13101311
});
1312+
converter.addConversion([&](cir::VectorType type) -> mlir::Type {
1313+
const mlir::Type ty = converter.convertType(type.getEltType());
1314+
return mlir::VectorType::get(type.getSize(), ty);
1315+
});
13111316
converter.addConversion([&](cir::BoolType type) -> mlir::Type {
13121317
return mlir::IntegerType::get(type.getContext(), 1,
13131318
mlir::IntegerType::Signless);

clang/test/CIR/CodeGen/vector-ext.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
typedef int vi4 __attribute__((ext_vector_type(4)));
9+
typedef int vi3 __attribute__((ext_vector_type(3)));
10+
typedef int vi2 __attribute__((ext_vector_type(2)));
11+
typedef double vd2 __attribute__((ext_vector_type(2)));
12+
13+
vi4 vec_a;
14+
// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<!s32i x 4>
15+
16+
// LLVM: @[[VEC_A:.*]] = dso_local global <4 x i32> zeroinitializer
17+
18+
// OGCG: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
19+
20+
vi3 vec_b;
21+
// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<!s32i x 3>
22+
23+
// LLVM: @[[VEC_B:.*]] = dso_local global <3 x i32> zeroinitializer
24+
25+
// OGCG: @[[VEC_B:.*]] = global <3 x i32> zeroinitializer
26+
27+
vi2 vec_c;
28+
// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<!s32i x 2>
29+
30+
// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i32> zeroinitializer
31+
32+
// OGCG: @[[VEC_C:.*]] = global <2 x i32> zeroinitializer
33+
34+
vd2 d;
35+
36+
// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<!cir.double x 2>
37+
38+
// LLVM: @[[VEC_B:.*]] = dso_local global <2 x double> zeroinitialize
39+
40+
// OGCG: @[[VEC_B:.*]] = global <2 x double> zeroinitializer
41+
42+
void foo() {
43+
vi4 a;
44+
vi3 b;
45+
vi2 c;
46+
vd2 d;
47+
}
48+
49+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
50+
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<!s32i x 3>, !cir.ptr<!cir.vector<!s32i x 3>>, ["b"]
51+
// CIR: %[[VEC_C:.*]] = cir.alloca !cir.vector<!s32i x 2>, !cir.ptr<!cir.vector<!s32i x 2>>, ["c"]
52+
// CIR: %[[VEC_D:.*]] = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["d"]
53+
54+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
55+
// LLVM: %[[VEC_B:.*]] = alloca <3 x i32>, i64 1, align 16
56+
// LLVM: %[[VEC_C:.*]] = alloca <2 x i32>, i64 1, align 8
57+
// LLVM: %[[VEC_D:.*]] = alloca <2 x double>, i64 1, align 16
58+
59+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
60+
// OGCG: %[[VEC_B:.*]] = alloca <3 x i32>, align 16
61+
// OGCG: %[[VEC_C:.*]] = alloca <2 x i32>, align 8
62+
// OGCG: %[[VEC_D:.*]] = alloca <2 x double>, align 16
63+
64+
void foo2(vi4 p) {}
65+
66+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["p", init]
67+
// CIR: cir.store %{{.*}}, %[[VEC_A]] : !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>
68+
69+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
70+
// LLVM: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16
71+
72+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
73+
// OGCG: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16

clang/test/CIR/CodeGen/vector.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
typedef int vi4 __attribute__((vector_size(16)));
9+
typedef double vd2 __attribute__((vector_size(16)));
10+
typedef long long vll2 __attribute__((vector_size(16)));
11+
12+
vi4 vec_a;
13+
// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<!s32i x 4>
14+
15+
// LLVM: @[[VEC_A:.*]] = dso_local global <4 x i32> zeroinitializer
16+
17+
// OGCG: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
18+
19+
vd2 b;
20+
// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<!cir.double x 2>
21+
22+
// LLVM: @[[VEC_B:.*]] = dso_local global <2 x double> zeroinitialize
23+
24+
// OGCG: @[[VEC_B:.*]] = global <2 x double> zeroinitializer
25+
26+
vll2 c;
27+
// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<!s64i x 2>
28+
29+
// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i64> zeroinitialize
30+
31+
// OGCG: @[[VEC_C:.*]] = global <2 x i64> zeroinitializer
32+
33+
void vec_int_test() {
34+
vi4 a;
35+
vd2 b;
36+
vll2 c;
37+
}
38+
39+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
40+
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["b"]
41+
// CIR: %[[VEC_C:.*]] = cir.alloca !cir.vector<!s64i x 2>, !cir.ptr<!cir.vector<!s64i x 2>>, ["c"]
42+
43+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
44+
// LLVM: %[[VEC_B:.*]] = alloca <2 x double>, i64 1, align 16
45+
// LLVM: %[[VEC_C:.*]] = alloca <2 x i64>, i64 1, align 16
46+
47+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
48+
// OGCG: %[[VEC_B:.*]] = alloca <2 x double>, align 16
49+
// OGCG: %[[VEC_C:.*]] = alloca <2 x i64>, align 16
50+
51+
void foo2(vi4 p) {}
52+
53+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["p", init]
54+
// CIR: cir.store %{{.*}}, %[[VEC_A]] : !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>
55+
56+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
57+
// LLVM: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16
58+
59+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
60+
// OGCG: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16

clang/test/CIR/IR/vector.cir

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: cir-opt %s | FileCheck %s
2+
3+
!s32i = !cir.int<s, 32>
4+
5+
module {
6+
7+
cir.global external @vec_a = #cir.zero : !cir.vector<!s32i x 4>
8+
// CHECK: cir.global external @vec_a = #cir.zero : !cir.vector<!s32i x 4>
9+
10+
cir.global external @vec_b = #cir.zero : !cir.vector<!s32i x 3>
11+
// CHECK: cir.global external @vec_b = #cir.zero : !cir.vector<!s32i x 3>
12+
13+
cir.global external @vec_c = #cir.zero : !cir.vector<!s32i x 2>
14+
// CHECK: cir.global external @vec_c = #cir.zero : !cir.vector<!s32i x 2>
15+
16+
cir.func @vec_int_test() {
17+
%0 = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
18+
%1 = cir.alloca !cir.vector<!s32i x 3>, !cir.ptr<!cir.vector<!s32i x 3>>, ["b"]
19+
%2 = cir.alloca !cir.vector<!s32i x 2>, !cir.ptr<!cir.vector<!s32i x 2>>, ["c"]
20+
cir.return
21+
}
22+
23+
// CHECK: cir.func @vec_int_test() {
24+
// CHECK: %0 = cir.alloca !cir.vector<!s32i x 4>, !cir.ptr<!cir.vector<!s32i x 4>>, ["a"]
25+
// CHECK: %1 = cir.alloca !cir.vector<!s32i x 3>, !cir.ptr<!cir.vector<!s32i x 3>>, ["b"]
26+
// CHECK: %2 = cir.alloca !cir.vector<!s32i x 2>, !cir.ptr<!cir.vector<!s32i x 2>>, ["c"]
27+
// CHECK: cir.return
28+
// CHECK: }
29+
30+
cir.func @vec_double_test() {
31+
%0 = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["a"]
32+
cir.return
33+
}
34+
35+
// CHECK: cir.func @vec_double_test() {
36+
// CHECK: %0 = cir.alloca !cir.vector<!cir.double x 2>, !cir.ptr<!cir.vector<!cir.double x 2>>, ["a"]
37+
// CHECK: cir.return
38+
// CHECK: }
39+
40+
}

0 commit comments

Comments
 (0)