Subject: bug#36370: 27.0.50; XFIXNAT called on negative numbers

From: Bruno Haible <[email-masked]>
Date: Fri, 28 Jun 2019 21:56:05 +0200

On Freitag, 28. Juni 2019 19:15:06 CEST Pip Cet wrote:
> On Fri, Jun 28, 2019 at 5:46 PM Paul Eggert <[email-masked]> wrote:
> > Pip Cet wrote:
> > > It's way too easy
> > > to do something like
> > >
> > > eassume(ptr->field >= 0 && f(ptr));
> > >
> > > when what you mean is
> > >
> > > eassume(ptr->field >= 0);
> > > eassume(f(ptr));
> >
> > These mean the same thing.
> 
> I'm really convinced they don't. Can you humor me and explain why
> they're equivalent?
> 
> I'm considering this test case:
> ====
> int global;
> 
> extern int f(void);
> 
> #define eassume0(cond) ((cond) ? (void) 0 : __builtin_unreachable ())
> #ifdef ASSUME_GNULIB
> #define eassume eassume0
> #else
> #define eassume(cond) (__builtin_constant_p (!(cond) == !(cond)) ?
> eassume0(cond) : (void) 0)
> #endif
> 
> int main(void)
> {
> #ifdef TWO_ASSUMES
>   eassume (global == 0);
>   eassume (f ());
> #else
>   eassume (global == 0 && f ());
> #endif
> 
>   global++;
> }
> ====
> with this external function:
> ====
> extern int global;
> 
> int f(void)
> {
>   return ++global;
> }
> ====
> 
> I believe, and that is what my patch is based on, that the compiler
> should be free to "use" the first eassume and ignore the second one,
> resulting in this machine code:
> 
>     movl    $1, global(%rip)
>     xorl    %eax, %eax
>     ret

For reference: This test case produces:
  Options                        Result
  none                           increment
  -DASSUME_GNULIB                increment
  -DTWO_ASSUMES                  single-store
  -DASSUME_GNULIB -DTWO_ASSUMES  increment

Bruno