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