On Thu, Aug 31, 2023 at 3:58 PM Krister Walfridsson via Gcc
<gcc@gcc.gnu.org> wrote:
>
> My translation validation tool reports some miscompilations related to the
> internal call CLZ(0) when CLZ_DEFINED_VALUE_AT_ZERO is false, but I am not
> sure I use the correct semantics...
>
> I started by modeling CLZ(0) as undefined behavior, but that made the tool
> report a miscompilation for gcc.c-torture/execute/920501-6.c where sccp
> changes a loop to
>
>    _36 = t_10(D) != 0;
>    _35 = .CLZ (t_10(D));
>    _34 = 63 - _35;
>    _33 = (unsigned int) _34;
>    _32 = (long long unsigned int) _33;
>    _31 = _32 + 1;
>    b_38 = _36 ? _31 : 1;
>
> This may call CLZ with 0, but the value is not used, so it seems
> reasonable to allow this. I therefore changed my tool to treat CLZ(0) as
> returning an undefined value instead (by generating it as a symbolic
> value, which then makes the tool test that the IR is valid for all
> values).
>
> This still makes this optimization fail because the calculation of _34 may
> overflow... :(  This could be a bug in the sccp pass (which could have
> done the calculation as unsigned), but fixing this would still make the
> tool report a miscompilation as the ranges calculated during the dom3 pass
> claims that _35 has a range:
>    _35  : [irange] int [0, 63]
>
> So what is the correct semantics for CLZ when CLZ_DEFINED_VALUE_AT_ZERO is
> false?

The value of .CLZ (0) is undefined then.  I belive your analysis is correct in
that both 63 - _35 might overflow and that dom3 (thus ranger) mis-computes
the range for _35.  I wonder why we don't elide _36 ? _31 : 1 with that info
(possibly no range-op for .CLZ?), of course it would be wrong to do so.

Can you open a bugreport please?

Richard.

>
>     /Krister

Reply via email to