https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93376

--- Comment #8 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:c124b345e460780e3c3d4a6e58d0e6e03da982a1

commit r10-6178-gc124b345e460780e3c3d4a6e58d0e6e03da982a1
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Jan 23 16:17:56 2020 +0100

    i386: Fix ICEs on TImode signed overflow add/sub patterns [PR93376]

    The following testcase ICEs, because during try_combine of i3:
    (insn 18 17 19 2 (parallel [
                (set (reg:CCO 17 flags)
                    (eq:CCO (plus:OI (sign_extend:OI (reg:TI 96))
                            (const_int 1 [0x1]))
                        (sign_extend:OI (plus:TI (reg:TI 96)
                                (const_int 1 [0x1])))))
                (set (reg:TI 98)
                    (plus:TI (reg:TI 96)
                        (const_int 1 [0x1])))
            ]) "pr93376.c":8:10 223 {*addvti4_doubleword_1}
         (expr_list:REG_UNUSED (reg:TI 98)
            (expr_list:REG_DEAD (reg:TI 96)
                (nil))))
    and i2:
    (insn 17 37 18 2 (set (reg:TI 96)
            (const_wide_int 0x7fffffffffffffffffffffffffffffff))
"pr93376.c":8:10 65 {*movti_internal}
         (nil))
    the eq in there gets simplified into:
    (eq:CCO (const_wide_int 0x080000000000000000000000000000000)
        (const_wide_int 0x80000000000000000000000000000000))
    and simplify-rtx.c tries to simplify it by simplifying MINUS
    of the two operands.
    Now, i386 defines MAX_BITSIZE_MODE_ANY_INT to 128, because OImode
    and XImode are used mainly as a placeholder for the vector modes;
    these new signed overflow patterns are an exception to that,
    but what they really need is just TImode precision + 1 (maybe 2 worst case)
    bits at any time.

    wide-int.h defines WIDE_INT_MAX_ELTS in a way that it contains one more
    HWI above number of HWIs to cover WIDE_INT_MAX_ELTS, so on i386 that is
    3 HWIs, meaning that TImode precision + 1/2 bits is still representable in
    there.  Unfortunately, the way wi::sub_large is implemented, it needs
    not just those 3 HWIs, but one HWI above the maximum of the lengths of
    both operands, which means it buffer overflows, overwrites the following
    precision in wide_int_storage and ICEs later on.  The need for 4 HWIs is
    only temporary, because canonize immediately after it canonicalizes it
    back to 3 HWIs only.

    The patch is something suggested by Richard S., avoid using OImode
    for this and instead use a partial int mode that is smaller.

    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.

Reply via email to