Bug 34792 - [avr] c++ worse than c compiler at 8-bit optimisations
Summary: [avr] c++ worse than c compiler at 8-bit optimisations
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.2.2
: P3 enhancement
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2008-01-15 09:03 UTC by David Brown
Modified: 2011-10-09 20:52 UTC (History)
3 users (show)

See Also:
Host:
Target: avr
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Brown 2008-01-15 09:03:32 UTC
As noted in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34791 , it is important on the avr to use 8-bit logic whenever possible.  In some cases, the c++ compiler will produce worse code than the c compiler for exactly the same source:

extern uint8_t data[64];

uint8_t bar2(uint8_t x, uint8_t y) {
	return data[(y ^ x) & 0x0f];
}

Compiled as c, this gives:

  61               	bar2:
  62               	/* prologue: frame size=0 */
  63               	/* prologue end (size=0) */
  64 0018 E62F      		mov r30,r22	 ;  y, y
  65 001a E827      		eor r30,r24	 ;  y, x
  66 001c F0E0      		ldi r31,lo8(0)	 ; ,
  67 001e EF70      		andi r30,lo8(15)	 ;  tmp46,
  68 0020 F070      		andi r31,hi8(15)	 ;  tmp46,
  69 0022 E050      		subi r30,lo8(-(data))	 ;  tmp46,
  70 0024 F040      		sbci r31,hi8(-(data))	 ;  tmp46,
  71 0026 8081      		ld r24,Z	 ;  tmp50, data
  72 0028 90E0      		ldi r25,lo8(0)	 ;  <result>,
  73               	/* epilogue: frame size=0 */
  74 002a 0895      		ret
  75               	/* epilogue end (size=1) */
  76               	/* function bar2 size 10 (9) */

Here there is only one extra instruction, the "andi r31, hi8(15)".  But compiling as c++, using the same -Os option, gives:


  61               	_Z4bar2hh:
  62               	/* prologue: frame size=0 */
  63               	/* prologue end (size=0) */
  64 0018 E62F      		mov r30,r22	 ;  y, y
  65 001a F0E0      		ldi r31,lo8(0)	 ;  y,
  66 001c 90E0      		ldi r25,lo8(0)	 ;  x,
  67 001e E827      		eor r30,r24	 ;  y, x
  68 0020 F927      		eor r31,r25	 ;  y, x
  69 0022 EF70      		andi r30,lo8(15)	 ;  y,
  70 0024 F070      		andi r31,hi8(15)	 ;  y,
  71 0026 E050      		subi r30,lo8(-(data))	 ;  y,
  72 0028 F040      		sbci r31,hi8(-(data))	 ;  y,
  73 002a 8081      		ld r24,Z	 ;  tmp51, data
  74 002c 90E0      		ldi r25,lo8(0)	 ;  <result>,
  75               	/* epilogue: frame size=0 */
  76 002e 0895      		ret
  77               	/* epilogue end (size=1) */
  78               	/* function uint8_t bar2(uint8_t, uint8_t) size 12 (11) */

This time, the compiler has clearly missed several opportunities to use 8-bit logic instead of 16-bit logic.
Comment 1 Georg-Johann Lay 2011-10-09 20:52:54 UTC
Cosed as fixed in 4.7.0. With -Os -mmcu=avr4 both avr-gcc and avr-g++ compile to the same, optimal code:

bar2:
	eor r22,r24
	andi r22,lo8(15)
	mov r30,r22
	ldi r31,lo8(0)
	subi r30,lo8(-(data))
	sbci r31,hi8(-(data))
	ld r24,Z
	ret

_Z4bar2hh:
	eor r22,r24
	andi r22,lo8(15)
	mov r30,r22
	ldi r31,lo8(0)
	subi r30,lo8(-(data))
	sbci r31,hi8(-(data))
	ld r24,Z
	ret