This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/47148] [4.6 Regression] likely wrong code bug


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]