[AMDGPU] Recompute EXEC liveness in SIWholeQuadMode::toExact (#200866)
This is required as stale liveness information can lead to an incorrect
optimization in `SIOptimizeExecMaskingPreRA`. For example, when `hi16`
is removed from EXEC, `optimizeElseBranch` produces an incorrect result
by removing `S_AND`.
This is caused by the following code:
```c++
SlotIndex StartIdx = LIS->getInstructionIndex(SaveExecMI);
SlotIndex EndIdx = LIS->getInstructionIndex(*AndExecMI);
for (MCRegUnit Unit : TRI->regunits(ExecReg)) {
LiveRange &RegUnit = LIS->getRegUnit(Unit);
if (RegUnit.find(StartIdx) != std::prev(RegUnit.find(EndIdx)))
return false;
}
```
When `hi16` is available there are two `RegUnit`s, one for `hi16` and
one for `lo16`. In the case of `wqm.ll` test it produces two live
ranges:
```
0: [320r,320d:3)[368r,368d:2)[736r,736d:4)[832r,832d:1)[944r,944d:0) 0@944r 1@832r 2@368r 3@320r 4@736r
1: [12r,12d:1)[320r,320d:5)[368r,368d:4)[736r,736d:6)[744r,744d:0)[832r,832d:3)[944r,944d:2) 0@744r 1@12r 2@944r 3@832r 4@368r 5@320r 6@736r
```
When `hi16` is removed there is only one range:
```
0: [320r,320d:3)[368r,368d:2)[736r,736d:4)[832r,832d:1)[944r,944d:0) 0@944r 1@832r 2@368r 3@320r 4@736r
```
If only the first range is considered the loop will finish without
returning false and continue to remove `S_AND`. It is because EXEC
register for `S_AND` added by `SIWholeQuadMode::toExact` is not in the
range. This is incorrect.
When `hi16` is present the incorrect behavior is masked by the second
live range coming from `hi16`, causing the loop to return. This can be
most likely explained by the fact that `hi16` is only computed after the
new `S_AND` was added so contains more up to date information. Removing
EXEC from `LiveIntervals` forces the live range to be recomputed.