|
|
Message-ID: <20210228182445.66f1de08.maandree@kth.se>
Date: Sun, 28 Feb 2021 18:24:45 +0100
From: Mattias Andrée <maandree@....se>
To: musl@...ts.openwall.com
Subject: Re: [PATCH] Remove unnecessary if in __secs_to_tm
On Sun, 28 Feb 2021 12:06:15 -0500
Rich Felker <dalias@...c.org> wrote:
> On Sun, Feb 28, 2021 at 04:09:12PM +0100, Mattias Andrée wrote:
> > Since years divisible by 100 but not by 400 are not leap years,
> > q_cycles can at most be 24 (DAYS_PER_100Y / DAYS_PER_4Y == 24).
> > ---
> > src/time/__secs_to_tm.c | 3 +--
> > 1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/src/time/__secs_to_tm.c b/src/time/__secs_to_tm.c
> > index 093d9021..2d0c0b2c 100644
> > --- a/src/time/__secs_to_tm.c
> > +++ b/src/time/__secs_to_tm.c
> > @@ -44,8 +44,7 @@ int __secs_to_tm(long long t, struct tm *tm)
> > remdays -= c_cycles * DAYS_PER_100Y;
> >
> > q_cycles = remdays / DAYS_PER_4Y;
> > - if (q_cycles == 25) q_cycles--;
> > - remdays -= q_cycles * DAYS_PER_4Y;
> > + remdays %= DAYS_PER_4Y;
> >
> > remyears = remdays / 365;
> > if (remyears == 4) remyears--;
>
> I think you're right about the condition being impossible -- it looks
> like the error in thinking was that, while 400Y and 4Y are strictly
> larger than 4*100Y and 4*1Y respectively, 100Y is smaller than 25*4Y.
>
> However, changing the -= to %= is not desirable. The point of the -=
> has nothing to do with the edge case that can't happen; it's to avoid
> a modulo operation. Since the divisor is a constant though maybe the
> compiler can generate the same code for both, anyway..?
>
> Rich
For x86_64 `remdays %= DAYS_PER_4Y` just becomes a move.
divmod in
int r = 52, q;
void divmod(void)
{
q = r / 111;
r %= 111;
}
becomes
movl r(%rip), %eax
movl $111, %ecx
cltd
idivl %ecx
movl %eax, q(%rip)
movl %edx, r(%rip)
ret
`remdays -= q_cycles * DAYS_PER_4Y;` on the other hand
becomes a move, a multiplication, and an addition.
divmod in
int r = 52, q;
void divmod(void)
{
q = r / 111;
r -= q * 111;
}
becomes
movl r(%rip), %eax
movl $111, %ecx
cltd
idivl %ecx
movl %eax, q(%rip)
imull $-111, %eax, %eax
addl r(%rip), %eax
movl %eax, r(%rip)
ret
So I would say %= is the better option, at least for x86_64.
Of course, if you prefer, I will change it to use -=.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.