Bug 33111 - Bad code generation with -O2 (ARM 7 architecture)
Summary: Bad code generation with -O2 (ARM 7 architecture)
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2007-08-19 07:49 UTC by Jaro Gress
Modified: 2009-05-22 14:51 UTC (History)
1 user (show)

See Also:
Host: cygwin gnuarm 4.2.0
Target: ARM7
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
This file does not compile correctly with -O2 (12.21 KB, application/octet-stream)
2007-08-19 22:22 UTC, Jaro Gress
Details
This is the working unoptimized assembly of uip.c (10.41 KB, application/octet-stream)
2007-08-19 22:24 UTC, Jaro Gress
Details
This is the nonworking optimized assembly of uip.c (11.51 KB, application/octet-stream)
2007-08-19 22:25 UTC, Jaro Gress
Details
Test of optimized comparison (-O2) (593 bytes, text/plain)
2007-09-09 20:44 UTC, Jaro Gress
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jaro Gress 2007-08-19 07:49:04 UTC
#define UIP_LLH_LEN 10000
#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define u8_t unsigned char
#define u16_t unsigned short
#define UIP_BUFSIZE 1000

typedef struct {
  /* IP header. */
  u8_t vhl,
    tos,          
    len[2],       
    ipid[2],        
    ipoffset[2],  
    ttl,          
    proto;     
  u16_t ipchksum;
  u16_t srcipaddr[2], 
    destipaddr[2];
  
  /* TCP header. */
  u16_t srcport,
    destport;
  u8_t seqno[4],  
    ackno[4],
    tcpoffset,
    flags,
    wnd[2];     
  u16_t tcpchksum;
  u8_t urgp[2];
  u8_t optdata[4];
} uip_tcpip_hdr;


u8_t uip_buf[UIP_BUFSIZE+2];
volatile u8_t uip_acc32[4];

int jaroslav;

int main(void)
{
	if((BUF->ackno[0] == uip_acc32[0]) &&
		(BUF->ackno[1] == uip_acc32[1]) &&
		(BUF->ackno[2] == uip_acc32[2]) &&
		(BUF->ackno[3] == uip_acc32[3]))
			jaroslav++;
	return 1;
}

	.file	"main.c"
	.text
	.align	2
	.global	main
	.type	main, %function
main:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	ldr	r0, .L10
	ldr	r1, .L10+4
	ldrb	r2, [r0, #28]	@ zero_extendqisi2
	ldrb	r3, [r1, #0]	@ zero_extendqisi2
	cmp	r2, r3
	@ lr needed for prologue
	beq	.L9
.L2:
	mov	r0, #1
	bx	lr
.L9:
	ldrb	r2, [r1, #1]	@ zero_extendqisi2
	ldrb	r3, [r0, #29]	@ zero_extendqisi2
	cmp	r3, r2
	bne	.L2
	ldrb	r2, [r1, #2]	@ zero_extendqisi2
	ldrb	r3, [r0, #30]	@ zero_extendqisi2
	cmp	r3, r2
	bne	.L2
	ldrb	r2, [r1, #3]	@ zero_extendqisi2
	ldrb	r3, [r0, #31]	@ zero_extendqisi2
	cmp	r3, r2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!I THINK CC's OF THIS COMPARE NEVER GET LOOKED AT
	ldreq	r2, .L10+8
	ldreq	r3, [r2, #0]
	addeq	r3, r3, #1
	streq	r3, [r2, #0]
	b	.L2
.L11:
	.align	2
.L10:
	.word	uip_buf+10000
	.word	uip_acc32
	.word	jaroslav
	.size	main, .-main
	.comm	uip_buf,1002,1
	.comm	uip_acc32,4,1
	.comm	jaroslav,4,4
	.ident	"GCC: (GNU) 4.2.0"
Comment 1 Andrew Pinski 2007-08-19 08:59:46 UTC
> #define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
Right there is an alias violation.
Comment 2 Jaro Gress 2007-08-19 13:23:49 UTC
The attached sample code does not illustrate the real problem.
Further investigation is required why the code works with -O0 
and does not work with -O2.
Comment 3 Jaro Gress 2007-08-19 22:22:59 UTC
Created attachment 14077 [details]
This file does not compile correctly with -O2
Comment 4 Jaro Gress 2007-08-19 22:24:10 UTC
Created attachment 14078 [details]
This is the working unoptimized assembly of uip.c
Comment 5 Jaro Gress 2007-08-19 22:25:14 UTC
Created attachment 14079 [details]
This is the nonworking optimized assembly of uip.c
Comment 6 Jaro Gress 2007-09-09 20:44:27 UTC
Created attachment 14180 [details]
Test of optimized comparison (-O2)

Comparison of four consecutive bytes gets optimized (-O2) as comparison of a word. The word address produced does not have the last two bits zero and the ARM7 processor either ignores them (LPC2000) or data aborts (SAM7).
Comment 7 Rask Ingemann Lambertsen 2007-09-09 21:08:03 UTC
Did you read comment #1?
Does -fno-strict-aliasing magically "fix" your code?
Comment 8 Jaro Gress 2007-09-09 22:23:48 UTC
Subject: RE:  Bad code generation with -O2 (ARM 7 architecture)

The -fno-strict-aliasing does not fix the unaligned access.

-----Original Message-----
From: rask at gcc dot gnu dot org [mailto:gcc-bugzilla@gcc.gnu.org] 
Sent: Monday, 10 September 2007 07:08
To: gressau@optusnet.com.au
Subject: [Bug c/33111] Bad code generation with -O2 (ARM 7 architecture)



------- Comment #7 from rask at gcc dot gnu dot org  2007-09-09 21:08
-------
Did you read comment #1?
Does -fno-strict-aliasing magically "fix" your code?


Comment 9 Andrew Pinski 2008-12-27 06:53:36 UTC
(In reply to comment #1)
> > #define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
> Right there is an alias violation.

More than that this is an alignment violation.  

Comment 10 Richard Earnshaw 2009-05-22 14:51:40 UTC
The ARM7 does not support unaligned accesses in the way that C programmers normally expect (even if it doesn't fault them in the MMU then it still won't fetch what you might expect -- see the CPU manuals for details).

As of ARM11 the rules were changed, but that's a different story...