Skip to content

Commit c421d23

Browse files
committed
Disable TempRValueOpt when there are users of the temp object preceding the copy
1 parent d62f9cd commit c421d23

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
@@ -546,9 +546,13 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
546546
// only users that modify memory are the copy_addr [initialization] and
547547
// destroy_addr.
548548
InstructionSetWithSize loadInsts(getFunction());
549+
// Set of tempObj users
550+
InstructionSet userSet(getFunction());
549551
for (auto *useOper : tempObj->getUses()) {
550552
SILInstruction *user = useOper->getUser();
551553

554+
userSet.insert(user);
555+
552556
if (user == copyInst)
553557
continue;
554558

@@ -575,6 +579,20 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
575579
return;
576580
}
577581

582+
// Check and return without optimization if we have any users of tempObj that
583+
// precede the copyInst.
584+
// This can happen with projections.
585+
// TODO: We can enable this case if we clone the projections at "load" uses
586+
587+
// All instructions in userSet are in the same block as copyInst. collectLoads
588+
// ensures of this.
589+
for (SILInstruction &inst : llvm::make_range(copyInst->getParent()->begin(),
590+
copyInst->getIterator())) {
591+
if (userSet.contains(&inst)) {
592+
return;
593+
}
594+
}
595+
578596
AliasAnalysis *aa = getPassManager()->getAnalysis<AliasAnalysis>(getFunction());
579597

580598
// 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
@@ -1821,3 +1821,21 @@ bb0:
18211821
dealloc_stack %src : $*MOS
18221822
return %instance_3 : $MOS
18231823
}
1824+
1825+
// CHECK-LABEL: sil [ossa] @dont_optimize_use_before_copy :
1826+
// CHECK: copy_addr
1827+
// CHECK-LABEL: } // end sil function 'dont_optimize_use_before_copy'
1828+
sil [ossa] @dont_optimize_use_before_copy : $@convention(thin) <B> (@in_guaranteed GS<B>, @inout GS<B>) -> () {
1829+
bb0(%0 : $*GS<B>, %1 : $*GS<B>):
1830+
%2 = alloc_stack $GS<B>
1831+
%3 = struct_element_addr %2 : $*GS<B>, #GS._value
1832+
copy_addr %1 to [init] %2 : $*GS<B>
1833+
%5 = load [trivial] %3 : $*Builtin.Int64
1834+
%6 = builtin "cmp_slt_Int64"(%5 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
1835+
copy_addr %2 to %1 : $*GS<B>
1836+
destroy_addr %2 : $*GS<B>
1837+
dealloc_stack %2 : $*GS<B>
1838+
%10 = tuple ()
1839+
return %10 : $()
1840+
}
1841+

0 commit comments

Comments
 (0)