This is the mail archive of the gcc-patches@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]

Re: [PATCH] Fix *anddi_2 (PR target/59101)


On Wed, Nov 13, 2013 at 6:03 PM, Jakub Jelinek <jakub@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  <jakub@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.


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