Skip to content

Commit 223ebd2

Browse files
authored
Merge pull request #79994 from Azoy/fix-empty-inlinearray
[SILGen] Fix empty inline array literals
2 parents 203ad94 + 8b3499d commit 223ebd2

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

lib/SIL/IR/SILType.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ bool SILType::isEmpty(const SILFunction &F) const {
157157
}
158158
return true;
159159
}
160+
160161
if (StructDecl *structDecl = getStructOrBoundGenericStruct()) {
161162
// Also, a struct is empty if it either has no fields or if all fields are
162163
// empty.
@@ -168,6 +169,13 @@ bool SILType::isEmpty(const SILFunction &F) const {
168169
}
169170
return true;
170171
}
172+
173+
if (auto bfa = getAs<BuiltinFixedArrayType>()) {
174+
if (auto size = bfa->getFixedInhabitedSize()) {
175+
return size == 0;
176+
}
177+
}
178+
171179
return false;
172180
}
173181

lib/SILGen/SILGenExpr.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4599,11 +4599,21 @@ visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C) {
45994599
}
46004600

46014601
static RValue emitInlineArrayLiteral(SILGenFunction &SGF, CollectionExpr *E,
4602-
SGFContext C) {
4602+
SGFContext C) {
46034603
ArgumentScope scope(SGF, E);
46044604

46054605
auto iaTy = E->getType()->castTo<BoundGenericType>();
46064606
auto loweredIAType = SGF.getLoweredType(iaTy);
4607+
4608+
// If this is an empty InlineArray literal and it's loadable, then create an
4609+
// empty tuple value and just bitcast it for the loaded value. Address only
4610+
// empty inline arrays will just have an empty 'alloc_stack'.
4611+
if (E->getNumElements() == 0 && !loweredIAType.isAddressOnly(SGF.F)) {
4612+
auto emptyTuple = ManagedValue::forRValueWithoutOwnership(SGF.emitEmptyTuple(E));
4613+
auto inlineArray = SGF.B.createUncheckedBitCast(E, emptyTuple, loweredIAType);
4614+
return scope.popPreservingValue(RValue(SGF, E, inlineArray));
4615+
}
4616+
46074617
auto elementType = iaTy->getGenericArgs()[1]->getCanonicalType();
46084618
auto loweredElementType = SGF.getLoweredType(elementType);
46094619
auto &eltTL = SGF.getTypeLowering(AbstractionPattern::getOpaque(), elementType);

test/SILGen/inlinearray_literal.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,39 @@
22

33
import Synchronization
44

5+
// CHECK-LABEL: sil{{.*}} @$s19inlinearray_literal12emptyTrivials11InlineArrayVy$_SiGyF : $@convention(thin) () -> InlineArray<0, Int> {
6+
// CHECK: [[EMPTY_TUPLE:%.*]] = tuple ()
7+
// CHECK-NEXT: [[IA:%.*]] = unchecked_trivial_bit_cast [[EMPTY_TUPLE]] to $InlineArray<0, Int>
8+
// CHECK-NEXT: return [[IA]]
9+
// CHECK-LABEL: } // end sil function '$s19inlinearray_literal12emptyTrivials11InlineArrayVy$_SiGyF'
10+
func emptyTrivial() -> InlineArray<0, Int> {
11+
[]
12+
}
13+
14+
// CHECK-LABEL: sil{{.*}} @$s19inlinearray_literal15emptyNontrivials11InlineArrayVy$_SSGyF : $@convention(thin) () -> @owned InlineArray<0, String> {
15+
// CHECK: [[EMPTY_TUPLE:%.*]] = tuple ()
16+
// CHECK-NEXT: [[IA:%.*]] = unchecked_bitwise_cast [[EMPTY_TUPLE]] to $InlineArray<0, String>
17+
// CHECK-NEXT: [[COPY_IA:%.*]] = copy_value [[IA]]
18+
// CHECK-NEXT: return [[COPY_IA]]
19+
// CHECK-LABEL: } // end sil function '$s19inlinearray_literal15emptyNontrivials11InlineArrayVy$_SSGyF'
20+
func emptyNontrivial() -> InlineArray<0, String> {
21+
[]
22+
}
23+
24+
// CHECK-LABEL: sil{{.*}} @$s19inlinearray_literal16emptyNoncopyables11InlineArrayVy$_15Synchronization6AtomicVySiGGyF : $@convention(thin) () -> @out InlineArray<0, Atomic<Int>> {
25+
// CHECK: bb0([[IA_RETURN:%.*]] : $*InlineArray<0, Atomic<Int>>):
26+
// CHECK-NEXT: [[IA_ALLOC:%.*]] = alloc_stack $InlineArray<0, Atomic<Int>>
27+
// CHECK: [[IA_CAST:%.*]] = unchecked_addr_cast [[IA_ALLOC]] to $*InlineArray<0, Atomic<Int>>
28+
// CHECK-NEXT: [[IA_BOX:%.*]] = alloc_box
29+
// CHECK-NEXT: [[BORROW_BOX:%.*]] = begin_borrow [lexical] [[IA_BOX]]
30+
// CHECK-NEXT: [[PROJECT_BOX:%.*]] = project_box [[BORROW_BOX]], 0
31+
// CHECK-NEXT: copy_addr [take] [[IA_CAST]] to [init] [[PROJECT_BOX]]
32+
// CHECK-NEXT: dealloc_stack [[IA_ALLOC]]
33+
// CHECK-LABEL: } // end sil function '$s19inlinearray_literal16emptyNoncopyables11InlineArrayVy$_15Synchronization6AtomicVySiGGyF'
34+
func emptyNoncopyable() -> InlineArray<0, Atomic<Int>> {
35+
[]
36+
}
37+
538
// CHECK-LABEL: sil{{.*}} @$s19inlinearray_literal7trivials11InlineArrayVy$3_SiGyF : $@convention(thin) () -> InlineArray<4, Int> {
639
// CHECK: [[SLAB_ALLOC:%.*]] = alloc_stack $InlineArray<4, Int>
740
// CHECK-NEXT: [[ELEMENT_PTR:%.*]] = unchecked_addr_cast [[SLAB_ALLOC]] to $*Int

0 commit comments

Comments
 (0)