Skip to content

Commit 90e8feb

Browse files
committed
[CIR][CIRGen] Emit constant global _Atomic's
1 parent acf2445 commit 90e8feb

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenExprConst.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,22 @@ mlir::Attribute ConstantEmitter::emitForMemory(CIRGenModule &CGM,
16751675
QualType destType) {
16761676
// For an _Atomic-qualified constant, we may need to add tail padding.
16771677
if (auto AT = destType->getAs<AtomicType>()) {
1678-
assert(0 && "not implemented");
1678+
QualType destValueType = AT->getValueType();
1679+
C = emitForMemory(CGM, C, destValueType);
1680+
1681+
uint64_t innerSize = CGM.getASTContext().getTypeSize(destValueType);
1682+
uint64_t outerSize = CGM.getASTContext().getTypeSize(destType);
1683+
if (innerSize == outerSize)
1684+
return C;
1685+
1686+
assert(innerSize < outerSize && "emitted over-large constant for atomic");
1687+
auto &builder = CGM.getBuilder();
1688+
auto zeroArray = builder.getZeroInitAttr(
1689+
mlir::cir::ArrayType::get(builder.getContext(), builder.getUInt8Ty(),
1690+
(outerSize - innerSize) / 8));
1691+
SmallVector<mlir::Attribute, 4> anonElts = {C, zeroArray};
1692+
auto arrAttr = mlir::ArrayAttr::get(builder.getContext(), anonElts);
1693+
return builder.getAnonConstStruct(arrAttr, false);
16791694
}
16801695

16811696
// Zero-extend bool.

clang/test/CIR/CodeGen/c11atomic.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 %s -triple aarch64-none-linux-android21 -fclangir -emit-cir -std=c11 -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 %s -triple aarch64-none-linux-android21 -fclangir -emit-llvm -std=c11 -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
// CIR-DAG: ![[PS:.*]] = !cir.struct<struct "PS" {!cir.int<s, 16>, !cir.int<s, 16>, !cir.int<s, 16>}
7+
// CIR-DAG: ![[ANON:.*]] = !cir.struct<struct {!cir.struct<struct "PS" {!cir.int<s, 16>, !cir.int<s, 16>, !cir.int<s, 16>} {{.*}}>, !cir.array<!cir.int<u, 8> x 2>}>
8+
// CIR-DAG: cir.global external @testPromotedStructGlobal = #cir.const_struct<{#cir.const_struct<{#cir.int<1> : !s16i, #cir.int<2> : !s16i, #cir.int<3> : !s16i}> : ![[PS]], #cir.zero : !cir.array<!u8i x 2>}> : ![[ANON]]
9+
10+
// LLVM-DAG: %[[PS:.*]] = type { i16, i16, i16 }
11+
// LLVM-DAG: @testPromotedStructGlobal = global { %[[PS]], [2 x i8] } { %[[PS]] { i16 1, i16 2, i16 3 }, [2 x i8] zeroinitializer }
12+
typedef struct { short x, y, z; } PS;
13+
_Atomic PS testPromotedStructGlobal = (PS){1, 2, 3};

0 commit comments

Comments
 (0)