On Tue, Mar 10, 2020 at 7:39 AM Jakub Jelinek <ja...@redhat.com> wrote:
>
> Hi!
>
> In r10-1938-g460bf043c8266dd080308f4783137aee0d0f862c *testdi_1 has been
> changed, so that if the mask has upper 32-bits 0 and then at least one bit
> set, it requires CCZmode rather than CCNOmode, because in that case it uses
> testl instruction rather than testq and so the SF flag wouldn't respect the
> state of the 64-bit result.
> The *testqi_ext_3 define_insn_and_split needs to match that though,
> otherwise it can create an RTL pattern that used to match *testdi_1 but
> doesn't anymore and we'd ICE due to an unrecognizable insn.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
>
> 2020-03-10  Jakub Jelinek  <ja...@redhat.com>
>
>         PR target/94088
>         * config/i386/i386.md (*testqi_ext_3): Call ix86_match_ccmode with
>         CCZmode instead of CCNOmode if operands[2] has DImode and pos + len
>         is 32.
>
>         * gcc.target/i386/pr94088.c: New test.

OK.

Thanks,
Uros.

> --- gcc/config/i386/i386.md.jj  2020-03-06 11:35:46.279074931 +0100
> +++ gcc/config/i386/i386.md     2020-03-09 13:25:47.045165188 +0100
> @@ -8826,18 +8826,23 @@ (define_insn_and_split "*testqi_ext_3"
>              (match_operand 3 "const_int_operand" "n")
>              (match_operand 4 "const_int_operand" "n"))
>            (const_int 0)]))]
> -  "ix86_match_ccmode (insn, CCNOmode)
> -   && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
> -       || GET_MODE (operands[2]) == SImode
> -       || GET_MODE (operands[2]) == HImode
> -       || GET_MODE (operands[2]) == QImode)
> +  "((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
> +    || GET_MODE (operands[2]) == SImode
> +    || GET_MODE (operands[2]) == HImode
> +    || GET_MODE (operands[2]) == QImode)
>     /* Ensure that resulting mask is zero or sign extended operand.  */
>     && INTVAL (operands[4]) >= 0
>     && ((INTVAL (operands[3]) > 0
>         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
>         || (<MODE>mode == DImode
>            && INTVAL (operands[3]) > 32
> -          && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
> +          && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
> +   && ix86_match_ccmode (insn,
> +                        /* *testdi_1 requires CCZmode if the mask has bit
> +                           31 set and all bits above it clear.  */
> +                        GET_MODE (operands[2]) == DImode
> +                        && INTVAL (operands[3]) + INTVAL (operands[4]) == 32
> +                        ? CCZmode : CCNOmode)"
>    "#"
>    "&& 1"
>    [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
> --- gcc/testsuite/gcc.target/i386/pr94088.c.jj  2020-03-09 13:23:56.485796409 
> +0100
> +++ gcc/testsuite/gcc.target/i386/pr94088.c     2020-03-09 13:23:21.627310722 
> +0100
> @@ -0,0 +1,9 @@
> +/* PR target/94088 */
> +/* { dg-do compile } */
> +/* { dg-options "-mtbm -O1 -fira-loop-pressure -fno-dce" } */
> +
> +double
> +foo (int x)
> +{
> +  return x / (4294950402U % -65472 + 161);
> +}
>
>         Jakub
>

Reply via email to