Skip to content

[CIR] Introduce type aliases for records #136387

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 3 commits into from
Apr 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ struct CIROpAsmDialectInterface : public OpAsmDialectInterface {
using OpAsmDialectInterface::OpAsmDialectInterface;

AliasResult getAlias(Type type, raw_ostream &os) const final {
if (auto recordType = dyn_cast<cir::RecordType>(type)) {
StringAttr nameAttr = recordType.getName();
if (!nameAttr)
os << "rec_anon_" << recordType.getKindAsStr();
else
os << "rec_" << nameAttr.getValue();
return AliasResult::OverridableAlias;
}
if (auto intType = dyn_cast<cir::IntType>(type)) {
// We only provide alias for standard integer types (i.e. integer types
// whose width is a power of 2 and at least 8).
Expand Down
47 changes: 22 additions & 25 deletions clang/test/CIR/CodeGen/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

// For LLVM IR checks, the structs are defined before the variables, so these
// checks are at the top.
// CIR-DAG: !rec_IncompleteS = !cir.record<struct "IncompleteS" incomplete>
// CIR-DAG: !rec_CompleteS = !cir.record<struct "CompleteS" {!s32i, !s8i}>
// CIR-DAG: !rec_OuterS = !cir.record<struct "OuterS" {!rec_InnerS, !s32i}>
// CIR-DAG: !rec_InnerS = !cir.record<struct "InnerS" {!s32i, !s8i}>
// CIR-DAG: !rec_PackedS = !cir.record<struct "PackedS" packed {!s32i, !s8i}>
// CIR-DAG: !rec_PackedAndPaddedS = !cir.record<struct "PackedAndPaddedS" packed padded {!s32i, !s8i, !u8i}>
// LLVM-DAG: %struct.CompleteS = type { i32, i8 }
// LLVM-DAG: %struct.OuterS = type { %struct.InnerS, i32 }
// LLVM-DAG: %struct.InnerS = type { i32, i8 }
Expand All @@ -20,8 +26,7 @@

struct IncompleteS *p;

// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!cir.record<struct
// CIR-SAME: "IncompleteS" incomplete>>
// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteS>
// LLVM-DAG: @p = dso_local global ptr null
// OGCG-DAG: @p = global ptr null, align 8

Expand All @@ -30,10 +35,9 @@ struct CompleteS {
char b;
} cs;

// CIR: cir.global external @cs = #cir.zero : !cir.record<struct
// CIR-SAME: "CompleteS" {!s32i, !s8i}>
// LLVM-DAG: @cs = dso_local global %struct.CompleteS zeroinitializer
// OGCG-DAG: @cs = global %struct.CompleteS zeroinitializer, align 4
// CIR: cir.global external @cs = #cir.zero : !rec_CompleteS
// LLVM-DAG: @cs = dso_local global %struct.CompleteS zeroinitializer
// OGCG-DAG: @cs = global %struct.CompleteS zeroinitializer, align 4

struct InnerS {
int a;
Expand All @@ -47,10 +51,9 @@ struct OuterS {

struct OuterS os;

// CIR: cir.global external @os = #cir.zero : !cir.record<struct
// CIR-SAME: "OuterS" {!cir.record<struct "InnerS" {!s32i, !s8i}>, !s32i}>
// LLVM-DAG: @os = dso_local global %struct.OuterS zeroinitializer
// OGCG-DAG: @os = global %struct.OuterS zeroinitializer, align 4
// CIR: cir.global external @os = #cir.zero : !rec_OuterS
// LLVM-DAG: @os = dso_local global %struct.OuterS zeroinitializer
// OGCG-DAG: @os = global %struct.OuterS zeroinitializer, align 4

#pragma pack(push)
#pragma pack(1)
Expand All @@ -60,20 +63,18 @@ struct PackedS {
char a1;
} ps;

// CIR: cir.global external @ps = #cir.zero : !cir.record<struct "PackedS"
// CIR-SAME: packed {!s32i, !s8i}>
// LLVM-DAG: @ps = dso_local global %struct.PackedS zeroinitializer
// OGCG-DAG: @ps = global %struct.PackedS zeroinitializer, align 1
// CIR: cir.global external @ps = #cir.zero : !rec_PackedS
// LLVM-DAG: @ps = dso_local global %struct.PackedS zeroinitializer
// OGCG-DAG: @ps = global %struct.PackedS zeroinitializer, align 1

struct PackedAndPaddedS {
int b0;
char b1;
} __attribute__((aligned(2))) pps;

// CIR: cir.global external @pps = #cir.zero : !cir.record<struct
// CIR-SAME: "PackedAndPaddedS" packed padded {!s32i, !s8i, !u8i}>
// LLVM-DAG: @pps = dso_local global %struct.PackedAndPaddedS zeroinitializer
// OGCG-DAG: @pps = global %struct.PackedAndPaddedS zeroinitializer, align 2
// CIR: cir.global external @pps = #cir.zero : !rec_PackedAndPaddedS
// LLVM-DAG: @pps = dso_local global %struct.PackedAndPaddedS zeroinitializer
// OGCG-DAG: @pps = global %struct.PackedAndPaddedS zeroinitializer, align 2

#pragma pack(pop)

Expand All @@ -82,9 +83,7 @@ void f(void) {
}

// CIR: cir.func @f()
// CIR-NEXT: cir.alloca !cir.ptr<!cir.record<struct "IncompleteS" incomplete>>,
// CIR-SAME: !cir.ptr<!cir.ptr<!cir.record<struct
// CIR-SAME: "IncompleteS" incomplete>>>, ["p"]
// CIR-NEXT: cir.alloca !cir.ptr<!rec_IncompleteS>, !cir.ptr<!cir.ptr<!rec_IncompleteS>>, ["p"] {alignment = 8 : i64}
// CIR-NEXT: cir.return

// LLVM: define void @f()
Expand All @@ -101,9 +100,7 @@ void f2(void) {
}

// CIR: cir.func @f2()
// CIR-NEXT: cir.alloca !cir.record<struct "CompleteS" {!s32i, !s8i}>,
// CIR-SAME: !cir.ptr<!cir.record<struct "CompleteS" {!s32i, !s8i}>>,
// CIR-SAME: ["s"] {alignment = 4 : i64}
// CIR-NEXT: cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["s"] {alignment = 4 : i64}
// CIR-NEXT: cir.return

// LLVM: define void @f2()
Expand Down Expand Up @@ -160,7 +157,7 @@ char f4(int a, struct CompleteS *p) {
return p->b;
}

// CIR: cir.func @f4(%[[ARG_A:.*]]: !s32i {{.*}}, %[[ARG_P:.*]]: !cir.ptr<!cir.record<struct "CompleteS" {!s32i, !s8i}>>
// CIR: cir.func @f4(%[[ARG_A:.*]]: !s32i {{.*}}, %[[ARG_P:.*]]: !cir.ptr<!rec_CompleteS>
// CIR-NEXT: %[[A_ADDR:.*]] = cir.alloca {{.*}} ["a", init] {alignment = 4 : i64}
// CIR-NEXT: %[[P_ADDR:.*]] = cir.alloca {{.*}} ["p", init] {alignment = 8 : i64}
// CIR-NEXT: %[[RETVAL_ADDR:.*]] = cir.alloca {{.*}} ["__retval"] {alignment = 1 : i64}
Expand Down
5 changes: 2 additions & 3 deletions clang/test/CIR/CodeGen/struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
struct IncompleteS;
IncompleteS *p;

// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!cir.record<struct "IncompleteS" incomplete>>
// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteS>
// LLVM: @p = dso_local global ptr null
// OGCG: @p = global ptr null, align 8

Expand All @@ -17,8 +17,7 @@ void f(void) {
}

// CIR: cir.func @f()
// CIR-NEXT: cir.alloca !cir.ptr<!cir.record<struct "IncompleteS" incomplete>>,
// CIR-SAME: !cir.ptr<!cir.ptr<!cir.record<struct "IncompleteS" incomplete>>>, ["p"]
// CIR-NEXT: cir.alloca !cir.ptr<!rec_IncompleteS>, !cir.ptr<!cir.ptr<!rec_IncompleteS>>, ["p"]
// CIR-NEXT: cir.return

// LLVM: define void @f()
Expand Down
4 changes: 1 addition & 3 deletions clang/test/CIR/CodeGen/typedef.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ void local_typedef(void) {
}

// CIR: cir.func @local_typedef()
// CIR: cir.alloca !cir.record<struct "Struct" {!s32i}>,
// CIR-SAME: !cir.ptr<!cir.record<struct "Struct" {!s32i}>>, ["s"]
// CIR-SAME: {alignment = 4 : i64}
// CIR: cir.alloca !rec_Struct, !cir.ptr<!rec_Struct>, ["s"] {alignment = 4 : i64}
// CIR: cir.return

// LLVM: %struct.Struct = type { i32 }
Expand Down
5 changes: 2 additions & 3 deletions clang/test/CIR/CodeGen/union.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

union IncompleteU *p;

// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!cir.record<union "IncompleteU" incomplete>>
// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteU>
// LLVM: @p = dso_local global ptr null
// OGCG: @p = global ptr null, align 8

Expand All @@ -16,8 +16,7 @@ void f(void) {
}

// CIR: cir.func @f()
// CIR-NEXT: cir.alloca !cir.ptr<!cir.record<union "IncompleteU" incomplete>>,
// CIR-SAME: !cir.ptr<!cir.ptr<!cir.record<union "IncompleteU" incomplete>>>, ["p"]
// CIR-NEXT: cir.alloca !cir.ptr<!rec_IncompleteU>, !cir.ptr<!cir.ptr<!rec_IncompleteU>>, ["p"]
// CIR-NEXT: cir.return

// LLVM: define void @f()
Expand Down
14 changes: 10 additions & 4 deletions clang/test/CIR/IR/struct.cir
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// RUN: cir-opt %s | FileCheck %s

!rec_S = !cir.record<struct "S" incomplete>
!rec_U = !cir.record<union "U" incomplete>

// CHECK: !rec_S = !cir.record<struct "S" incomplete>
// CHECK: !rec_U = !cir.record<union "U" incomplete>

module {
cir.global external @p1 = #cir.ptr<null> : !cir.ptr<!cir.record<struct "S" incomplete>>
cir.global external @p2 = #cir.ptr<null> : !cir.ptr<!cir.record<union "U" incomplete>>
cir.global external @p1 = #cir.ptr<null> : !cir.ptr<!rec_S>
cir.global external @p2 = #cir.ptr<null> : !cir.ptr<!rec_U>
}

// CHECK: cir.global external @p1 = #cir.ptr<null> : !cir.ptr<!cir.record<struct "S" incomplete>>
// CHECK: cir.global external @p2 = #cir.ptr<null> : !cir.ptr<!cir.record<union "U" incomplete>>
// CHECK: cir.global external @p1 = #cir.ptr<null> : !cir.ptr<!rec_S>
// CHECK: cir.global external @p2 = #cir.ptr<null> : !cir.ptr<!rec_U>
Loading