Skip to content

Commit d84bab0

Browse files
authored
Merge pull request #33839 from eeckstein/improve-cast-optimizer
SimplifyCFG: Handle checked_cast_addr_br with consumption kind copy_on_success
2 parents 6aebda5 + 0ec6eb2 commit d84bab0

File tree

3 files changed

+104
-8
lines changed

3 files changed

+104
-8
lines changed

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -918,25 +918,32 @@ SILInstruction *CastOptimizer::simplifyCheckedCastAddrBranchInst(
918918
return nullptr;
919919
}
920920

921-
// For CopyOnSuccess casts, we could insert an explicit copy here, but this
922-
// case does not happen in practice.
923-
//
924921
// Both TakeOnSuccess and TakeAlways can be reduced to an
925922
// UnconditionalCheckedCast, since the failure path is irrelevant.
923+
AllocStackInst *copiedSrc = nullptr;
926924
switch (Inst->getConsumptionKind()) {
927925
case CastConsumptionKind::BorrowAlways:
928926
llvm_unreachable("checked_cast_addr_br never has BorrowAlways");
929927
case CastConsumptionKind::CopyOnSuccess:
930-
return nullptr;
928+
if (!Src->getType().isTrivial(*BB->getParent())) {
929+
copiedSrc = Builder.createAllocStack(Loc, Src->getType());
930+
Builder.createCopyAddr(Loc, Src, copiedSrc, IsNotTake, IsInitialization);
931+
Src = copiedSrc;
932+
}
933+
break;
931934
case CastConsumptionKind::TakeAlways:
932935
case CastConsumptionKind::TakeOnSuccess:
933936
break;
934937
}
935938

936-
if (!emitSuccessfulIndirectUnconditionalCast(Builder, Loc, dynamicCast)) {
937-
// No optimization was possible.
938-
return nullptr;
939-
}
939+
bool result = emitSuccessfulIndirectUnconditionalCast(
940+
Builder, Builder.getModule().getSwiftModule(), Loc, Src,
941+
Inst->getSourceFormalType(), Dest, Inst->getTargetFormalType(), Inst);
942+
(void)result;
943+
assert(result && "emit cannot fail for an checked_cast_addr_br");
944+
945+
if (copiedSrc)
946+
Builder.createDeallocStack(Loc, copiedSrc);
940947
eraseInstAction(Inst);
941948
}
942949
SILInstruction *NewI = &BB->back();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-frontend -O -module-name=test -emit-sil %s | %FileCheck %s
2+
3+
func convert<
4+
T: BinaryFloatingPoint, U: BinaryFloatingPoint
5+
>(_ value: T, to: U.Type) -> U {
6+
U(value)
7+
}
8+
9+
// Check that the follwing functions can be optimized to no-ops.
10+
11+
// CHECK-LABEL: sil @$s4test0A6DoubleyS2dF
12+
// CHECK: return %0
13+
// CHECK: } // end sil function '$s4test0A6DoubleyS2dF'
14+
public func testDouble(_ x: Double) -> Double {
15+
return convert(x, to: Double.self)
16+
}
17+
18+
// CHECK-LABEL: sil @$s4test0A5FloatyS2fF
19+
// CHECK: return %0
20+
// CHECK: } // end sil function '$s4test0A5FloatyS2fF'
21+
public func testFloat(_ x: Float) -> Float {
22+
return convert(x, to: Float.self)
23+
}
24+
25+

test/SILOptimizer/simplify_cfg.sil

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,6 +2980,70 @@ bb3:
29802980
br bb2(%z : $Builtin.Int1)
29812981
}
29822982

2983+
// CHECK-LABEL: sil @trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed Int, @guaranteed Int) -> @owned Int
2984+
// CHECK: [[SRC:%.*]] = alloc_stack $Int
2985+
// CHECK: store %0 to [[SRC]]
2986+
// CHECK: [[DST:%.*]] = alloc_stack $Int
2987+
// CHECK: [[LD1:%.*]] = load [[SRC]]
2988+
// CHECK: store [[LD1]] to [[DST]]
2989+
// CHECK: [[LD2:%.*]] = load [[DST]]
2990+
// CHECK: return [[LD2]]
2991+
// CHECK: } // end sil function 'trivial_checked_cast_addr_br'
2992+
sil @trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed Int, @guaranteed Int) -> @owned Int {
2993+
bb0(%0 : $Int, %1 : $Int):
2994+
%6 = alloc_stack $Int
2995+
store %0 to %6 : $*Int
2996+
%8 = alloc_stack $Int
2997+
checked_cast_addr_br copy_on_success Int in %6 : $*Int to Int in %8 : $*Int, bb1, bb2
2998+
2999+
bb1:
3000+
%10 = load %8 : $*Int
3001+
dealloc_stack %8 : $*Int
3002+
br bb3(%10 : $Int)
3003+
3004+
bb2:
3005+
retain_value %1: $Int
3006+
dealloc_stack %8 : $*Int
3007+
br bb3(%1 : $Int)
3008+
3009+
bb3(%11 : $Int):
3010+
dealloc_stack %6 : $*Int
3011+
return %11 : $Int
3012+
}
3013+
3014+
// CHECK-LABEL: sil @non_trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed String, @guaranteed String) -> @owned String
3015+
// CHECK: [[SRC:%.*]] = alloc_stack $String
3016+
// CHECK: store %0 to [[SRC]]
3017+
// CHECK: [[DST:%.*]] = alloc_stack $String
3018+
// CHECK: [[TEMP:%.*]] = alloc_stack $String
3019+
// CHECK: copy_addr [[SRC]] to [initialization] [[TEMP]]
3020+
// CHECK: [[LD1:%.*]] = load [[TEMP]]
3021+
// CHECK: store [[LD1]] to [[DST]]
3022+
// CHECK: [[LD2:%.*]] = load [[DST]]
3023+
// CHECK: return [[LD2]]
3024+
// CHECK: } // end sil function 'non_trivial_checked_cast_addr_br'
3025+
sil @non_trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed String, @guaranteed String) -> @owned String {
3026+
bb0(%0 : $String, %1 : $String):
3027+
%6 = alloc_stack $String
3028+
store %0 to %6 : $*String
3029+
%8 = alloc_stack $String
3030+
checked_cast_addr_br copy_on_success String in %6 : $*String to String in %8 : $*String, bb1, bb2
3031+
3032+
bb1:
3033+
%10 = load %8 : $*String
3034+
dealloc_stack %8 : $*String
3035+
br bb3(%10 : $String)
3036+
3037+
bb2:
3038+
retain_value %1: $String
3039+
dealloc_stack %8 : $*String
3040+
br bb3(%1 : $String)
3041+
3042+
bb3(%11 : $String):
3043+
dealloc_stack %6 : $*String
3044+
return %11 : $String
3045+
}
3046+
29833047
// CHECK-LABEL: sil @dont_hang
29843048
// CHECK: bb6:
29853049
// CHECK: integer_literal $Builtin.Int64, 1

0 commit comments

Comments
 (0)