Skip to content

Commit 4991421

Browse files
authored
[CIR][CodeGen] Supports const array user in the globals replacement (#1567)
This is a just small fix that cover the case when the global union is declared with `static` keyword and one of the its users is an array
1 parent 9f6742f commit 4991421

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,9 @@ void CIRGenModule::replaceGlobal(cir::GlobalOp oldSym, cir::GlobalOp newSym) {
10091009
if (oldSymUses.has_value()) {
10101010
for (auto use : *oldSymUses) {
10111011
auto *userOp = use.getUser();
1012-
assert((isa<cir::GetGlobalOp>(userOp) || isa<cir::GlobalOp>(userOp)) &&
1013-
"GlobalOp symbol user is neither a GetGlobalOp nor a GlobalOp");
1012+
assert(
1013+
(isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1014+
"GlobalOp symbol user is neither a GetGlobalOp nor a GlobalOp");
10141015

10151016
if (auto ggo = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
10161017
auto useOpResultValue = ggo.getAddr();
@@ -1028,6 +1029,15 @@ void CIRGenModule::replaceGlobal(cir::GlobalOp oldSym, cir::GlobalOp newSym) {
10281029
auto nw = getNewInitValue(*this, newSym, oldTy, glob, init.value());
10291030
glob.setInitialValueAttr(nw);
10301031
}
1032+
} else if (auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1033+
mlir::Attribute init =
1034+
getNewInitValue(*this, newSym, oldTy, glob, c.getValue());
1035+
auto ar = cast<ConstArrayAttr>(init);
1036+
mlir::OpBuilder::InsertionGuard guard(builder);
1037+
builder.setInsertionPointAfter(c);
1038+
auto newUser =
1039+
builder.create<cir::ConstantOp>(c.getLoc(), ar.getType(), ar);
1040+
c.replaceAllUsesWith(newUser.getOperation());
10311041
}
10321042
}
10331043
}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,24 @@ typedef union {
1616
S_2 b;
1717
} U;
1818

19+
typedef union {
20+
int f0;
21+
int f1;
22+
} U1;
23+
24+
static U1 g = {5};
25+
// LLVM: @__const.bar.x = private constant [2 x ptr] [ptr @g, ptr @g]
26+
// LLVM: @g = internal global { i32 } { i32 5 }
27+
// FIXME: LLVM output should be: @g = internal global %union.U { i32 5 }
28+
29+
1930
void foo() { U arr[2] = {{.b = {1, 2}}, {.a = {1}}}; }
2031

2132
// CIR: cir.const #cir.const_record<{#cir.const_record<{#cir.const_record<{#cir.int<1> : !s64i, #cir.int<2> : !s64i}> : {{.*}}}> : {{.*}}, #cir.const_record<{#cir.const_record<{#cir.int<1> : !s8i}> : {{.*}}, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 15>}>
2233
// LLVM: store { { %struct.S_2 }, { %struct.S_1, [15 x i8] } } { { %struct.S_2 } { %struct.S_2 { i64 1, i64 2 } }, { %struct.S_1, [15 x i8] } { %struct.S_1 { i8 1 }, [15 x i8] zeroinitializer } }
34+
35+
void bar(void) {
36+
int *x[2] = { &g.f0, &g.f0 };
37+
}
38+
// CIR: cir.global "private" internal dsolocal @g = #cir.const_record<{#cir.int<5> : !s32i}> : !ty_anon_struct
39+
// CIR: cir.const #cir.const_array<[#cir.global_view<@g> : !cir.ptr<!s32i>, #cir.global_view<@g> : !cir.ptr<!s32i>]> : !cir.array<!cir.ptr<!s32i> x 2>

0 commit comments

Comments
 (0)