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.