#107123 [PR optimization/3507, optimization/3996] Non-optimal code

Package:
gcc
Source:
gcc-defaults
Description:
GNU C compiler
Submitter:
Petr Vandrovec
Date:
2015-08-21 14:15:06 UTC
Severity:
wishlist
#107123#5
Date:
2001-07-30 17:27:15 UTC
From:
To:
Hi,
  this simple code snippet generates a bit suboptimal code
when compiled with gcc-3.0. For some unknown reason
simple '--b->cnt' is correctly assembled as 'decl (somememory)',
but when this expression is tested for zero (which is available
on i386 in Z flag after simple decrement), it loads value
into register, decrements, then even again tests for zero, and
finally stores it back to memory ... This is visible in both
freeblock and freeblockC.

  Second problem is that when decremented field in structure
is not integer (for example char) and function is chained into
another one with same arguments, some of arguments are
for unknown reason written back to stack, although their
value did not change (I even tried to mark argument
as 'struct blockChar* const b', but no change on generated
code). This is visible in freeblockC only.

  These are all acceptable because of gcc-2.95.x generated
even worse code.

  But what's not acceptable happens in readAsyncCallback.
For some strange reason it allocates 16bytes of stack, for
unknown reason (note that it was compiled with
-mpreferred-stack-boundary=2, so it is not any stack aligning). 
It is smallest example of problem I'm suffering of - I have
function which reserves 364 bytes on stack with gcc-3.0, but
only 120 bytes when compiled with gcc-2.95, and code generated by
gcc-3.0 does not even touch couple of on-stack variables
which were optimized, but then somehow left in stack frame.

				Thanks,
					Petr Vandrovec
					vandrove@vc.cvut.cz

struct blockInt {
	unsigned int cnt;
};

void __freeblock(struct blockInt*);

void freeblock(struct blockInt* b) {
	if (--b->cnt) __freeblock(b);
}

void simpleDec(struct blockInt* b) {
	--b->cnt;
}

struct blockChar {
	unsigned char cnt;
	void* address;
};

void __freeblockC(struct blockChar*);

void freeblockC(struct blockChar* b) {
	if (--b->cnt) __freeblockC(b);
}

void simpleDecC(struct blockChar* b) {
	--b->cnt;
}
struct semaphore {
	void*	queue;
	int	value;
};

struct LB_async {
	struct semaphore*		sema;
};

void LBL_sSignal(struct semaphore*);

static inline void __LBL_sSignal(struct semaphore* sem) {
	if (!--sem->value && sem->queue) {
		LBL_sSignal(sem);
	}
}

void readAsyncCallback(struct LB_async* req) {
	__LBL_sSignal(req->sema);
}
---------- generated asm ----------

	.file	"x.c"
# GNU C version 3.0.1 20010728 (Debian prerelease) (i386-linux)
#	compiled by GNU C version 3.0.1 20010728 (Debian prerelease).
# options passed:  -lang-c -D__GNUC__=3 -D__GNUC_MINOR__=0
# -D__GNUC_PATCHLEVEL__=1 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__
# -D__linux__ -D__unix -D__linux -Asystem=posix -D__OPTIMIZE__
# -D__STDC_HOSTED__=1 -W -Wall -Acpu=i386 -Amachine=i386 -Di386 -D__i386
# -D__i386__ -D__tune_i386__ -mpreferred-stack-boundary=2 -O2 -W -Wall
# -fomit-frame-pointer -fverbose-asm
# options enabled:  -fdefer-pop -fomit-frame-pointer
# -foptimize-sibling-calls -fcse-follow-jumps -fcse-skip-blocks
# -fexpensive-optimizations -fthread-jumps -fstrength-reduce -fpeephole
# -fforce-mem -ffunction-cse -finline -fkeep-static-consts -fcaller-saves
# -fpcc-struct-return -fgcse -frerun-cse-after-loop -frerun-loop-opt
# -fdelete-null-pointer-checks -fschedule-insns2 -fsched-interblock
# -fsched-spec -fbranch-count-reg -freorder-blocks -fcommon -fverbose-asm
# -fgnu-linker -fregmove -foptimize-register-move -fargument-alias
# -fstrict-aliasing -fident -fpeephole2 -fguess-branch-probability
# -fmath-errno -m80387 -mhard-float -mno-soft-float -mieee-fp
# -mfp-ret-in-387 -mpreferred-stack-boundary=2

	.text
	.align 4
.globl freeblock
	.type	freeblock,@function
freeblock:
	movl	4(%esp), %edx
	movl	(%edx), %eax
	decl	%eax
	testl	%eax, %eax
	movl	%eax, (%edx)
	je	.L2
	jmp	__freeblock
	.p2align 2
.L2:
	ret
.Lfe1:
	.size	freeblock,.Lfe1-freeblock
	.align 4
.globl simpleDec
	.type	simpleDec,@function
simpleDec:
	movl	4(%esp), %eax
	decl	(%eax)
	ret
.Lfe2:
	.size	simpleDec,.Lfe2-simpleDec
	.align 4
.globl freeblockC
	.type	freeblockC,@function
freeblockC:
	movl	4(%esp), %edx
	movb	(%edx), %al
	decl	%eax
	testb	%al, %al
	movb	%al, (%edx)
	je	.L5
	movl	%edx, 4(%esp)
	jmp	__freeblockC
	.p2align 2
.L5:
	ret
.Lfe3:
	.size	freeblockC,.Lfe3-freeblockC
	.align 4
.globl simpleDecC
	.type	simpleDecC,@function
simpleDecC:
	movl	4(%esp), %eax
	decb	(%eax)
	ret
.Lfe4:
	.size	simpleDecC,.Lfe4-simpleDecC
	.align 4
.globl readAsyncCallback
	.type	readAsyncCallback,@function
readAsyncCallback:
	subl	$16, %esp
	movl	20(%esp), %eax
	movl	(%eax), %edx
	movl	4(%edx), %eax
	decl	%eax
	testl	%eax, %eax
	movl	%eax, 4(%edx)
	je	.L11
.L10:
	addl	$16, %esp
	ret
	.p2align 2
.L11:
	movl	(%edx), %ecx
	testl	%ecx, %ecx
	je	.L10
	pushl	%edx
	call	LBL_sSignal
	popl	%eax
	jmp	.L10
.Lfe5:
	.size	readAsyncCallback,.Lfe5-readAsyncCallback
	.ident	"GCC: (GNU) 3.0.1 20010728 (Debian prerelease)"

#107123#8
Date:
2001-08-11 07:46:01 UTC
From:
To:
Thank you very much for your problem report.
It has the internal identification `optimization/3996'.
The individual assigned to look at your
report is: unassigned.

#107123#15
Date:
2001-08-11 09:53:11 UTC
From:
To:
# submitted Debian report #107123 to gcc-gnats as PR 3996
# http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=3996&database=gcc

forwarded 107123 gcc-gnats@gcc.gnu.org
retitle 107123 [PR optimization/3996] Non-optimal code
thanks

#107123#20
Date:
2002-04-03 00:36:59 UTC
From:
To:
State-Changed-From-To: open->closed
State-Changed-By: rth
State-Changed-When: Tue Apr  2 16:36:58 2002
State-Changed-Why:
    Duplicate of PR 3507.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=3996

#107123#25
Date:
2002-04-03 11:22:30 UTC
From:
To:
State-Changed-From-To: open->closed
State-Changed-By: neil
State-Changed-When: Wed Apr  3 03:22:28 2002
State-Changed-Why:
    This is tedious - can you stop Debbugs replying to GNATS?
    They get themselves in a mail loop.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6141

#107123#34
Date:
2002-12-18 15:51:20 UTC
From:
To:
State-Changed-From-To: open->closed
State-Changed-By: bangerth
State-Changed-When: Wed Dec 18 07:51:19 2002
State-Changed-Why:
    Mail picked up accidentially.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6150

#107123#53
Date:
2008-01-30 20:43:13 UTC
From:
To:
This bug report was submitted for an older version of gcc/g++/gcj.
Please recheck with the current gcc-4.3/g++-4.3/gcj-4.3 packages
from unstable.

#107123#56
Date:
2008-01-30 20:43:13 UTC
From:
To:
This bug report was submitted for an older version of gcc/g++/gcj.
Please recheck with the current gcc-4.3/g++-4.3/gcj-4.3 packages
from unstable.

#107123#61
Date:
2015-08-21 13:43:08 UTC
From:
To:
Dear submitter,

as the package gcc-4.6 has just been removed from the Debian archive
unstable we hereby close the associated bug reports.  We are sorry
that we couldn't deal with your issue properly.

For details on the removal, please see https://bugs.debian.org/796274

The version of this package that was in Debian prior to this removal
can still be found using http://snapshot.debian.org/.

This message was generated automatically; if you believe that there is
a problem with it please contact the archive administrators by mailing
ftpmaster@ftp-master.debian.org.

Debian distribution maintenance software
pp.
Scott Kitterman (the ftpmaster behind the curtain)