bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
From: Jeffrey Walton <noloader@gmail.com>
To: Bruno Haible <bruno@clisp.org>
Cc: bug-gnulib@gnu.org
Subject: Re: test-bitrotate.c missing test cases
Date: Tue, 31 Mar 2020 02:31:30 -0400	[thread overview]
Message-ID: <CAH8yC8mUf9bVfi+ZWNtkWFYA-iynK305yW7Haj8Mco6t6jBeXQ@mail.gmail.com> (raw)
In-Reply-To: <2790438.WTOhFlp6Ne@omega>

On Sun, Mar 29, 2020 at 11:40 AM Bruno Haible <bruno@clisp.org> wrote:
>
> Jeffrey,
>
> > Forgive my ignorance... No'oping 0 leaks timing information
>
> There are only few algorithms where leaking timing information is an
> issue. For most of the code we deal with, the developer wants to get
> optimal performance.
>
> > I also don't think developers are going to write a rotate like:
> >
> >     if (n != 0)
> >         x = rotr32(x, n);
>
> Sure they will. Here's an example from lib/vasnprintf.c, where a shift
> count of 0 is treated specially:
>
>
>       /* Copy a, shifting it left by s bits, yields r.
>          Memory layout:
>          At the beginning: r = roomptr[0..a_len],
>          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
>       r_ptr = roomptr;
>       if (s == 0)
>         {
>           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
>           r_ptr[a_len] = 0;
>         }
>       else
>         {
>           const mp_limb_t *sourceptr = a_ptr;
>           mp_limb_t *destptr = r_ptr;
>           mp_twolimb_t accu = 0;
>           size_t count;
>           for (count = a_len; count > 0; count--)
>             {
>               accu += (mp_twolimb_t) *sourceptr++ << s;
>               *destptr++ = (mp_limb_t) accu;
>               accu = accu >> GMP_LIMB_BITS;
>             }
>           *destptr++ = (mp_limb_t) accu;
>         }

Let me try again.

The C standard says a shift and rotate is well defined over [0, N-1]
inclusive. 0 is _not_ undefined, and N is undefined.

The current rotate does not provide an implementation that abstracts
the C standard. It has undefined behavior for the element 0. It
requires special handling of element 0 which introduces a branch. (The
current implementation does not even do that; it pushes the
technological debt onto users). The current implementation makes
spurious claims about N being well defined when it is not; it is
clearly undefined behavior.

The current rotate is not portable; in fact it is dangerous. Folks
using it have been merely getting lucky because the implementation
cannot guarantee a rotate of N will not be removed by the compiler.
Looking at the self tests, luck ran out on a rotate of 0. The current
rotate could not pass a complete set of self tests.

The updated implementation provides a complete abstraction of the C
standard by providing a means to rotate over [0, N-1] without
branches. According to the Clang, GCC and ICC compiler teams, the
pattern used by the updated implementation is recognized by the
compiler and will be compiled down to 1 rotate instruction when the
hardware supports it.

There is no risk with the updated implementation. There is
considerable risk with the existing implementation. In fact, the fact
that the existing implementation omits tests cases for element 0
should tell you how broken the current implementation is. The current
implementation does not work in practice.

Jeff


      reply	other threads:[~2020-03-31  6:31 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-29  9:00 test-bitrotate.c missing test cases Jeffrey Walton
2020-03-29 10:27 ` Jeffrey Walton
2020-03-29 12:53 ` Bruno Haible
2020-03-29 13:10   ` Jeffrey Walton
2020-03-29 15:40     ` Bruno Haible
2020-03-31  6:31       ` Jeffrey Walton [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAH8yC8mUf9bVfi+ZWNtkWFYA-iynK305yW7Haj8Mco6t6jBeXQ@mail.gmail.com \
    --to=noloader@gmail.com \
    --cc=bruno@clisp.org \
    --cc=bug-gnulib@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).