Skip to content

Commit 9c62086

Browse files
committed
The instance alignment mask in the class metadata is a 16-bit field, and must be loaded with a 16-bit load instruction for correctness on big-endian systems.
1 parent 7127bff commit 9c62086

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4338,16 +4338,20 @@ irgen::emitClassResilientInstanceSizeAndAlignMask(IRGenFunction &IGF,
43384338
&& "didn't find size or alignment in metadata?!");
43394339
Address metadataAsBytes(IGF.Builder.CreateBitCast(metadata, IGF.IGM.Int8PtrTy),
43404340
IGF.IGM.getPointerAlignment());
4341-
auto loadZExtInt32AtOffset = [&](Size offset) {
4342-
Address slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes, offset);
4343-
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int32Ty->getPointerTo());
4344-
llvm::Value *result = IGF.Builder.CreateLoad(slot);
4345-
if (IGF.IGM.SizeTy != IGF.IGM.Int32Ty)
4346-
result = IGF.Builder.CreateZExt(result, IGF.IGM.SizeTy);
4347-
return result;
4348-
};
4349-
llvm::Value *size = loadZExtInt32AtOffset(scanner.InstanceSize);
4350-
llvm::Value *alignMask = loadZExtInt32AtOffset(scanner.InstanceAlignMask);
4341+
4342+
Address slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes,
4343+
scanner.InstanceSize);
4344+
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int32Ty->getPointerTo());
4345+
llvm::Value *size = IGF.Builder.CreateLoad(slot);
4346+
if (IGF.IGM.SizeTy != IGF.IGM.Int32Ty)
4347+
size = IGF.Builder.CreateZExt(size, IGF.IGM.SizeTy);
4348+
4349+
slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes,
4350+
scanner.InstanceAlignMask);
4351+
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int16Ty->getPointerTo());
4352+
llvm::Value *alignMask = IGF.Builder.CreateLoad(slot);
4353+
alignMask = IGF.Builder.CreateZExt(alignMask, IGF.IGM.SizeTy);
4354+
43514355
return {size, alignMask};
43524356
}
43534357

test/IRGen/class.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ bb0(%0 : $@thick C.Type):
9797
// CHECK: [[SIZE32:%.*]] = load i32, i32* [[T1]], align 8
9898
// CHECK: [[SIZE:%.*]] = zext i32 [[SIZE32]] to i64
9999
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[META_PTR]], i32 52
100-
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
101-
// CHECK: [[ALIGN32:%.*]] = load i32, i32* [[T1]], align 4
102-
// CHECK: [[ALIGN:%.*]] = zext i32 [[ALIGN32]] to i64
100+
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i16*
101+
// CHECK: [[ALIGN16:%.*]] = load i16, i16* [[T1]], align 4
102+
// CHECK: [[ALIGN:%.*]] = zext i16 [[ALIGN16]] to i64
103103
// CHECK: [[RESULT:%[0-9]+]] = call noalias %swift.refcounted* @rt_swift_allocObject(%swift.type* %0, i64 [[SIZE]], i64 [[ALIGN]])
104104
%1 = alloc_ref_dynamic %0 : $@thick C.Type, $C
105105
return %1 : $C

test/IRGen/generic_classes.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ sil @_TFC15generic_classes31RecursiveGenericInheritsGenericD : $@convention(meth
211211
// CHECK: [[SIZE32:%.*]] = load i32, i32* [[T1]], align 8
212212
// CHECK: [[SIZE:%.*]] = zext i32 [[SIZE32]] to i64
213213
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[METADATA_ARRAY]], i32 52
214-
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
215-
// CHECK: [[ALIGN32:%.*]] = load i32, i32* [[T1]], align 4
216-
// CHECK: [[ALIGN:%.*]] = zext i32 [[ALIGN32]] to i64
214+
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i16*
215+
// CHECK: [[ALIGN16:%.*]] = load i16, i16* [[T1]], align 4
216+
// CHECK: [[ALIGN:%.*]] = zext i16 [[ALIGN16]] to i64
217217
// CHECK: call noalias %swift.refcounted* @rt_swift_allocObject(%swift.type* [[METADATA]], i64 [[SIZE]], i64 [[ALIGN]])
218218
sil @RootGeneric_fragile_dependent_alloc : $<G> () -> RootGeneric<G> {
219219
entry:

0 commit comments

Comments
 (0)