[Bug target/93376] [10 Regression] ICE: in immed_wide_int_const_1, at emit-rtl.c:660 with -Og -finline-functions-called-once

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Jan 22 11:07:00 GMT 2020


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rsandifo at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem seems to be during try_combine:
(gdb) p debug_rtx (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))))
(gdb) p debug_rtx (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))
(correct), where the first CONST_WIDE_INT has 3 elts (as it is the TImode MS
bit zero extended into OImode) and the second one has 2 elts (the same
sign-extended into OImode).
The problem is that i386.md has
/* 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)
which means WIDE_INT_MAX_ELTS is 3, which is big enough to handle all that the
patterns need, they only need one hwi above the TImode bits to detect overflow
in either way (maybe even just 1-2 bits).
I'm afraid we don't want to bump MAX_BITSIZE_MODE_ANY_INT, because it would
have consequences anywhere.

Anyway, what happens when simplify-rtx.c calls:
4443            case MINUS:
4444              result = wi::sub (pop0, pop1);
4445              break;
(gdb) p pop0
$44 = {<std::__pair_base<rtx_def*, machine_mode>> = {<No data fields>},
(const_wide_int 0x080000000000000000000000000000000)first = , second =
E_OImode}
(gdb) p pop1
$45 = {<std::__pair_base<rtx_def*, machine_mode>> = {<No data fields>},
(const_wide_int 0x80000000000000000000000000000000)first = , second = E_OImode}
again, len 3 and len 2.
That results in wi::sub creating result of:
$47 = {<wide_int_storage> = {val = {8589917872, 140737127633408,
140737488338464}, len = 13162290, precision = 256}, 
  static is_sign_extended = true}
where the val array has 3 elts, but then:
2539        result.set_len (sub_large (val, xi.val, xi.len,
2540                                   yi.val, yi.len, precision,
2541                                   UNSIGNED, 0));
and that one unnecessarily uses yet another HWI, overwriting precision in the
wide_int_storage.

The following fixes the ICE, Richard S., would this be acceptable to you?
Only the second hunk is strictly necessary.

--- gcc/wide-int.cc.jj  2020-01-12 11:54:38.535381394 +0100
+++ gcc/wide-int.cc     2020-01-22 12:05:06.739486117 +0100
@@ -1155,8 +1155,14 @@ wi::add_large (HOST_WIDE_INT *val, const

   if (len * HOST_BITS_PER_WIDE_INT < prec)
     {
-      val[len] = mask0 + mask1 + carry;
-      len++;
+      HOST_WIDE_INT val_top = mask0 + mask1 + carry;
+      /* Don't extend len unnecessarily when canonize would shrink it
+        again immediately.  */
+      if (SIGN_MASK (val[len - 1]) != val_top)
+       {
+         val[len] = val_top;
+         len++;
+       }
       if (overflow)
        *overflow
          = (sgn == UNSIGNED && carry) ? wi::OVF_OVERFLOW : wi::OVF_NONE;
@@ -1566,8 +1572,14 @@ wi::sub_large (HOST_WIDE_INT *val, const

   if (len * HOST_BITS_PER_WIDE_INT < prec)
     {
-      val[len] = mask0 - mask1 - borrow;
-      len++;
+      HOST_WIDE_INT val_top = mask0 - mask1 - borrow;
+      /* Don't extend len unnecessarily when canonize would shrink it
+        again immediately.  */
+      if (SIGN_MASK (val[len - 1]) != val_top)
+       {
+         val[len] = val_top;
+         len++;
+       }
       if (overflow)
        *overflow = (sgn == UNSIGNED && borrow) ? OVF_UNDERFLOW : OVF_NONE;
     }


More information about the Gcc-bugs mailing list