On Thu, Jan 23, 2020 at 2:17 PM Jakub Jelinek <ja...@redhat.com> wrote:
>
> On Thu, Jan 23, 2020 at 10:38:31AM +0100, Uros Bizjak wrote:
> > On Thu, Jan 23, 2020 at 10:33 AM Jakub Jelinek <ja...@redhat.com> wrote:
> > >
> > > On Thu, Jan 23, 2020 at 09:14:42AM +0000, Richard Sandiford wrote:
> > > > > The other patch is something suggested by Richard S., avoid using 
> > > > > OImode
> > > > > for this and instead use a partial int mode that is smaller.  This is 
> > > > > still
> > > > > playing with fire because even the partial int mode is larger than
> > > > > MAX_BITSIZE_MODE_ANY_INT, but at least its precision fits into those 3
> > > > > WIDE_INT_MAX_ELTS wide-int.h uses.
> > > >
> > > > I think we should increase MAX_BITSIZE_MODE_ANY_INT to the precision
> > > > of POImode at the same time, and make that precision less than 192
> > > > (191 maybe?).  That way everything is "correct" without increasing
> > > > the size of wide_int.
> > >
> > > The 192 was chosen just to be nice and round, I guess it could be just 130
> > > or say 160 (128 + 32).
> > >
> > > Uros, would you be ok with bumping MAX_BITSIZE_MODE_ANY_INT to 160
> > > and changing the POImode patch to use 160 bits instead of 192
> > > if it passes testing?
> >
> > We can try 160 and hope that nothing breaks due to "weird" number.
>
> Following passed bootstrap/regtest on x86_64-linux and i686-linux.
>
> Ok for trunk then?
>
> 2020-01-23  Jakub Jelinek  <ja...@redhat.com>
>
>         PR target/93376
>         * config/i386/i386-modes.def (POImode): New mode.
>         (MAX_BITSIZE_MODE_ANY_INT): Change from 128 to 160.
>         * config/i386/i386.md (DPWI): New mode attribute.
>         (addv<mode>4, subv<mode>4): Use <DPWI> instead of <DWI>.
>         (QWI): Rename to...
>         (QPWI): ... this.  Use POI instead of OI for TImode.
>         (*addv<dwi>4_doubleword, *addv<dwi>4_doubleword_1,
>         *subv<dwi>4_doubleword, *subv<dwi>4_doubleword_1): Use <QPWI>
>         instead of <QWI>.
>
>         * gcc.dg/pr93376.c: New test.

LGTM.

Thanks,
Uros.

> --- gcc/config/i386/i386-modes.def.jj   2020-01-22 16:10:29.812837184 +0100
> +++ gcc/config/i386/i386-modes.def      2020-01-23 11:43:37.931345071 +0100
> @@ -107,10 +107,19 @@ INT_MODE (XI, 64);
>  PARTIAL_INT_MODE (HI, 16, P2QI);
>  PARTIAL_INT_MODE (SI, 32, P2HI);
>
> +/* Mode used for signed overflow checking of TImode.  As
> +   MAX_BITSIZE_MODE_ANY_INT is only 160, wide-int.h reserves only that
> +   rounded up to multiple of HOST_BITS_PER_WIDE_INT bits in wide_int etc.,
> +   so OImode is too large.  For the overflow checking we actually need
> +   just 1 or 2 bits beyond TImode precision.  Use 160 bits to have
> +   a multiple of 32.  */
> +PARTIAL_INT_MODE (OI, 160, POI);
> +
>  /* Keep the OI and XI modes from confusing the compiler into thinking
>     that these modes could actually be used for computation.  They are
> -   only holders for vectors during data movement.  */
> -#define MAX_BITSIZE_MODE_ANY_INT (128)
> +   only holders for vectors during data movement.  Include POImode precision
> +   though.  */
> +#define MAX_BITSIZE_MODE_ANY_INT (160)
>
>  /* The symbol Pmode stands for one of the above machine modes (usually 
> SImode).
>     The tm.h file specifies which one.  It is not a distinct mode.  */
> --- gcc/config/i386/i386.md.jj  2020-01-22 16:10:29.815837139 +0100
> +++ gcc/config/i386/i386.md     2020-01-23 11:40:54.923822116 +0100
> @@ -6054,15 +6054,18 @@ (define_insn "*addqi_ext_2"
>    [(set_attr "type" "alu")
>     (set_attr "mode" "QI")])
>
> +;; Like DWI, but use POImode instead of OImode.
> +(define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
> +
>  ;; Add with jump on overflow.
>  (define_expand "addv<mode>4"
>    [(parallel [(set (reg:CCO FLAGS_REG)
>                    (eq:CCO
> -                    (plus:<DWI>
> -                      (sign_extend:<DWI>
> +                    (plus:<DPWI>
> +                      (sign_extend:<DPWI>
>                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
>                        (match_dup 4))
> -                        (sign_extend:<DWI>
> +                        (sign_extend:<DPWI>
>                            (plus:SWIDWI (match_dup 1)
>                              (match_operand:SWIDWI 2
>                                "<general_hilo_operand>")))))
> @@ -6078,7 +6081,7 @@ (define_expand "addv<mode>4"
>    if (CONST_SCALAR_INT_P (operands[2]))
>      operands[4] = operands[2];
>    else
> -    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
> +    operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
>  })
>
>  (define_insn "*addv<mode>4"
> @@ -6123,17 +6126,17 @@ (define_insn "addv<mode>4_1"
>               (const_string "<MODE_SIZE>")))])
>
>  ;; Quad word integer modes as mode attribute.
> -(define_mode_attr QWI [(SI "TI") (DI "OI")])
> +(define_mode_attr QPWI [(SI "TI") (DI "POI")])
>
>  (define_insn_and_split "*addv<dwi>4_doubleword"
>    [(set (reg:CCO FLAGS_REG)
>         (eq:CCO
> -         (plus:<QWI>
> -           (sign_extend:<QWI>
> +         (plus:<QPWI>
> +           (sign_extend:<QPWI>
>               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
> -           (sign_extend:<QWI>
> +           (sign_extend:<QPWI>
>               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" 
> "r<di>,o")))
> -         (sign_extend:<QWI>
> +         (sign_extend:<QPWI>
>             (plus:<DWI> (match_dup 1) (match_dup 2)))))
>     (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
>         (plus:<DWI> (match_dup 1) (match_dup 2)))]
> @@ -6172,11 +6175,11 @@ (define_insn_and_split "*addv<dwi>4_doub
>  (define_insn_and_split "*addv<dwi>4_doubleword_1"
>    [(set (reg:CCO FLAGS_REG)
>         (eq:CCO
> -         (plus:<QWI>
> -           (sign_extend:<QWI>
> +         (plus:<QPWI>
> +           (sign_extend:<QPWI>
>               (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
> -           (match_operand:<QWI> 3 "const_scalar_int_operand" ""))
> -         (sign_extend:<QWI>
> +           (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
> +         (sign_extend:<QPWI>
>             (plus:<DWI>
>               (match_dup 1)
>               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
> @@ -6570,11 +6573,11 @@ (define_insn "*subsi_2_zext"
>  (define_expand "subv<mode>4"
>    [(parallel [(set (reg:CCO FLAGS_REG)
>                    (eq:CCO
> -                    (minus:<DWI>
> -                      (sign_extend:<DWI>
> +                    (minus:<DPWI>
> +                      (sign_extend:<DPWI>
>                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
>                        (match_dup 4))
> -                    (sign_extend:<DWI>
> +                    (sign_extend:<DPWI>
>                        (minus:SWIDWI (match_dup 1)
>                                      (match_operand:SWIDWI 2
>                                                 "<general_hilo_operand>")))))
> @@ -6590,7 +6593,7 @@ (define_expand "subv<mode>4"
>    if (CONST_SCALAR_INT_P (operands[2]))
>      operands[4] = operands[2];
>    else
> -    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
> +    operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
>  })
>
>  (define_insn "*subv<mode>4"
> @@ -6637,12 +6640,12 @@ (define_insn "subv<mode>4_1"
>  (define_insn_and_split "*subv<dwi>4_doubleword"
>    [(set (reg:CCO FLAGS_REG)
>         (eq:CCO
> -         (minus:<QWI>
> -           (sign_extend:<QWI>
> +         (minus:<QPWI>
> +           (sign_extend:<QPWI>
>               (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
> -           (sign_extend:<QWI>
> +           (sign_extend:<QPWI>
>               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" 
> "r<di>,o")))
> -         (sign_extend:<QWI>
> +         (sign_extend:<QPWI>
>             (minus:<DWI> (match_dup 1) (match_dup 2)))))
>     (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
>         (minus:<DWI> (match_dup 1) (match_dup 2)))]
> @@ -6679,11 +6682,11 @@ (define_insn_and_split "*subv<dwi>4_doub
>  (define_insn_and_split "*subv<dwi>4_doubleword_1"
>    [(set (reg:CCO FLAGS_REG)
>         (eq:CCO
> -         (minus:<QWI>
> -           (sign_extend:<QWI>
> +         (minus:<QPWI>
> +           (sign_extend:<QPWI>
>               (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
> -           (match_operand:<QWI> 3 "const_scalar_int_operand" ""))
> -         (sign_extend:<QWI>
> +           (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
> +         (sign_extend:<QPWI>
>             (minus:<DWI>
>               (match_dup 1)
>               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
> --- gcc/testsuite/gcc.dg/pr93376.c.jj   2020-01-23 11:40:54.923822116 +0100
> +++ gcc/testsuite/gcc.dg/pr93376.c      2020-01-23 11:40:54.923822116 +0100
> @@ -0,0 +1,20 @@
> +/* PR target/93376 */
> +/* { dg-do compile { target int128 } } */
> +/* { dg-options "-Og -finline-functions-called-once" } */
> +
> +unsigned a, b, c;
> +
> +int
> +bar (int x)
> +{
> +  short s = __builtin_sub_overflow (~x, 0, &b);
> +  a = __builtin_ffsll (~x);
> +  return __builtin_add_overflow_p (-(unsigned __int128) a, s,
> +                                  (unsigned __int128) 0);
> +}
> +
> +void
> +foo (void)
> +{
> +  c = bar (0);
> +}
>
>
>         Jakub
>

Reply via email to