On 9/25/26 1:24 AM, Stian Halseth wrote:
find_cond_trap emits the sequence from gen_cond_trap before cond_earliest.
On SPARC that sequence is a comparison followed by a trap on the condition
codes, but the branch it replaces need not read them: a cbcond tests
general registers, so a condition code set earlier can be live across
TEST_BB and read by a later branch, which then tests the wrong value.

The fix for PR126501 added noce_clobbers_live_cc_p for the same problem in
the noce paths.  Use it here too.

On sparc64 with -mcbcond this miscompiles a switch over a sparse enum whose
default arm is unreachable, which is why LLVM 23 does not build there.

Bootstrapped on sparc64-unknown-linux-gnu.  The C and C++ testsuites,
run against an otherwise identical unpatched tree, change only in the
new test, which fails without the patch and passes with it.

gcc/ChangeLog:

        PR rtl-optimization/127578
        * ifcvt.cc (find_cond_trap): Reject a sequence that clobbers a
        condition-code register live out of TEST_BB.

gcc/testsuite/ChangeLog:

        PR rtl-optimization/127578
        * lib/target-supports.exp (check_effective_target_cbcond_hw): New.
        * gcc.target/sparc/cbcond-trap-1.c: New test.
---
Changes since v1: reuse noce_clobbers_live_cc_p, the check that
end_ifcvt_sequence already makes, instead of adding a new liveness check
(following Jeff's review).  Tested on master; v1 was tested on 16.2.
Generally good.  Just one minor documentation thing to add.  When we add new target selectors like that, we document them in doc/sourcebuild.texi.   It's a step often missed and I should have caught it the first time through.  I'll push the V3 once you cobble together the doc bits.

Thanks,
jeff

Reply via email to