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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P1
          Component|tree-optimization           |middle-end
   Target Milestone|7.0                         |5.5
            Summary|[7 Regression] ice on valid |[5/6/7 Regression] ice on
                   |C code on x86_64-linux-gnu  |valid C code on
                   |at -O3 in both 32-bit and   |x86_64-linux-gnu at -O3 in
                   |64-bit modes (internal      |both 32-bit and 64-bit
                   |compiler error: in          |modes (internal compiler
                   |set_value_range, at         |error: in set_value_range,
                   |tree-vrp.c:361)             |at tree-vrp.c:361)

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Hmm, so

 <boolean_type 0x2aaaac16c888 public SI
    size <integer_cst 0x2aaaac025ee8 type <integer_type 0x2aaaac02a150
bitsizetype> constant 32>
    unit size <integer_cst 0x2aaaac025f00 type <integer_type 0x2aaaac02a0a8
sizetype> constant 4>
    align 32 symtab 0 alias set -1 canonical type 0x2aaaac16c888 precision 32
min <integer_cst 0x2aaaac176a20 -2147483648> max <integer_cst 0x2aaaac176bb8
2147483647>>

(look at the types min/max value).  For this rason 

(gdb) p debug_tree (min)
 <integer_cst 0x2aaaac176d98 type <boolean_type 0x2aaaac16c888> constant public
overflow -1>

is not considered is_overflow_infinity (it's not vrp_val_is_min/max).

So what is causing this is likely behavioral change of some constant folding
with respect to BOOLEAN_TYPEs.  Here

  _22 = BIT_FIELD_REF <mask__23.24_5, 32, 96>;
  _53 = (_Bool) _22;

changed behavior in force_fit_type which does:

tree
force_fit_type (tree type, const wide_int_ref &cst,
                int overflowable, bool overflowed)
{
  signop sign = TYPE_SIGN (type);

  /* If we need to set overflow flags, return a new unshared node.  */
  if (overflowed || !wi::fits_to_tree_p (cst, type))
    {
      if (overflowed
          || overflowable < 0
          || (overflowable > 0 && sign == SIGNED))
        {
          wide_int tmp = wide_int::from (cst, TYPE_PRECISION (type), sign);
          tree t = build_new_int_cst (type, tmp);
          TREE_OVERFLOW (t) = 1;
          return t;
        }

where -1 no longer "fits" bool even though it should.  So

  /* Short-circuit boolean types since various transformations assume that
     they can only take values 0 and 1.  */
  if (TREE_CODE (type) == BOOLEAN_TYPE)
    return eq_p (x, 0) || eq_p (x, 1);

is wrong and should use eq_p (x, -1) instead as bool is signed?  The
int_fits_type_p function is likely wrong as well (uses integer_onep).

The patch has been backported as well, adjusting regression marker.

Reply via email to