On Wed, Nov 13, 2013 at 08:12:41PM +0100, Uros Bizjak wrote: > Patch is OK everywhere, with or without the suggested change.
Ok, here is what I've committed, so far to trunk/4.8, after another round of bootstrap/regtest: 2013-11-14 Jakub Jelinek <ja...@redhat.com> Uros Bizjak <ubiz...@gmail.com> PR target/59101 * config/i386/i386.md (*anddi_2): Only allow CCZmode if operands[2] satisfies_constraint_Z that might have bit 31 set. * gcc.c-torture/execute/pr59101.c: New test. --- gcc/config/i386/i386.md.jj 2013-11-13 19:17:58.281733148 +0100 +++ gcc/config/i386/i386.md 2013-11-13 20:41:08.941030127 +0100 @@ -7978,7 +7978,18 @@ (define_insn "*anddi_2" (const_int 0))) (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") (and:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) + "TARGET_64BIT + && ix86_match_ccmode + (insn, + /* If we are going to emit andl instead of andq, and the operands[2] + constant might have the SImode sign bit set, make sure the sign + flag isn't tested, because the instruction will set the sign flag + based on bit 31 rather than bit 63. If it isn't CONST_INT, + conservatively assume it might have bit 31 set. */ + (satisfies_constraint_Z (operands[2]) + && (!CONST_INT_P (operands[2]) + || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) + ? CCZmode : CCNOmode) && ix86_binary_operator_ok (AND, DImode, operands)" "@ and{l}\t{%k2, %k0|%k0, %k2} --- gcc/testsuite/gcc.c-torture/execute/pr59101.c.jj 2013-11-13 20:37:47.795031458 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr59101.c 2013-11-13 20:37:47.795031458 +0100 @@ -0,0 +1,15 @@ +/* PR target/59101 */ + +__attribute__((noinline, noclone)) int +foo (int a) +{ + return (~a & 4102790424LL) > 0 | 6; +} + +int +main () +{ + if (foo (0) != 7) + __builtin_abort (); + return 0; +} Jakub