llvm-project
8ed9dd99 - [PowerPC] Don't let optimizeCompareInstr define CR0 while it is still live (#220999)

Commit
16 days ago
[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>
Author
Parents
Loading