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.