Skip to content

Commit 332b405

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

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,13 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
547547
// only users that modify memory are the copy_addr [initialization] and
548548
// destroy_addr.
549549
InstructionSetWithSize loadInsts(getFunction());
550+
// Set of tempObj users
551+
InstructionSet userSet(getFunction());
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,20 @@ 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.
585+
// This can happen with projections.
586+
// TODO: We can enable this case if we clone the projections at "load" uses
587+
588+
// All instructions in userSet are in the same block as copyInst. collectLoads
589+
// ensures of this.
590+
for (SILInstruction &inst : llvm::make_range(copyInst->getParent()->begin(),
591+
copyInst->getIterator())) {
592+
if (userSet.contains(&inst)) {
593+
return;
594+
}
595+
}
596+
579597
AliasAnalysis *aa = getPassManager()->getAnalysis<AliasAnalysis>(getFunction());
580598

581599
// 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)