Skip to content

Commit dbda1bf

Browse files
committed
[AddressLowering] Don't end_borrow trivial args.
When loading an argument, first check whether its type is trivial. If so, produce a `load [trivial]`. Only then produce `load [take]`s or `load_borrow`s. Fixes an issue where values passed @in_guaranteed were `load [trivial]`'d and then `end_borrow`'d.
1 parent fc7a17b commit dbda1bf

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,12 +515,14 @@ static void convertDirectToIndirectFunctionArgs(AddressLoweringState &pass) {
515515
auto loc = SILValue(arg).getLoc();
516516
SILValue undefAddress = SILUndef::get(addrType, *pass.function);
517517
SingleValueInstruction *load;
518-
if (param.isConsumed()) {
519-
load = argBuilder.createTrivialLoadOr(loc, undefAddress,
520-
LoadOwnershipQualifier::Take);
518+
if (addrType.isTrivial(*pass.function)) {
519+
load = argBuilder.createLoad(loc, undefAddress,
520+
LoadOwnershipQualifier::Trivial);
521+
} else if (param.isConsumed()) {
522+
load = argBuilder.createLoad(loc, undefAddress,
523+
LoadOwnershipQualifier::Take);
521524
} else {
522-
load = cast<SingleValueInstruction>(
523-
argBuilder.emitLoadBorrowOperation(loc, undefAddress));
525+
load = argBuilder.createLoadBorrow(loc, undefAddress);
524526
for (SILInstruction *termInst : pass.exitingInsts) {
525527
pass.getBuilder(termInst->getIterator())
526528
.createEndBorrow(pass.genLoc(), load);

test/SILOptimizer/address_lowering.sil

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,28 @@ bb3(%15 : @owned $T):
10681068
return %15 : $T
10691069
}
10701070

1071+
// Verify that trivial arguments are loaded trivially and for which no
1072+
// end_borrows were created.
1073+
// CHECK-LABEL: sil [ossa] @f171_subtract_overflow : {{.*}} {
1074+
// CHECK: {{bb[0-9]+}}([[RETVAL:%[^,]+]] : $*Builtin.Int64, [[LHS_ADDR:%[^,]+]] : $*Builtin.Int64, [[RHS_ADDR:%[^,]+]] :
1075+
// CHECK: [[LHS:%[^,]+]] = load [trivial] [[LHS_ADDR]]
1076+
// CHECK: [[RHS:%[^,]+]] = load [trivial] [[RHS_ADDR]]
1077+
// CHECK: [[SUM_AND:%[^,]+]] = apply {{%[^,]+}}([[LHS]], [[RHS]])
1078+
// CHECK-NOT: end_borrow
1079+
// CHECK: ([[SUM:%[^,]+]], [[OVERFLOWED:%[^,]+]]) = destructure_tuple [[SUM_AND]]
1080+
// CHECK: store [[SUM]] to [trivial] [[RETVAL]]
1081+
// CHECK: return [[OVERFLOWED]]
1082+
// CHECK-LABEL: } // end sil function 'f171_subtract_overflow'
1083+
sil [ossa] @f171_subtract_overflow : $@convention(thin) (@in_guaranteed Int, @in_guaranteed Int) -> (@out Int, Bool) {
1084+
bb0(%0 : $Int, %1 : $Int):
1085+
%2 = function_ref @f171_subtract_overflow_callee : $@convention(method) (Int, Int) -> (Int, Bool)
1086+
%3 = apply %2(%0, %1) : $@convention(method) (Int, Int) -> (Int, Bool)
1087+
(%4, %5) = destructure_tuple %3 : $(Int, Bool)
1088+
%6 = tuple (%4 : $Int, %5 : $Bool)
1089+
return %6 : $(Int, Bool)
1090+
}
1091+
sil [ossa] @f171_subtract_overflow_callee : $@convention(method) (Int, Int) -> (Int, Bool)
1092+
10711093
// Test switching on a single opaque value.
10721094
// CHECK-LABEL: sil [ossa] @f210_testSwitchEnum : $@convention(method) <T> (@in Optional<T>, @inout T) -> () {
10731095
// CHECK: bb0(%0 : $*Optional<T>, %1 : $*T):

0 commit comments

Comments
 (0)