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 <jakub@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.