Make CopyForwarding more conservative about shrinking lifetimes.
Fixes <rdar://problem/39209102> [SR-7354]: Swift 4.1 Regression: EXC_BAD_ACCESS for Optimized Builds in Xcode 9.3
Commentary:
The underlying problem is that CopyForwarding is an inherently
dangerous pass by design that has been waiting for the SIL
representation to evolve to the point where it can be rewritten.
The regressions was caused by PredictableMemOps failing to preserve
normal patterns of ownership. When it forwards loads, it implicitly
extends the lifetime of stored value
store %val to %addr
...
retain %val
...
destroy_addr %addr
CopyForwarding already tried to detect such violations of ownership
rules and normally bypasses destroy hoisting in those cases. In this
case, it fails to detect the problem because PredictableMemOps has
already erased the load, so there's no evidence of the value's
lifetime being extended.
It might have been nice if PredictableMemOps had transformed the
retain %val into a retain %addr. However, for the immediate fix, we
don't want to change any existing behavior other than suppressing
optimization. In the long term, CopyForwarding does not really make
sense without SemanticSIL+SILOwnership and should be totally rewritten
and greatly simplified at that point.