#include <stdint.h> extern int16_t foo(int16_t, int16_t); int main(void) { int16_t x = 0; int16_t y = 0; uint8_t c = 0x20; do { x = foo(x, y); y = foo(y, c); c++; if (c >= 0x80) c = 0x20; } while (y > 0); while(1); } c:\tmp>avr-gcc -mmcu=avr2 -O1 -S ca.c -o ca.s c:\tmp>avr-gcc --version avr-gcc (AVR_8_bit_GNU_Toolchain_3.4.3_1072) 4.8.1 The sequence c++; if (c >= 0x80) c = 0x20; compiles into inc r15 brge .L2 set clr r15 bld r15,5 .L2: which fails when c == 0x7f, as brge does jump after the increment. Jan Waclawek
I see similar code with -fno-peephole2 What about the following that is also turned into a signed test and generates an ADIW / BRGE sequence. This is also wrong then when we start with 0x7ffe? uint16_t fun_adiw (uint16_t c) { c += 2; if (c >= 0x8000) c = 0x20; return c; }
Author: gjl Date: Fri May 9 11:20:43 2014 New Revision: 210267 URL: http://gcc.gnu.org/viewcvs?rev=210267&root=gcc&view=rev Log: gcc/config/avr PR target/61055 * config/avr/avr.md (cc): Add new attribute set_vzn. (addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]: Set cc insn attribute to set_vzn instead of set_zn for alternatives with INC, DEC or NEG. * config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN. (avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN. INC, DEC and ADD+ADC set cc0 to CC_CLOBBER. gcc/testsuite/ PR target/61055 * gcc.target/avr/torture/pr61055.c: New test. Added: trunk/gcc/testsuite/gcc.target/avr/torture/pr61055.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/avr/avr.c trunk/gcc/config/avr/avr.md trunk/gcc/testsuite/ChangeLog
Author: gjl Date: Fri May 9 11:25:11 2014 New Revision: 210268 URL: http://gcc.gnu.org/viewcvs?rev=210268&root=gcc&view=rev Log: gcc/config/avr Backport from 2014-05-09 trunk r210267 PR target/61055 * config/avr/avr.md (cc): Add new attribute set_vzn. (addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]: Set cc insn attribute to set_vzn instead of set_zn for alternatives with INC, DEC or NEG. * config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN. (avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN. INC, DEC and ADD+ADC set cc0 to CC_CLOBBER. gcc/testsuite/ Backport from 2014-05-09 trunk r210267 PR target/61055 * gcc.target/avr/torture/pr61055.c: New test. Added: branches/gcc-4_9-branch/gcc/testsuite/gcc.target/avr/torture/pr61055.c Modified: branches/gcc-4_9-branch/gcc/ChangeLog branches/gcc-4_9-branch/gcc/config/avr/avr.c branches/gcc-4_9-branch/gcc/config/avr/avr.md branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
Author: gjl Date: Fri May 9 11:29:58 2014 New Revision: 210269 URL: http://gcc.gnu.org/viewcvs?rev=210269&root=gcc&view=rev Log: gcc/ Backport from 2014-05-09 trunk r210267 PR target/61055 * config/avr/avr.md (cc): Add new attribute set_vzn. (addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]: Set cc insn attribute to set_vzn instead of set_zn for alternatives with INC, DEC or NEG. * config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN. (avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN. INC, DEC and ADD+ADC set cc0 to CC_CLOBBER. gcc/testsuite/ Backport from 2014-05-09 trunk r210267 PR target/61055 * gcc.target/avr/torture/pr61055.c: New test. Added: branches/gcc-4_8-branch/gcc/testsuite/gcc.target/avr/torture/pr61055.c Modified: branches/gcc-4_8-branch/gcc/ChangeLog branches/gcc-4_8-branch/gcc/config/avr/avr.c branches/gcc-4_8-branch/gcc/config/avr/avr.md branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Author: gjl Date: Fri May 9 11:34:46 2014 New Revision: 210270 URL: http://gcc.gnu.org/viewcvs?rev=210270&root=gcc&view=rev Log: gcc/ Backport from 2014-05-09 trunk r210267 PR target/61055 * config/avr/avr.md (cc): Add new attribute set_vzn. (addqi3, negqi2) [cc]: Set cc insn attribute to set_vzn instead of set_zn for alternatives with INC, DEC or NEG. * config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN. (avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN. INC, DEC set cc0 to CC_CLOBBER. gcc/testsuite/ Backport from 2014-05-09 trunk r210267 PR target/61055 * gcc.target/avr/torture/pr61055.c: New test. Added: branches/gcc-4_7-branch/gcc/testsuite/gcc.target/avr/torture/pr61055.c Modified: branches/gcc-4_7-branch/gcc/ChangeLog branches/gcc-4_7-branch/gcc/config/avr/avr.c branches/gcc-4_7-branch/gcc/config/avr/avr.md branches/gcc-4_7-branch/gcc/testsuite/ChangeLog
Fixed in 4.7.4, 4.8.3, 4.9.1 and trunk.