Skip to content

Commit b388f4b

Browse files
authored
Merge pull request #14652 from eeckstein/fix-alignment
2 parents 8045963 + e88d4e2 commit b388f4b

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,10 @@ static llvm::Value *stackPromote(IRGenFunction &IGF,
739739
return Alloca.getAddress();
740740
}
741741

742-
llvm::Value *irgen::appendSizeForTailAllocatedArrays(IRGenFunction &IGF,
743-
llvm::Value *size,
744-
TailArraysRef TailArrays) {
742+
std::pair<llvm::Value *, llvm::Value *>
743+
irgen::appendSizeForTailAllocatedArrays(IRGenFunction &IGF,
744+
llvm::Value *size, llvm::Value *alignMask,
745+
TailArraysRef TailArrays) {
745746
for (const auto &TailArray : TailArrays) {
746747
SILType ElemTy = TailArray.first;
747748
llvm::Value *Count = TailArray.second;
@@ -750,16 +751,17 @@ llvm::Value *irgen::appendSizeForTailAllocatedArrays(IRGenFunction &IGF,
750751

751752
// Align up to the tail-allocated array.
752753
llvm::Value *ElemStride = ElemTI.getStride(IGF, ElemTy);
753-
llvm::Value *AlignMask = ElemTI.getAlignmentMask(IGF, ElemTy);
754-
size = IGF.Builder.CreateAdd(size, AlignMask);
755-
llvm::Value *InvertedMask = IGF.Builder.CreateNot(AlignMask);
754+
llvm::Value *ElemAlignMask = ElemTI.getAlignmentMask(IGF, ElemTy);
755+
size = IGF.Builder.CreateAdd(size, ElemAlignMask);
756+
llvm::Value *InvertedMask = IGF.Builder.CreateNot(ElemAlignMask);
756757
size = IGF.Builder.CreateAnd(size, InvertedMask);
757758

758759
// Add the size of the tail allocated array.
759760
llvm::Value *AllocSize = IGF.Builder.CreateMul(ElemStride, Count);
760761
size = IGF.Builder.CreateAdd(size, AllocSize);
762+
alignMask = IGF.Builder.CreateOr(alignMask, ElemAlignMask);
761763
}
762-
return size;
764+
return {size, alignMask};
763765
}
764766

765767

@@ -800,7 +802,8 @@ llvm::Value *irgen::emitClassAllocation(IRGenFunction &IGF, SILType selfType,
800802
val = IGF.emitInitStackObjectCall(metadata, val, "reference.new");
801803
} else {
802804
// Allocate the object on the heap.
803-
size = appendSizeForTailAllocatedArrays(IGF, size, TailArrays);
805+
std::tie(size, alignMask)
806+
= appendSizeForTailAllocatedArrays(IGF, size, alignMask, TailArrays);
804807
val = IGF.emitAllocObjectCall(metadata, size, alignMask, "reference.new");
805808
StackAllocSize = -1;
806809
}
@@ -823,7 +826,8 @@ llvm::Value *irgen::emitClassAllocationDynamic(IRGenFunction &IGF,
823826
= emitClassResilientInstanceSizeAndAlignMask(IGF,
824827
selfType.getClassOrBoundGenericClass(),
825828
metadata);
826-
size = appendSizeForTailAllocatedArrays(IGF, size, TailArrays);
829+
std::tie(size, alignMask)
830+
= appendSizeForTailAllocatedArrays(IGF, size, alignMask, TailArrays);
827831

828832
llvm::Value *val = IGF.emitAllocObjectCall(metadata, size, alignMask,
829833
"reference.new");

lib/IRGen/GenClass.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,12 @@ namespace irgen {
9595
typedef llvm::ArrayRef<std::pair<SILType, llvm::Value *>> TailArraysRef;
9696

9797
/// Adds the size for tail allocated arrays to \p size and returns the new
98-
/// size value.
99-
llvm::Value *appendSizeForTailAllocatedArrays(IRGenFunction &IGF,
100-
llvm::Value *size,
101-
TailArraysRef TailArrays);
98+
/// size value. Also updades the alignment mask to represent the alignment of
99+
/// the largest element.
100+
std::pair<llvm::Value *, llvm::Value *>
101+
appendSizeForTailAllocatedArrays(IRGenFunction &IGF,
102+
llvm::Value *size, llvm::Value *alignMask,
103+
TailArraysRef TailArrays);
102104

103105
/// Emit an allocation of a class.
104106
/// The \p StackAllocSize is an in- and out-parameter. The passed value

test/IRGen/tail_alloc.sil

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ bb0(%c1 : $Builtin.Word, %c2 : $Builtin.Word):
9595
// CHECK-NEXT: [[S3:%[0-9]+]] = and i64 [[S1]], [[S2]]
9696
// CHECK-NEXT: [[S4:%[0-9]+]] = mul i64 %stride, %0
9797
// CHECK-NEXT: [[S5:%[0-9]+]] = add i64 [[S3]], [[S4]]
98-
// CHECK: call noalias %swift.refcounted* @swift_allocObject(%swift.type* %{{[0-9]+}}, i64 [[S5]], i64 7)
98+
// CHECK-NEXT: [[A:%[0-9]+]] = or i64 7, %flags.alignmentMask
99+
// CHECK: call noalias %swift.refcounted* @swift_allocObject(%swift.type* %{{[0-9]+}}, i64 [[S5]], i64 [[A]])
99100
// CHECK: ret
100101
sil @alloc_generic : $@convention(thin) <T> (Builtin.Word, @thick T.Type) -> @owned TestClass {
101102
bb0(%0 : $Builtin.Word, %1 : $@thick T.Type):
@@ -110,10 +111,15 @@ bb0(%0 : $Builtin.Word, %1 : $@thick T.Type):
110111
// CHECK-NEXT: [[INT_PTR:%[0-9]+]] = bitcast i8* [[SIZE_ADDR]] to i32*
111112
// CHECK-NEXT: [[SIZE:%[0-9]+]] = load i32, i32* [[INT_PTR]]
112113
// CHECK-NEXT: [[SIZE64:%[0-9]+]] = zext i32 [[SIZE]] to i64
113-
// CHECK: [[ALIGN_TMP:%[0-9]+]] = add i64 [[SIZE64]], 3
114+
// CHECK-NEXT: [[ALIGN_ADDR:%[0-9]+]] = getelementptr inbounds i8, i8* [[BYTE_PTR]], i32 52
115+
// CHECK-NEXT: [[SHORT_PTR:%[0-9]+]] = bitcast i8* [[ALIGN_ADDR]] to i16*
116+
// CHECK-NEXT: [[ALIGN:%[0-9]+]] = load i16, i16* [[SHORT_PTR]]
117+
// CHECK-NEXT: [[ALIGN64:%[0-9]+]] = zext i16 [[ALIGN]] to i64
118+
// CHECK-NEXT: [[ALIGN_TMP:%[0-9]+]] = add i64 [[SIZE64]], 3
114119
// CHECK-NEXT: [[ALIGNED:%[0-9]+]] = and i64 [[ALIGN_TMP]], -4
115120
// CHECK-NEXT: [[TOTAL_SIZE:%[0-9]+]] = add i64 [[ALIGNED]], 12
116-
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* %0, i64 [[TOTAL_SIZE]], i64 {{.*}})
121+
// CHECK-NEXT: [[TOTAL_ALIGN:%[0-9]+]] = or i64 [[ALIGN64]], 3
122+
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* %0, i64 [[TOTAL_SIZE]], i64 [[TOTAL_ALIGN]])
117123
// CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %{{.*TestClassC}}*
118124
// CHECK-NEXT: ret %{{.*TestClassC}}* [[O2]]
119125
sil @alloc_dynamic : $@convention(thin) (@thick TestClass.Type) -> @owned TestClass {

0 commit comments

Comments
 (0)