Skip to content

Commit 6475178

Browse files
committed
[sil-combine] When promoting an unchecked_take_enum_data_addr + load -> load + unchecked_enum_data, make sure to handle the non-trivialness of the operand and the trivialness of the result correctly.
1 parent d1c7890 commit 6475178

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,25 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#define DEBUG_TYPE "sil-combine"
14+
1415
#include "SILCombiner.h"
1516
#include "swift/Basic/STLExtras.h"
1617
#include "swift/SIL/DebugUtils.h"
1718
#include "swift/SIL/DynamicCasts.h"
1819
#include "swift/SIL/InstructionUtils.h"
1920
#include "swift/SIL/PatternMatch.h"
2021
#include "swift/SIL/Projection.h"
22+
#include "swift/SIL/SILBitfield.h"
2123
#include "swift/SIL/SILBuilder.h"
24+
#include "swift/SIL/SILInstruction.h"
2225
#include "swift/SIL/SILVisitor.h"
23-
#include "swift/SIL/SILBitfield.h"
2426
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
2527
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
2628
#include "swift/SILOptimizer/Analysis/ValueTracking.h"
29+
#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
2730
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
2831
#include "swift/SILOptimizer/Utils/Devirtualize.h"
2932
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
30-
#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
3133
#include "llvm/ADT/DenseMap.h"
3234
#include "llvm/ADT/SmallPtrSet.h"
3335
#include "llvm/ADT/SmallVector.h"
@@ -1764,10 +1766,22 @@ SILInstruction *SILCombiner::visitUncheckedTakeEnumDataAddrInst(
17641766
auto *svi = cast<SingleValueInstruction>(user);
17651767
SILValue newValue;
17661768
if (auto *oldLoad = dyn_cast<LoadInst>(svi)) {
1767-
auto newLoad = Builder.emitLoadValueOperation(
1768-
loc, enumAddr, oldLoad->getOwnershipQualifier());
1769-
newValue =
1770-
Builder.createUncheckedEnumData(loc, newLoad, enumElt, payloadType);
1769+
// If the old load is trivial and our enum addr is non-trivial, we need to
1770+
// use a load_borrow here. We know that the unchecked_enum_data will
1771+
// produce a trivial value meaning that we can just do a
1772+
// load_borrow/immediately end the lifetime here.
1773+
if (oldLoad->getOwnershipQualifier() == LoadOwnershipQualifier::Trivial &&
1774+
!enumAddr->getType().isTrivial(Builder.getFunction())) {
1775+
Builder.emitScopedBorrowOperation(loc, enumAddr, [&](SILValue newLoad) {
1776+
newValue = Builder.createUncheckedEnumData(loc, newLoad, enumElt,
1777+
payloadType);
1778+
});
1779+
} else {
1780+
auto newLoad = Builder.emitLoadValueOperation(
1781+
loc, enumAddr, oldLoad->getOwnershipQualifier());
1782+
newValue =
1783+
Builder.createUncheckedEnumData(loc, newLoad, enumElt, payloadType);
1784+
}
17711785
} else if (auto *lbi = cast<LoadBorrowInst>(svi)) {
17721786
auto newLoad = Builder.emitLoadBorrowOperation(loc, enumAddr);
17731787
for (auto ui = lbi->consuming_use_begin(), ue = lbi->consuming_use_end();

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ enum AddressOnlyEnum {
4141
case AddressOnly(Any)
4242
}
4343

44+
enum NonTrivialLoadableEnum {
45+
case noPayload
46+
case trivialPayload(Builtin.Int32)
47+
case nonTrivialPayload(Builtin.NativeObject)
48+
}
49+
4450
protocol FakeProtocol {
4551
func requirement()
4652
}
@@ -4800,3 +4806,21 @@ bb4:
48004806
destroy_value %cast : $Builtin.NativeObject
48014807
return %2 : $UInt
48024808
}
4809+
4810+
// CHECK-LABEL: sil [ossa] @unchecked_take_enum_data_addr_promotion_trivialpayload_nontrivial_enum : $@convention(thin) (@inout NonTrivialLoadableEnum) -> Builtin.Int32 {
4811+
// CHECK-NOT: unchecked_take_enum_data_addr
4812+
// CHECK: unchecked_enum_data
4813+
// CHECK-NOT: unchecked_take_enum_data_addr
4814+
// CHECK: } // end sil function 'unchecked_take_enum_data_addr_promotion_trivialpayload_nontrivial_enum'
4815+
sil [ossa] @unchecked_take_enum_data_addr_promotion_trivialpayload_nontrivial_enum : $@convention(thin) (@inout NonTrivialLoadableEnum) -> Builtin.Int32 {
4816+
bb0(%0 : $*NonTrivialLoadableEnum):
4817+
switch_enum_addr %0 : $*NonTrivialLoadableEnum, case #NonTrivialLoadableEnum.trivialPayload!enumelt: bb1, default bb2
4818+
4819+
bb1:
4820+
%2 = unchecked_take_enum_data_addr %0 : $*NonTrivialLoadableEnum, #NonTrivialLoadableEnum.trivialPayload!enumelt
4821+
%3 = load [trivial] %2 : $*Builtin.Int32
4822+
return %3 : $Builtin.Int32
4823+
4824+
bb2:
4825+
unreachable
4826+
}

0 commit comments

Comments
 (0)