https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127578
Bug ID: 127578
Summary: [sparc] wrong code at -O2 with -mcbcond:
find_cond_trap clobbers a live %icc
Product: gcc
Version: 16.2.0
URL: https://github.com/sparclinux/issues/issues/98
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: stian at itx dot no
Target Milestone: ---
Target: sparc64-unknown-linux-gnu
Attached testcase traps on a valid switch value:
$ gcc -O2 -mcpu=niagara4 pr-reproducer.c -o r && ./r
Illegal instruction
$ gcc -O2 -mcpu=ultrasparc pr-reproducer.c -o r && ./r ; echo $?
0
Needs -O2 and -mcbcond (niagara4/niagara7/m8). -mno-cbcond or
-fno-if-conversion avoids it.
find_cond_trap (ifcvt.cc) emits the compare+trap from gen_cond_trap before
cond_earliest without checking what it clobbers. With -mcbcond the cbcond
jump does not read %icc, so an %icc set in an earlier block is live across
the block and used by a later branch; the inserted compare overwrites it and
the conditional trap then tests the wrong comparison:
cmp %g1, 0x20
bgu,pn %icc, .Lhi
cmp %g1, 0 ! clobbers %icc
tgu 5 ! wants %g1 >u 32, now tests %g1 >u 0
Same code in 14.x and master.
Patch attached; bootstrapped and regtested on sparc64-unknown-linux-gnu, no
changes in check-gcc.