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.

--- 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