char >> 7 is compiled to LSL reg SBC reg,reg
which leaves cc0 in a mess because Z-flag is not set by SBC, it's propagated from LSL. Patch as obvious, new testcase pass and contains *cmpqi. Ok to commit? Johann gcc/ PR target/39633 * config/avr/avr.c (notice_update_cc): For ashiftrt:QI, only offsets 1..5 set cc0 in a usable way. testsuite/ * gcc.target/avr/torture/pr39633.c: New test case.
Index: testsuite/gcc.target/avr/torture/pr39633.c =================================================================== --- testsuite/gcc.target/avr/torture/pr39633.c (revision 0) +++ testsuite/gcc.target/avr/torture/pr39633.c (revision 0) @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +#include <stdlib.h> + +char c = 42; + +void __attribute__((noinline,noclone)) +pr39633 (char a) +{ + a >>= 7; + if (a) + c = a; +} + +int main() +{ + pr39633 (6); + + if (c != 42) + abort(); + + exit(0); + + return 0; +} Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 176136) +++ config/avr/avr.c (working copy) @@ -1479,9 +1479,8 @@ notice_update_cc (rtx body ATTRIBUTE_UNU { rtx x = XEXP (src, 1); - if (GET_CODE (x) == CONST_INT - && INTVAL (x) > 0 - && INTVAL (x) != 6) + if (CONST_INT_P (x) + && IN_RANGE (INTVAL (x), 1, 5)) { cc_status.value1 = SET_DEST (set); cc_status.flags |= CC_OVERFLOW_UNUSABLE;