diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/DeadStoreElimination.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/DeadStoreElimination.swift index c7c4a1fa44986..ef7eb618e10f9 100644 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/DeadStoreElimination.swift +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/DeadStoreElimination.swift @@ -167,8 +167,15 @@ private extension StoreInst { var hasValidOwnershipForDeadStoreElimination: Bool { switch storeOwnership { - case .unqualified, .trivial: + case .unqualified: return true + case .trivial: + // Storing a trivial enum case in a non-trivial enum must be treated like a non-trivial + // init or assign, e.g. + // %1 = enum $Optional, #Optional.none!enumelt + // store %1 to [trivial] %0 // <- cannot delete this store! + // store %2 to [assign] %0 + return source.type.isTrivial(in: parentFunction) case .initialize, .assign: // In OSSA, non-trivial values cannot be dead-store eliminated because that could shrink // the lifetime of the original stored value (because it's not kept in memory anymore). diff --git a/test/SILOptimizer/dead_store_elim.sil b/test/SILOptimizer/dead_store_elim.sil index 4cd51cceba8f7..c55bc4992cc9e 100644 --- a/test/SILOptimizer/dead_store_elim.sil +++ b/test/SILOptimizer/dead_store_elim.sil @@ -1615,6 +1615,17 @@ bb0(%0 : $Int, %1 : @owned $IntAndFoo, %2 : $*IntAndFoo): return %r : $() } +// We don't support this, yet. +// Just check that we don't crash. +sil [ossa] @test_trivial_store_of_non_trivial_enum : $@convention(thin) (@owned Optional) -> @out Optional { +bb0(%0 : $*Optional, %1 : @owned $Optional): + %2 = enum $Optional, #Optional.none!enumelt + store %2 to [trivial] %0 + store %1 to [assign] %0 + %r = tuple () + return %r +} + // CHECK-LABEL: sil @test_bind_memory : // CHECK: store %0 // CHECK: end sil function 'test_bind_memory'