File tree Expand file tree Collapse file tree 2 files changed +50
-8
lines changed Expand file tree Collapse file tree 2 files changed +50
-8
lines changed Original file line number Diff line number Diff line change @@ -3310,16 +3310,20 @@ static void emitApplyArgument(IRGenSILFunction &IGF,
33103310 bool canForwardLoadToIndirect = false ;
33113311 auto *load = dyn_cast<LoadInst>(arg);
33123312 [&]() {
3313- if (apply && load && apply->getParent () == load->getParent ()) {
3314- for (auto it = std::next (load->getIterator ()), e = apply->getIterator ();
3315- it != e; ++it) {
3316- if (isa<LoadInst>(&(*it))) {
3317- continue ;
3318- }
3319- return ;
3313+ if (!apply || !load || apply->getParent () != load->getParent ())
3314+ return ;
3315+ // We cannot forward projections as the code that does the optimization
3316+ // does not know about them.
3317+ if (!isa<AllocStackInst>(load->getOperand ()))
3318+ return ;
3319+ for (auto it = std::next (load->getIterator ()), e = apply->getIterator ();
3320+ it != e; ++it) {
3321+ if (isa<LoadInst>(&(*it))) {
3322+ continue ;
33203323 }
3321- canForwardLoadToIndirect = true ;
3324+ return ;
33223325 }
3326+ canForwardLoadToIndirect = true ;
33233327 }();
33243328 IGF.getLoweredExplosion (arg, out);
33253329 if (canForwardLoadToIndirect) {
Original file line number Diff line number Diff line change 1+ // RUN: %target-swift-frontend %s -Osize -Xllvm -sil-disable-pass=lower-aggregate-instrs -disable-large-loadable-types-reg2mem -import-objc-header %S/Inputs/large_argument_result_c.h -emit-ir -o - 2>&1 | %FileCheck %s
2+
3+ // REQUIRES: PTRSIZE=64
4+ // REQUIRES: CPU=arm64 || CPU=arm64e
5+
6+ sil_stage lowered
7+
8+ import Builtin
9+ import Swift
10+ import SwiftShims
11+
12+ struct ContainingLargeThing {
13+ var y : large_thing
14+ var x : large_thing
15+ }
16+
17+ sil @pass_and_return : $@convention(c) (large_thing, large_thing) -> large_thing
18+
19+ // Make sure that we are not dropping the struct_element_addr projection on the
20+ // floor
21+
22+ // CHECK: define{{.*}} swiftcc void @test(ptr {{.*}} dereferenceable(256) %0)
23+ // CHECK: [[TMP:%.*]] = alloca %TSo11large_thinga
24+ // CHECK: [[PROJ_ADDR:%.*]] = getelementptr inbounds i8, ptr %0, i64 128
25+ // CHECK: [[VAL:%.*]] = load i64, ptr %.sroa.3.0..sroa_idx
26+ // CHECK: store i64 [[VAL]], ptr [[TMP]]
27+ sil @test : $@convention(thin) (@in ContainingLargeThing) -> () {
28+ bb0(%0 : $*ContainingLargeThing):
29+ %1 = alloc_stack $ContainingLargeThing
30+ copy_addr [take] %0 to [init] %1 : $*ContainingLargeThing
31+ %2 = struct_element_addr %1 : $*ContainingLargeThing, #ContainingLargeThing.x
32+ %3 = function_ref @pass_and_return : $@convention(c) (large_thing, large_thing) -> large_thing
33+ %4 = load %2 : $*large_thing // user: %9
34+ %5 = apply %3(%4, %4) : $@convention(c) (large_thing, large_thing) -> large_thing
35+ dealloc_stack %1 : $*ContainingLargeThing
36+ %6 = tuple()
37+ return %6 : $()
38+ }
You can’t perform that action at this time.
0 commit comments