llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Sirui Mu (Lancern)
<details>
<summary>Changes</summary>
This patch adds support for the initialization of atomic aggregates with
padding. The changes include:
- During CIRGen, the type `_Atomic(T)` is represented by a CIR struct `{T,
sint8[padding_size]}` if the size of `_Atomic(T)` does not match the size of
`T`. `padding_size` is the difference between the size of `_Atomic(T)` and `T`.
- CIRGen for the initialization process is updated to handle the
initialization of such CIR struct values.
---
Full diff: https://github.com/llvm/llvm-project/pull/200668.diff
4 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenAtomic.cpp (+11-6)
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+23)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+7-1)
- (modified) clang/test/CIR/CodeGen/atomic.c (+47)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 3df0cd23d570e..0a961c177be8e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -124,9 +124,9 @@ class AtomicInfo {
LValue projectValue() const {
assert(lvalue.isSimple());
Address addr = getAtomicAddress();
- if (hasPadding()) {
- cgf.cgm.errorNYI(loc, "AtomicInfo::projectValue: padding");
- }
+ if (hasPadding())
+ addr = cgf.getBuilder().createGetMember(loc, addr, /*name=*/"value",
+ /*index=*/0);
assert(!cir::MissingFeatures::opTBAA());
return LValue::makeAddr(addr, getValueType(), lvalue.getBaseInfo());
@@ -262,9 +262,14 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
if (!requiresMemSetZero(addr.getElementType()))
return false;
- cgf.cgm.errorNYI(loc,
- "AtomicInfo::emitMemSetZeroIfNecaessary: emit memset zero");
- return false;
+ addr = addr.withElementType(cgf.getBuilder(), cgf.cgm.voidTy);
+ mlir::Value zero = cgf.getBuilder().getConstInt(loc, cgf.cgm.uInt8Ty, 0);
+ mlir::Value memSetSize = cgf.getBuilder().getConstInt(
+ loc, cgf.cgm.uInt64Ty,
+ cgf.getContext().toCharUnitsFromBits(atomicSizeInBits).getQuantity());
+
+ cgf.getBuilder().createMemSet(loc, addr, zero, memSetSize);
+ return true;
}
/// Return true if \param valueTy is a type that should be casted to integer
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index aeb1a122429e2..e78c8928de854 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -692,6 +692,29 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
addr.getAlignment()};
}
+ using CIRBaseBuilderTy::createGetMember;
+ Address createGetMember(mlir::Location loc, Address base,
+ llvm::StringRef name, unsigned index) {
+ auto recordTy = mlir::cast<cir::RecordType>(base.getElementType());
+
+ assert(index < recordTy.getMembers().size() &&
+ "member index out of bounds");
+ mlir::Type memberTy = recordTy.getMembers()[index];
+ mlir::Type memberPtrTy = getPointerTo(memberTy);
+
+ auto moduleOp =
+ getInsertionBlock()->getParentOp()->getParentOfType<mlir::ModuleOp>();
+ mlir::DataLayout layout(moduleOp);
+ auto memberOffset =
+ CharUnits::fromQuantity(recordTy.getElementOffset(layout, index));
+
+ mlir::Value memberPtr =
+ createGetMember(loc, memberPtrTy, base.getBasePointer(), name, index);
+ return Address(memberPtr, memberTy,
+ base.getAlignment().alignmentAtOffset(memberOffset),
+ base.isKnownNonNull());
+ }
+
cir::GetRuntimeMemberOp createGetIndirectMember(mlir::Location loc,
mlir::Value objectPtr,
mlir::Value memberPtr) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 61e2365bd5255..e6452f8592d22 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -639,7 +639,13 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
uint64_t valueSize = astContext.getTypeSize(valueType);
uint64_t atomicSize = astContext.getTypeSize(ty);
if (valueSize != atomicSize) {
- cgm.errorNYI("convertType: atomic type value size != atomic size");
+ assert(valueSize < atomicSize);
+ auto paddingArray =
+ cir::ArrayType::get(cgm.sInt8Ty, (atomicSize - valueSize) / 8);
+ mlir::Type elements[] = {resultType, paddingArray};
+ resultType = cir::RecordType::get(&getMLIRContext(),
/*members=*/elements,
+ /*packed=*/false, /*padded=*/false,
+ /*kind=*/cir::RecordType::Struct);
}
break;
diff --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c
index e4f3fe82310a4..aae9792ba2b76 100644
--- a/clang/test/CIR/CodeGen/atomic.c
+++ b/clang/test/CIR/CodeGen/atomic.c
@@ -5,6 +5,10 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value
-emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+struct S1 {
+ short x, y, z;
+};
+
_Atomic int g1;
_Atomic int g2 = 42;
// CIR: cir.global external @g2 = #cir.int<42> : !s32i {alignment = 4 : i64}
@@ -83,6 +87,49 @@ void f4(_Atomic(float) *p) {
// OGCG-LABEL: @f4
// OGCG: store atomic float 3.140000e+00, ptr %{{.+}} seq_cst, align 4
+void init_with_padding(_Atomic struct S1 *p) {
+ // CIR-LABEL: @init_with_padding
+ // LLVM-LABEL: @init_with_padding
+ // OGCG-LABEL: @init_with_padding
+
+ __c11_atomic_init(p, (struct S1){1, 2, 3});
+
+ // CIR: %[[PTR_VOID:.+]] = cir.cast bitcast %[[PTR:.+]] :
!cir.ptr<!rec_anon_struct> -> !cir.ptr<!void>
+ // CIR-NEXT: %[[MEMSET_VALUE:.+]] = cir.const #cir.int<0> : !u8i
+ // CIR-NEXT: %[[MEMSET_SIZE:.+]] = cir.const #cir.int<8> : !u64i
+ // CIR-NEXT: cir.libc.memset %[[MEMSET_SIZE]] bytes at %[[PTR_VOID]]
align(8) to %[[MEMSET_VALUE]] : !cir.ptr<!void>, !u8i, !u64i
+ // CIR-NEXT: %[[VALUE_PTR:.+]] = cir.get_member %[[PTR]][0] {name = "value"}
: !cir.ptr<!rec_anon_struct> -> !cir.ptr<!rec_S1>
+ // CIR-NEXT: %[[X_PTR:.+]] = cir.get_member %[[VALUE_PTR]][0] {name = "x"} :
!cir.ptr<!rec_S1> -> !cir.ptr<!s16i>
+ // CIR-NEXT: %[[X_INIT:.+]] = cir.const #cir.int<1> : !s16i
+ // CIR-NEXT: cir.store align(8) %[[X_INIT]], %[[X_PTR]] : !s16i,
!cir.ptr<!s16i>
+ // CIR-NEXT: %[[Y_PTR:.+]] = cir.get_member %[[VALUE_PTR]][1] {name = "y"} :
!cir.ptr<!rec_S1> -> !cir.ptr<!s16i>
+ // CIR-NEXT: %[[Y_INIT:.+]] = cir.const #cir.int<2> : !s16i
+ // CIR-NEXT: cir.store align(2) %[[Y_INIT]], %[[Y_PTR]] : !s16i,
!cir.ptr<!s16i>
+ // CIR-NEXT: %[[Z_PTR:.+]] = cir.get_member %[[VALUE_PTR]][2] {name = "z"} :
!cir.ptr<!rec_S1> -> !cir.ptr<!s16i>
+ // CIR-NEXT: %[[Z_INIT:.+]] = cir.const #cir.int<3> : !s16i
+ // CIR-NEXT: cir.store align(4) %[[Z_INIT]], %[[Z_PTR]] : !s16i,
!cir.ptr<!s16i>
+
+ // LLVM: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 8
+ // LLVM-NEXT: call void @llvm.memset.p0.i64(ptr align 8 %[[PTR]], i8 0, i64
8, i1 false)
+ // LLVM-NEXT: %[[VALUE_PTR:.+]] = getelementptr inbounds nuw { %struct.S1,
[2 x i8] }, ptr %[[PTR]], i32 0, i32 0
+ // LLVM-NEXT: %[[X_PTR:.+]] = getelementptr inbounds nuw %struct.S1, ptr
%[[VALUE_PTR]], i32 0, i32 0
+ // LLVM-NEXT: store i16 1, ptr %[[X_PTR]], align 8
+ // LLVM-NEXT: %[[Y_PTR:.+]] = getelementptr inbounds nuw %struct.S1, ptr
%[[VALUE_PTR]], i32 0, i32 1
+ // LLVM-NEXT: store i16 2, ptr %[[Y_PTR]], align 2
+ // LLVM-NEXT: %[[Z_PTR:.+]] = getelementptr inbounds nuw %struct.S1, ptr
%[[VALUE_PTR]], i32 0, i32 2
+ // LLVM-NEXT: store i16 3, ptr %[[Z_PTR]], align 4
+
+ // OGCG: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 8
+ // OGCG-NEXT: call void @llvm.memset.p0.i64(ptr align 8 %[[PTR]], i8 0, i64
8, i1 false)
+ // OGCG-NEXT: %[[VALUE_PTR:.+]] = getelementptr inbounds nuw { %struct.S1,
[2 x i8] }, ptr %[[PTR]], i32 0, i32 0
+ // OGCG-NEXT: %[[X_PTR:.+]] = getelementptr inbounds nuw %struct.S1, ptr
%[[VALUE_PTR]], i32 0, i32 0
+ // OGCG-NEXT: store i16 1, ptr %[[X_PTR]], align 8
+ // OGCG-NEXT: %[[Y_PTR:.+]] = getelementptr inbounds nuw %struct.S1, ptr
%[[VALUE_PTR]], i32 0, i32 1
+ // OGCG-NEXT: store i16 2, ptr %[[Y_PTR]], align 2
+ // OGCG-NEXT: %[[Z_PTR:.+]] = getelementptr inbounds nuw %struct.S1, ptr
%[[VALUE_PTR]], i32 0, i32 2
+ // OGCG-NEXT: store i16 3, ptr %[[Z_PTR]], align 4
+}
+
void atomic_to_non_atomic(_Atomic int *ptr, _Atomic volatile int *vptr) {
// CIR-LABEL: @atomic_to_non_atomic
// LLVM-LABEL: @atomic_to_non_atomic
``````````
</details>
https://github.com/llvm/llvm-project/pull/200668
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits