This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/47148] [4.6 Regression] likely wrong code bug
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 1 Jan 2011 20:53:56 +0000
- Subject: [Bug target/47148] [4.6 Regression] likely wrong code bug
- Auto-submitted: auto-generated
- References: <bug-47148-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47148
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|tree-optimization |target
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-01-01 20:53:39 UTC ---
It seems this is very much related to the PR46942 ABI screw up.
Apparently sometimes on x86_64 we actually rely on the sign/zero extensions
done by the caller, not to DImode, but just to SImode, not by setting
SUBREG_PROMOTED_P bit in the subregs, but at least in combine.c's
setup_incoming_promotions and thus the zero extension is optimized away.
Normally, e.g. when compiling
static unsigned a = 1, b = 1;
static __attribute__((noinline)) void
foo (unsigned char x)
{
unsigned c = (0x7000U / (x - 2)) ^ 1;
b &= c;
}
int
main (void)
{
foo (1);
foo (-1);
if (b && ((unsigned char) -1) == 255)
__builtin_abort ();
return 0;
}
the caller indeed does the needed promotions, as CALL_EXPR's argument has int
type rather than unsigned char. But when calling the artificial foo.part.0,
the
argument passed to it is unsigned char 255 rather than int 255 and it sets a
QImode %rdi register to -1 (i.e. 255) instead of setting SImode %rdi register
to 255, which means it is incorrectly sign extended instead of zero extended.