Allow kotlin.jvm.internal.Intrinsics#areEqual for boxed values.
Rewrite to primitive equality.
NB we can't do that for Float and Double, because java.lang.Float#equals
and java.lang.Double#equals behave differently from primitive equality comparisons.
CHECKCAST is redundant if the corresponding static type exactly matches the target type.
CHECKCAST instructions to-be-reified should not be eliminated.
KT-14811 Unnecessary checkcast generated in parameterized functions
KT-14963 unnecessary checkcast java/lang/Object
Previous version of the boxing/unboxing analysis treated merging boxed and non-boxed values as a hazard.
If such merged values are not used (e.g., early return + local variables reused in inlined calls),
corresponding boxing/unboxing operations still can be optimized out.
All information related to boxed value usage by instructions is moved to 'BoxedValueDescriptor'.
Introduce "tainted" (and "clean") boxed values, with the following rules:
merge(B, B) = B, if unboxed types are compatible,
T, otherwise
merge(B, X) = T
merge(T, X) = T
where
X is a non-boxed value,
B is a "clean" boxed value,
T is a "tainted" boxed value.
Postpone decision about value merge hazards until a "tainted" value is used.
See testData/simpleUnitializedMerge.kt
On exit from `if` we merge value in variable with slot 1 (x):
- from `if` body we get BoxedBasicValue
- from outer block we get UNITIALIZED_VALUE
So we just suppose `x` is unitialized after `if`
and there's no need to mark BoxedValue as unsafe to remove
because it's anyway can't be used after `if`
#KT-6842 Fixed