When implementing memset's today we often see this pattern:
$x0 = MOV 0xXYXYXYXYXYXYXYXY
store $x0, ...
$w1 = MOV 0xXYXYXYXY
store $w1, ...
We first create a 64bit constant in a 64bit register with all bytes the
same and then create a 32bit constant with all bytes the same in a 32bit
register. In many targets we could just access the lower part of the
64bit register instead.
- Ideally this would be handled by the ConstantHoist pass but it runs too early when memset isn't expanded yet.
- The memset expansion code already had this optimization implemented, however it didn't work as DAGCombiner would fold "trunc(bigconstant)" back to "smallconstant".
- This patch makes the memset expansion mark the constant as Opaque and stop DAGCombiner from constant folding in this situation. (Similar to how ConstantHoisting marks things as Opaque to avoid folding ADD/SUB/etc.)
rdar://44153998
This code changes because ConstantHoisting touches the constants here, and the less aggressive behavior of trunc(OpaqueConstant)" somehow makes DAGCombiner realizes this whole expression being 0 now which it didn't do before. The testcase unfortunately doesn't have enough information to figure out how an equivalent tests would look like that wouldn't constant fold to zero. So this probably has to stay like this...