Fix CastOptimizer for guaranteed values while handling checked_cast_br (#37800)

Fixes rdar://77684045. The rdar is about a SILVerifier assert for SIL created by
cast optimizer, where a guaranteed op of checked_cast_br iis transformed to an op of
a phi argument without creating borrow scope.

Fix:
During cast optimization, when the direction of checked_cast_br can be determined statically,
replace the success/failure value in the destination block and create an unconditional branch
to the destination block. This is done only in OSSA, since we ban critical edges.
This commit is contained in:
Meghana Gupta
2021-06-16 16:03:23 -07:00
committed by GitHub
parent 970c030d19
commit 2d7e6bfc05
3 changed files with 119 additions and 7 deletions

View File

@@ -1004,6 +1004,7 @@ CastOptimizer::simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
auto TargetFormalType = dynamicCast.getTargetFormalType();
auto Loc = dynamicCast.getLocation();
auto *SuccessBB = dynamicCast.getSuccessBlock();
auto *FailureBB = dynamicCast.getFailureBlock();
auto Op = dynamicCast.getSource();
auto *F = dynamicCast.getFunction();
@@ -1016,10 +1017,13 @@ CastOptimizer::simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
SILBuilderWithScope Builder(Inst, builderContext);
if (Feasibility == DynamicCastFeasibility::WillFail) {
TinyPtrVector<SILValue> Args;
if (Builder.hasOwnership())
Args.push_back(Inst->getOperand());
auto *NewI = Builder.createBranch(Loc, dynamicCast.getFailureBlock(), Args);
auto *NewI = Builder.createBranch(Loc, FailureBB);
if (Builder.hasOwnership()) {
FailureBB->getArgument(0)->replaceAllUsesWith(Op);
FailureBB->eraseArgument(0);
SuccessBB->getArgument(0)->replaceAllUsesWithUndef();
SuccessBB->eraseArgument(0);
}
eraseInstAction(Inst);
willFailAction();
return NewI;
@@ -1063,7 +1067,19 @@ CastOptimizer::simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
CastedValue = Op;
}
auto *NewI = Builder.createBranch(Loc, SuccessBB, CastedValue);
BranchInst *NewI = nullptr;
if (Builder.hasOwnership()) {
NewI = Builder.createBranch(Loc, SuccessBB);
SuccessBB->getArgument(0)->replaceAllUsesWith(CastedValue);
SuccessBB->eraseArgument(0);
FailureBB->getArgument(0)->replaceAllUsesWithUndef();
FailureBB->eraseArgument(0);
}
else {
NewI = Builder.createBranch(Loc, SuccessBB, CastedValue);
}
eraseInstAction(Inst);
willSucceedAction();
return NewI;