public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* c/7500: invalid assemly output with -O2 flag
@ 2002-08-05  9:36 rgohita
  0 siblings, 0 replies; only message in thread
From: rgohita @ 2002-08-05  9:36 UTC (permalink / raw)
  To: gcc-gnats


>Number:         7500
>Category:       c
>Synopsis:       invalid assemly output with -O2 flag
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 05 09:36:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Igor Mikhailov
>Release:        2.95.2 - 3.1
>Organization:
>Environment:
Linux Redhat 6.2, gcc cross-compiler for ARM
>Description:
This bug exists in gcc compilers from at least 2.95.2 to 3.1

The compilers were build for different ARM machines, with elf or coff format, with the same result.

The flags used for compilation were: -Wall -mcpu=<I've tried several, arm7tdmi is one of them>

It builds invalid code in case of -O2 optimization flag, however with -O1 flag the built code is completely Ok.

In the attached file, the wrong code is generated for is_same_ops() function. Normally, it should return 0, since the a and b variables are not the same according to the conditions. However, with the -O2 flag the function 
is_same_ops returns 1.
>How-To-Repeat:
arm-gcc -O[1,2] -Wall -c assembly_bug.c 

I'd like to show you the assembly code of the function, first for the -02 
flag, next for the -01:

Invalid code:
00000000 <_is_same_ops>:
   0:	e1a0c00d 	mov	r12, sp
   4:	e92dd800 	stmdb	sp!, {r11, r12, lr, pc}
   8:	e24cb004 	sub	r11, r12, #4	; 0x4
   c:	e3a0c000 	mov	r12, #0	; 0x0
  10:	e5902004 	ldr	r2, [r0, #4]
  14:	e5913004 	ldr	r3, [r1, #4]
  18:	e1520003 	cmp	r2, r3
  1c:	1a000008 	bne	44 <L3>
  20:	e5913000 	ldr	r3, [r1]
  24:	e5902000 	ldr	r2, [r0]
  28:	e3130007 	tst	r3, #7	; 0x7
  2c:	e2122007 	ands	r2, r2, #7	; 0x7
  30:	13a02001 	movne	r2, #1	; 0x1
  34:	13a01000 	movne	r1, #0	; 0x0
  38:	03a01001 	moveq	r1, #1	; 0x1
  3c:	e052c001 	subs	r12, r2, r1
  40:	13a0c001 	movne	r12, #1	; 0x1

Valid code
00000000 <_is_same_ops>:
   0:	e1a0c00d 	mov	r12, sp
   4:	e92dd800 	stmdb	sp!, {r11, r12, lr, pc}
   8:	e24cb004 	sub	r11, r12, #4	; 0x4
   c:	e3a0c000 	mov	r12, #0	; 0x0
  10:	e5902004 	ldr	r2, [r0, #4]
  14:	e5913004 	ldr	r3, [r1, #4]
  18:	e1520003 	cmp	r2, r3
  1c:	1a000008 	bne	44 <L3>
  20:	e5903000 	ldr	r3, [r0]
  24:	e2133007 	ands	r3, r3, #7	; 0x7
  28:	13a03001 	movne	r3, #1	; 0x1
  2c:	e5912000 	ldr	r2, [r1]
  30:	e3120007 	tst	r2, #7	; 0x7
  34:	13a02000 	movne	r2, #0	; 0x0
  38:	03a02001 	moveq	r2, #1	; 0x1
  3c:	e053c002 	subs	r12, r3, r2
  40:	13a0c001 	movne	r12, #1	; 0x1

As you can see in the invalid dump, after the command at offset 0x28 the 
result of the tst command is destroyed by the ands command, hence the result 
will be right only in 50% of the cases:). 
In the second dump however, after the ands command (offset 0x24), the correct 
action is taken - the result is stored in r3.
>Fix:
The only work-around is to use -O1 instead of -O2.
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="assembly_bug.c"
Content-Disposition: inline; filename="assembly_bug.c"

#define ERECVALL 0x7
typedef struct {
    int op;
    int fd;
} file_ops_t;

static int is_same_ops(file_ops_t *esc1, file_ops_t *esc2)
{
    return esc1->fd == esc2->fd && 
         !(esc1->op & ERECVALL) == !(esc2->op & ERECVALL);    
}

int main(void)
{
    file_ops_t a, b;
    int i;
    
    a.fd = 3;
    a.op = 0x10;
    b.fd = 3;
    b.op = 0x3;

    i = is_same_ops(&a, &b);
    return 0;
}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-08-05 16:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-05  9:36 c/7500: invalid assemly output with -O2 flag rgohita

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).