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

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #7)
> Ah, it's the code that makes SRA widen bit-precision values to
> size-precision integers.  That said, I don't see why the V_C_E should not be
> moveable.
> 
>   value$8_11 = MEM <unsigned char> [(struct Value *)&s_value + 8B];
>   _8 = VIEW_CONVERT_EXPR<_Bool>(value$8_11);
> 
> is exactly what RTL expansion will create - we're not truncating the
> result to bit-precision on _Bool loads.

The problem is the bits outside of bool are set and we don't truncate them out
and since we turn it into:

  _6 = VIEW_CONVERT_EXPR<_Bool>(value$8_8);
  _12 = value_7 != 0;
  _13 = _6 | _12;

We get the wrong answer. This is very similar to if _6 had been an
uninitialized which we fixed during the development of GCC 14.
That is the range of _6 (or _8) is only conditionally `[0,1]`, otherwise it
should be considered similar to an uninitialized variable.

The other thing which we might be able to solve this is change:
```
/* For integral conversions with the same precision or pointer
   conversions use a NOP_EXPR instead.  */
(simplify
  (view_convert @0)
  (if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
       && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0)))
       && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0)))
   (convert @0)))
```

to change bool convert to be convert too. In a similar way how we handle
`zero_one != 0` into a convert instead of a VCE (in VPR and other passes). This
will fix the above too.

Maybe I will test that to see what code generation will look like.

Reply via email to