Bug 61055 - [avr] wrong test instruction after increment with -O1
Summary: [avr] wrong test instruction after increment with -O1
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 normal
Target Milestone: 4.9.1
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2014-05-04 13:49 UTC by Jan Waclawek
Modified: 2014-05-09 11:38 UTC (History)
1 user (show)

See Also:
Host:
Target: avr
Build:
Known to work: 4.7.4, 4.8.3, 4.9.1
Known to fail: 4.7.3, 4.8.2, 4.9.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Waclawek 2014-05-04 13:49:33 UTC
#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
Comment 1 Georg-Johann Lay 2014-05-05 18:18:30 UTC
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;
}
Comment 2 Georg-Johann Lay 2014-05-09 11:21:16 UTC
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
Comment 3 Georg-Johann Lay 2014-05-09 11:25:42 UTC
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
Comment 4 Georg-Johann Lay 2014-05-09 11:30:30 UTC
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
Comment 5 Georg-Johann Lay 2014-05-09 11:35:18 UTC
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
Comment 6 Georg-Johann Lay 2014-05-09 11:38:53 UTC
Fixed in 4.7.4, 4.8.3, 4.9.1 and trunk.