Skip to content

Commit 8099dc6

Browse files
Merge pull request #1999 from aschwaighofer/rdar_67351073
Teach the swift calling convention about _Atomic types
2 parents e662434 + 020bdf7 commit 8099dc6

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

clang/lib/CodeGen/SwiftCallingConv.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,24 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) {
9393
// Just add it all as opaque.
9494
addOpaqueData(begin, begin + CGM.getContext().getTypeSizeInChars(type));
9595

96-
// Everything else is scalar and should not convert as an LLVM aggregate.
96+
// Atomic types.
97+
} else if (const auto *atomicType = type->getAs<AtomicType>()) {
98+
auto valueType = atomicType->getValueType();
99+
auto atomicSize = CGM.getContext().getTypeSizeInChars(atomicType);
100+
auto valueSize = CGM.getContext().getTypeSizeInChars(valueType);
101+
102+
addTypedData(atomicType->getValueType(), begin);
103+
104+
// Add atomic padding.
105+
auto atomicPadding = atomicSize - valueSize;
106+
if (atomicPadding > CharUnits::Zero())
107+
addOpaqueData(begin + valueSize, begin + atomicSize);
108+
109+
// Everything else is scalar and should not convert as an LLVM aggregate.
97110
} else {
98111
// We intentionally convert as !ForMem because we want to preserve
99112
// that a type was an i1.
100-
auto llvmType = CGM.getTypes().ConvertType(type);
113+
auto *llvmType = CGM.getTypes().ConvertType(type);
101114
addTypedData(llvmType, begin);
102115
}
103116
}

clang/test/CodeGen/64bit-swiftcall.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#define ERROR __attribute__((swift_error_result))
1111
#define CONTEXT __attribute__((swift_context))
1212

13+
// CHECK-DAG: %struct.atomic_padded = type { { %struct.packed, [7 x i8] } }
14+
// CHECK-DAG: %struct.packed = type <{ i64, i8 }>
15+
//
1316
// CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, i32 0, i32 0 }
1417

1518
/*****************************************************************************/
@@ -1042,3 +1045,27 @@ void no_lifetime_markers() {
10421045
// CHECK-NOT: call void @llvm.lifetime.
10431046
take_int5(return_int5());
10441047
}
1048+
1049+
typedef struct {
1050+
unsigned long long a;
1051+
unsigned long long b;
1052+
} double_word;
1053+
1054+
typedef struct {
1055+
_Atomic(double_word) a;
1056+
} atomic_double_word;
1057+
1058+
// CHECK-LABEL: use_atomic(i64 %0, i64 %1)
1059+
SWIFTCALL void use_atomic(atomic_double_word a) {}
1060+
1061+
typedef struct {
1062+
unsigned long long a;
1063+
unsigned char b;
1064+
} __attribute__((packed)) packed;
1065+
1066+
typedef struct {
1067+
_Atomic(packed) a;
1068+
} atomic_padded;
1069+
1070+
// CHECK-LABEL: use_atomic_padded(i64 %0, i64 %1)
1071+
SWIFTCALL void use_atomic_padded(atomic_padded a) {}

0 commit comments

Comments
 (0)