[PowerPC] Don't let optimizeCompareInstr define CR0 while it is still live (#220999)
This replaces the compare-against-zero in
`PPCInstrInfo::optimizeCompareInstr` with the record form of the
instruction defining the compared register only when CR0 is dead at that
point, checked with `MachineBasicBlock::computeRegisterLiveness`
scanning to the end of the block.
Fixes #220996.
## Why
The conversion makes `MI` define CR0. CR0 can still be live there: the
`ANDI_rec_1_{EQ,GT}_BIT` pseudo expansion emits `ANDI_rec` followed by
COPYs of `$cr0eq`/`$cr0gt`, and nothing keeps those copies adjacent to
their `andi.` once other instructions are scheduled in between. A later
compare candidate sitting between an `andi.` and one of its copies gets
converted, clobbers CR0, and the copy then reads the wrong value — the
two flag tests swap conditions.
The existing backward safety scan cannot see this: it only covers the
range between the candidate and the compare's first use (the stale
reader sits after that), and it is skipped entirely when `noSub` is set,
i.e. for every 32-bit compare on PPC64. Un-skipping that scan alone does
not fix the case from the issue (verified); the forward liveness check
does.
## Verification
PowerPC-only builds with assertions on (release/19.x 19.1.7 and main
d8217655d):
- New MIR test `llvm/test/CodeGen/PowerPC/cmp-opt-cr0-live.mir`: fails
on stock `llc` — the conversion happens and `-verify-machineinstrs`
reports `Bad machine code: Using an undefined physical register` for the
stale `%6:crbitrc = COPY $cr0gt` — and passes with this patch.
- `ninja check-llvm-codegen-powerpc`-equivalent (`llvm-lit
test/CodeGen/PowerPC`): identical pass/fail sets with and without the
patch on both bases, apart from the new test. (In my PowerPC-only
environment a handful of tests that need a native default target or
unbuilt utilities fail identically with and without the patch.)
- The C reproducer from the issue and the real-world victim
(libmongocrypt `unicode_fold()`, the case/diacritic folding for MongoDB
Queryable Encryption text search on ppc64le), compiled through the
patched `llc` for `powerpc64le` and run under `qemu-ppc64le`: correct
output.
- The peephole still fires where it is safe: in `unicode_fold`, 2 of the
3 record-form `andi.` conversions remain, only the unsafe one is
dropped.
---
*Disclosure (per the LLVM developer policy on AI-assisted
contributions): the initial analysis, reproduction, and drafting of this
change were done with the assistance of an AI coding tool. I have
reproduced the failure, reviewed every line of the patch, re-run the
verification myself, and am submitting this as the responsible author.*
---------
Co-authored-by: Amy Kwan <amy.kwan1@ibm.com>