On Wed, Nov 13, 2013 at 6:03 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> If *anddi_2 is used with 64-bit integer constant that matches > "Z" constraint, but has bit 31 set, we emit it as andl instead, > but that is wrong unless just ZF is tested in the flags, because > SF might be different (if operands[1] has bit 31 set, then SF > from andl will be set, but for the 64-bit operation it would be clear). > If constant doesn't have bit 31 set (nor any other higher bits), then > SF will be 0 both when using andl or when using andq, so it is fine > to keep using andl in that case. > > At -O2 VRP will optimize > _3 = ~a_2(D); > _4 = (long long int) _3; > _5 = _4 & 4102790424; > if (_5 > 0) > into: > _3 = ~a_2(D); > _4 = (long long int) _3; > _5 = _4 & 4102790424; > if (_5 != 0) > but at -O1, -Og (or -O2 -fno-tree-vrp) it will not and then we can end > up with wrong-code. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok > for trunk/4.8? > > 2013-11-13 Jakub Jelinek <ja...@redhat.com> > > PR target/59101 > * config/i386/i386.md (*anddi_2): Only allow CCZmode if > operands[2] is positive 64-bit constant that is negative in > SImode. > > * gcc.c-torture/execute/pr59101.c: New test. > > --- gcc/config/i386/i386.md.jj 2013-11-12 11:31:31.000000000 +0100 > +++ gcc/config/i386/i386.md 2013-11-13 10:14:10.981609589 +0100 > @@ -7978,7 +7978,12 @@ (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, CONST_INT_P (operands[2]) > + && INTVAL (operands[2]) > 0 > + && (INTVAL (operands[2]) > + & (HOST_WIDE_INT_1 << 31)) != 0 > + ? CCZmode : CCNOmode) "Z" constraint, a.k.a x86_64_zext_immediate_operand won't allow constants with high bits set. It looks to me, we can use mode_signbit_p here, and simplify the expression to ix86_match_ccmode (insn, mode_signbit_p (SImode, operands[2]) ? CCZmode : CCNOmode) Please also add comment, this issue is quite non-obvious. Uros.