On 9/23/26 2:10 PM, Stian Halseth wrote:
find_cond_trap emits the sequence returned by gen_cond_trap before
cond_earliest without checking what it sets. On targets where a
conditional trap is a comparison feeding a trap insn the sequence sets the
condition code register, which need not be dead there: with SPARC -mcbcond
the jump does not read the CC, so a CC value set in an earlier block is
live across TEST_BB and used by a later branch. Overwriting it silently
changes what that branch tests.
On sparc64 this miscompiles a switch over a sparse enum whose default arm
is unreachable. It is why LLVM 23 does not build on sparc64: clang-tblgen
takes the unreachable arm for a valid enumerator in
clang::RISCV::RVVType::applyBasicType(), and with that worked around the
resulting libLLVM is miscompiled in the same way and clang then traps in
llvm::TruncInstCombine::getReducedOperand().
Bootstrapped on sparc64-unknown-linux-gnu. check-gcc against an otherwise
identical unpatched tree is unchanged. LLVM 23.1.1, which does not
otherwise build on this target, builds with the patch applied. The new
test fails without the patch and passes with it.
gcc/ChangeLog:
PR rtl-optimization/127578
* ifcvt.cc (find_cond_trap): Do not convert when the generated
sequence sets a register that is live before cond_earliest.
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.
Something doesn't seem right here. Other targets that use condition
code registers haven't stumbled over this problem yet, so what is it
about sparc that makes it special relative to say the x86?
For most if-converted code we end up calling end_ifcvt_sequence which
(among other things) verifies that each generated insn in the sequence
can be recognized and does not clobber CC. Maybe we need to be doing
something similar for conditional traps. If so, it'd ideally be
refactored rather than duplicated.
Jeff