Skip to content

Commit 5f682ae

Browse files
committed
Disable TempRValueOpt when there are users of the temp object preceding the copy
1 parent 8ccabbd commit 5f682ae

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
542542
// re-initialization of the source.
543543
bool needFinalDeinit = copyInst->isTakeOfSrc();
544544

545+
SmallPtrSet<SILInstruction *, 4> userSet;
546+
545547
// Scan all uses of the temporary storage (tempObj) to verify they all refer
546548
// to the value initialized by this copy. It is sufficient to check that the
547549
// only users that modify memory are the copy_addr [initialization] and
@@ -550,6 +552,8 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
550552
for (auto *useOper : tempObj->getUses()) {
551553
SILInstruction *user = useOper->getUser();
552554

555+
userSet.insert(user);
556+
553557
if (user == copyInst)
554558
continue;
555559

@@ -576,6 +580,15 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
576580
return;
577581
}
578582

583+
// Check and return without optimization if we have any users of tempObj that
584+
// precede the copyInst. This can happen with projections.
585+
for (SILInstruction &inst : llvm::make_range(copyInst->getParent()->begin(),
586+
copyInst->getIterator())) {
587+
if (userSet.count(&inst)) {
588+
return;
589+
}
590+
}
591+
579592
AliasAnalysis *aa = getPassManager()->getAnalysis<AliasAnalysis>(getFunction());
580593

581594
// Check if the source is modified within the lifetime of the temporary.

test/SILOptimizer/temp_rvalue_opt_ossa.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,3 +1847,21 @@ bb0:
18471847
dealloc_stack %src : $*MOS
18481848
return %instance_3 : $MOS
18491849
}
1850+
1851+
// CHECK-LABEL: sil [ossa] @dont_optimize_use_before_copy :
1852+
// CHECK: copy_addr
1853+
// CHECK_LABEL: } // end sil function 'dont_optimize_use_before_copy'
1854+
sil [ossa] @dont_optimize_use_before_copy : $@convention(thin) <B> (@in_guaranteed GS<B>, @inout GS<B>) -> () {
1855+
bb0(%0 : $*GS<B>, %1 : $*GS<B>):
1856+
%2 = alloc_stack $GS<B>
1857+
%3 = struct_element_addr %2 : $*GS<B>, #GS._value
1858+
copy_addr %1 to [init] %2 : $*GS<B>
1859+
%5 = load [trivial] %3 : $*Builtin.Int64
1860+
%6 = builtin "cmp_slt_Int64"(%5 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
1861+
copy_addr %2 to %1 : $*GS<B>
1862+
destroy_addr %2 : $*GS<B>
1863+
dealloc_stack %2 : $*GS<B>
1864+
%10 = tuple ()
1865+
return %10 : $()
1866+
}
1867+

0 commit comments

Comments
 (0)