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