https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120375

            Bug ID: 120375
           Summary: arc: -mcpu=em x >> 31 clobber of CC isn't respected
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: keithp at keithp dot com
  Target Milestone: ---

Created attachment 61486
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61486&action=edit
foo.c source demonstrating arc nobs condition code bug

Commit 3ceb109fcb045de9d78b650112399bbb7df78cdc improved code generated for
shift operations on targets without a barrel shifter (-mcpu=em). 

For unsigned right shift by 31, this new code generates:

    add.f 0,r0,r0
    rlc   r0,0

This clobbers the condition codes, but the RTL matched for this operation
doesn't include (clobber (reg:CC CC_REG)). If CC is used again, it will contain
this new value.

The attached test case is built with:

    $ gcc -mcpu=em -O2 -S foo.c -fverbose-asm -fno-delayed-branch

(-fno-delayed-branch makes the asm easier to read, but the bug still occurs
without it).

The relevant assembly is here:

# foo.c:15:     if (mag > 0x7f800000)
        brgt    r3,2139095040,.L8       #, _13,,
# foo.c:12:     int sign = (x >> 31) & 1;
        add.f   0,r0,r0 # _9, _9
        rlc     r0,0            # _2
# foo.c:17:     if (mag == 0x7f800000)
        beq_s   .L9     #,

Note that the first compare-and-branch is compressed to a single instruction
which doesn't affect the flags. I think this is because that conversion is done
*after* the shift operation is split into add.f; rlc and the condition codes
are marked as clobbered.

I tried adding a clobber constraint to the "<insn>si3_nobs" insn in arc.md but
that causes the compiler to fail to match this insn.

Reply via email to