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.

Reply via email to