Skip to content

Commit 4e40ed6

Browse files
committed
[CIR][CodeGen] Removed special handling for array of union
Special handling for array of union was forcing all non-union C arrays to be emitted as CIR arrays, which differs from OG CodeGen, where some arrays are emitted as structs.
1 parent aeac352 commit 4e40ed6

File tree

3 files changed

+17
-72
lines changed

3 files changed

+17
-72
lines changed

clang/lib/CIR/CodeGen/CIRGenExprConst.cpp

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,48 +1106,6 @@ class ConstExprEmitter
11061106
}
11071107

11081108
auto desiredType = CGM.convertType(T);
1109-
// FIXME(cir): A hack to handle the emission of arrays of unions directly.
1110-
// See clang/test/CIR/CodeGen/union-array.c and
1111-
// clang/test/CIR/Lowering/nested-union-array.c for example. The root
1112-
// cause of these problems is CIR handles union differently than LLVM IR.
1113-
// So we can't fix the problem fundamentally by mocking LLVM's handling for
1114-
// unions. In LLVM, the union is basically a struct with the largest member
1115-
// of the union and consumers cast the union arbitrarily according to their
1116-
// needs. But in CIR, we tried to express union semantics properly. This is
1117-
// a fundamental difference.
1118-
//
1119-
// Concretely, for the problem here, if we're constructing the initializer
1120-
// for the array of unions, we can't even assume the type of the elements in
1121-
// the initializer are the same! It is odd that we can have an array with
1122-
// different element types. Here we just pretend it is fine by checking if
1123-
// we're constructing an array for an array of unions. If we didn't do so,
1124-
// we may meet problems during lowering to LLVM. To solve the problem, we
1125-
// may need to introduce 2 type systems for CIR: one for the CIR itself and
1126-
// one for lowering. e.g., we can compare the type of CIR during CIRGen,
1127-
// analysis and transformations without worrying the concerns here. And
1128-
// lower to LLVM IR (or anyother dialects) with the proper type.
1129-
//
1130-
// (Although the idea to make CIR's type system self contained and generate
1131-
// LLVM's
1132-
// types in later passes look fine, it has engineering level concern that
1133-
// it will make the skeleton of CIRGen to be diverged from the traditional
1134-
// CodeGen.)
1135-
//
1136-
// Besides union, there are other differences between CIR and LLVM's type
1137-
// system. e.g., LLVM's pointer types are opaque while CIR has concrete
1138-
// pointer types.
1139-
bool isDesiredArrayOfUnionDirectly = [&]() {
1140-
auto desiredArrayType = dyn_cast<cir::ArrayType>(desiredType);
1141-
if (!desiredArrayType)
1142-
return false;
1143-
1144-
auto elementRecordType =
1145-
dyn_cast<cir::RecordType>(desiredArrayType.getElementType());
1146-
if (!elementRecordType)
1147-
return false;
1148-
1149-
return elementRecordType.isUnion();
1150-
}();
11511109

11521110
// Emit initializer elements as MLIR attributes and check for common type.
11531111
mlir::Type CommonElementType;
@@ -1159,8 +1117,7 @@ class ConstExprEmitter
11591117

11601118
if (i == 0)
11611119
CommonElementType = C.getType();
1162-
else if (isDesiredArrayOfUnionDirectly &&
1163-
C.getType() != CommonElementType)
1120+
else if (C.getType() != CommonElementType)
11641121
CommonElementType = nullptr;
11651122
Elts.push_back(std::move(C));
11661123
}

clang/test/CIR/CodeGen/array-init.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ typedef struct {
99
long b;
1010
} T;
1111

12+
// Test array initialization with different elements.
13+
typedef struct {
14+
long a0;
15+
int a1;
16+
} Inner;
17+
typedef struct {
18+
int b0;
19+
Inner b1[1];
20+
} Outer;
21+
Outer outers[2] = {
22+
{1, {0, 1} },
23+
{1, {0, 0} }
24+
};
25+
// CIR: cir.global{{.*}} @outers = #cir.const_record<{#cir.const_record<{#cir.int<1> : !s32i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 4>, #cir.const_array<[#cir.const_record<{#cir.int<0> : !s64i, #cir.int<1> : !s32i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 4>}> : !rec_anon_struct]> : !cir.array<!rec_anon_struct x 1>}> : !rec_anon_struct2, #cir.const_record<{#cir.int<1> : !s32i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 4>, #cir.zero : !cir.array<!rec_Inner x 1>}> : !rec_anon_struct1}> : !rec_anon_struct3 {alignment = 16 : i64}
26+
// LLVM: @outers = {{.*}}global { { i32, [4 x i8], [1 x { i64, i32, [4 x i8] }] }, { i32, [4 x i8], [1 x %struct.Inner] } } { { i32, [4 x i8], [1 x { i64, i32, [4 x i8] }] } { i32 1, [4 x i8] zeroinitializer, [1 x { i64, i32, [4 x i8] }] [{ i64, i32, [4 x i8] } { i64 0, i32 1, [4 x i8] zeroinitializer }] }, { i32, [4 x i8], [1 x %struct.Inner] } { i32 1, [4 x i8] zeroinitializer, [1 x %struct.Inner] zeroinitializer } }, align 16
27+
1228
void buz(int x) {
1329
T arr[] = { {x, x}, {0, 0} };
1430
}

clang/test/CIR/Lowering/nested-union-array.c

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)