bug in longlong.h for aarch64 sub_ddmmss
Vincent Lefevre
vincent at vinc17.net
Tue Jun 16 14:11:53 UTC 2020
On 2020-06-16 14:47:23 +0200, Torbjorn Granlund wrote:
> Vincent Lefevre <vincent at vinc17.net> writes:
>
> On 2020-06-16 13:40:14 +0200, Torbjorn Granlund wrote:
> > Vincent Lefevre <vincent at vinc17.net> writes:
> >
> > #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
> > do { \
> > if (__builtin_constant_p (bl) && -(UDItype)(bl) < 0x1000) \
> > __asm__ ("adds\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
> > : "=r,r" (sh), "=&r,&r" (sl) \
> > : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
> > "r,Z" ((UDItype)(al)), "rI,r" (-(UDItype)(bl)) __CLOBBER_CC);\
> > else \
> > __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
> > : "=r,r" (sh), "=&r,&r" (sl) \
> > : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
> > "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC);\
> > } while(0);
> >
> > The two - signs ought to be ~, I think. Let me think a buit more about that.
>
> Note that the "else" case, which doesn't have a - sign in its
> arguments is affected too, AFAIK.
>
> I cannot follow you here.
>
> Are you saying that the asm in the else clause is broken too?
> Please explain.
Sorry, it seems OK (I thought that on (0,0), subs and adds would
be equivalent, but the carry out is actually different).
Note that I'm rather surprised to see that the issue disappears
if I add unrelated code. For instance, in the following testcase,
with GCC 9.1.0 -O2, I get "h = 0xffffffffffffffff", which is
incorrect, but if I define V, I get the correct "h = 0x0".
typedef unsigned int UDItype __attribute__ ((mode (DI)));
typedef unsigned long UWtype;
#define W_TYPE_SIZE 64
#define __GMP_DECLSPEC
#define __GMP_GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#include <stdio.h>
#include "longlong.h"
int v = 0;
int main (void)
{
volatile unsigned long u0 = 0x4000000000000000, r0 = 0x7ffffffffffffffd;
unsigned long u, r, h, l;
u = u0;
r = r0;
if (r < 0x8000000000000000)
r = 0x8000000000000000;
#ifdef V
if (v)
fflush (stdout);
#endif
umul_ppmm (h, l, r, r);
sub_ddmmss (h, l, u, 0, h, l);
printf ("h = 0x%lx\n", h);
return 0;
}
--
Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
More information about the gmp-bugs
mailing list