Skip to content

Commit e6ca3a6

Browse files
Merge pull request #71791 from aschwaighofer/large_types_reg2mem_sigh
LargeTypesReg2Mem: Gracefully handle the case when the Container type is deemed small but the Containee is not
2 parents cccaf01 + a17d79c commit e6ca3a6

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3306,7 +3306,7 @@ bool Peepholes::optimizeLoad(SILBasicBlock &BB, SILInstruction *I) {
33063306
if (next2It == BB.end())
33073307
return false;
33083308
auto *store = dyn_cast<StoreInst>(&*next2It);
3309-
if (!store)
3309+
if (!store || store->getSrc() != LI)
33103310
return false;
33113311
if (ignore(store))
33123312
return false;
@@ -3459,6 +3459,19 @@ class AddressAssignment {
34593459

34603460
SILValue getAddressForValue(SILValue v) {
34613461
auto it = valueToAddressMap.find(v);
3462+
3463+
// This can happen if we deem a container type small but a contained type
3464+
// big.
3465+
if (it == valueToAddressMap.end()) {
3466+
if (auto *sv = dyn_cast<SingleValueInstruction>(v)) {
3467+
auto addr = createAllocStack(v->getType());
3468+
auto builder = getBuilder(++sv->getIterator());
3469+
builder.createStore(sv->getLoc(), v, addr,
3470+
StoreOwnershipQualifier::Unqualified);
3471+
mapValueToAddress(v, addr);
3472+
return addr;
3473+
}
3474+
}
34623475
assert(it != valueToAddressMap.end());
34633476

34643477
return it->second;

test/IRGen/Inputs/large_c.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,14 @@ struct SamplesType {
2929
void* Z;
3030
void* AA;
3131
};
32+
33+
34+
typedef struct _ContainedType {
35+
unsigned int f1;
36+
float f2;
37+
} __attribute__((packed)) ContainedType;
38+
39+
typedef struct _ContainerType {
40+
char x1;
41+
ContainedType l[10];
42+
} __attribute__((packed)) ContainerType;

test/IRGen/loadable_by_address_reg2mem.sil

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ struct Y {
2929
var y2: X
3030
}
3131

32+
class C1 {
33+
}
34+
35+
sil_vtable C1 {
36+
}
37+
38+
struct Small {
39+
var x1 : Int
40+
}
41+
3242
// CHECK: sil @test1 : $@convention(thin) () -> () {
3343
// CHECK: bb0:
3444
// CHECK: %0 = alloc_stack $Optional<X>
@@ -229,3 +239,33 @@ bb0(%0 : $SamplesType):
229239
%t = tuple ()
230240
return %t : $()
231241
}
242+
243+
// In this test case Container type is identified as not large but contained
244+
// type is.
245+
sil @test9 : $@convention(thin) () -> () {
246+
bb0:
247+
%0 = alloc_stack $_ContainerType
248+
%1 = load %0 : $*_ContainerType
249+
%2 = alloc_stack $(_ContainedType, _ContainedType, _ContainedType, _ContainedType, _ContainedType,
250+
_ContainedType, _ContainedType, _ContainedType, _ContainedType, _ContainedType)
251+
252+
%3 = struct_extract %1 : $_ContainerType, #_ContainerType.l
253+
store %3 to %2 : $*(_ContainedType, _ContainedType, _ContainedType, _ContainedType, _ContainedType,
254+
_ContainedType, _ContainedType, _ContainedType, _ContainedType, _ContainedType)
255+
dealloc_stack %2 : $*(_ContainedType, _ContainedType, _ContainedType, _ContainedType, _ContainedType,
256+
_ContainedType, _ContainedType, _ContainedType, _ContainedType, _ContainedType)
257+
dealloc_stack %0 : $*_ContainerType
258+
%t = tuple ()
259+
return %t : $()
260+
}
261+
262+
sil @test10 : $@convention(thin) (@in_guaranteed C1, @in Small) -> () {
263+
bb0(%0 : $*C1, %1 : $*Small):
264+
%2 = load %1 : $*Small
265+
%3 = load %0 : $*C1
266+
retain_value %3 : $C1
267+
store %2 to %1 : $*Small
268+
retain_value %3 : $C1
269+
%t = tuple ()
270+
return %t : $()
271+
}

0 commit comments

Comments
 (0)