Re: Remove dependence on integer wrapping

From: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
To: Nathan Bossart <nathandbossart(at)gmail(dot)com>, jian he <jian(dot)universality(at)gmail(dot)com>
Cc: Joseph Koshakow <koshy44(at)gmail(dot)com>, Matthew Kim <matthewkmkim(at)gmail(dot)com>, Alexander Lakhin <exclusion(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>
Subject: Re: Remove dependence on integer wrapping
Date: 2024-08-14 07:02:28
Message-ID: 875ad3ec-f216-487e-baad-cdbaf32c1fcf@iki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 14/08/2024 06:07, Nathan Bossart wrote:
> On Tue, Aug 13, 2024 at 04:46:34PM -0500, Nathan Bossart wrote:
>> I've been preparing 0001 for commit. I've attached what I have so far.
>>
>> The main changes are the implementations of pg_abs_* and pg_neg_*. For the
>> former, I've used abs()/i64abs() for the short/int implementations. For
>> the latter, I've tried to use __builtin_sub_overflow() when possible, as
>> that appears to produce slightly better code. When
>> __builtin_sub_overflow() is not available, the values are upcasted before
>> negation, and we check that result before casting to the return type. That
>> approach more closely matches the surrounding functions. (One exception is
>> pg_neg_u64_overflow() when we have neither HAVE__BUILTIN_OP_OVERFLOW nor
>> HAVE_INT128. In that case, we have to hand-roll everything.)
>
> And here's a new version of the patch in which I've attempted to fix the
> silly mistakes.

LGTM, just a few small comments:

> * - If a * b overflows, return true, otherwise store the result of a * b
> * into *result. The content of *result is implementation defined in case of
> * overflow.
> + * - If -a overflows, return true, otherwise store the result of -a into
> + * *result. The content of *result is implementation defined in case of
> + * overflow.
> + * - Return the absolute value of a as an unsigned integer of the same
> + * width.
> *---------
> */

The last "Return the absolute value of a ..." sentence feels a bit
weird. In all the preceding sentences, 'a' is part of an "If a" sentence
that defines what 'a' is. In the last one, it's kind of just hanging there.

> +static inline uint16
> +pg_abs_s16(int16 a)
> +{
> + return abs(a);
> +}
> +

This is correct, but it took me a while to understand why. Maybe some
comments would be in order.

The function it calls is "int abs(int)". So this first widens the int16
to int32, and then narrows the result from int32 to uint16.

The man page for abs() says "Trying to take the absolute value of the
most negative integer is not defined." That's OK in this case, because
that refers to the most negative int32 value, and the argument here is
int16. But that's why the pg_abs_s64(int64) function needs the special
check for the most negative value.

There's also some code in libpq's pqCheckOutBufferSpace() function that
could use these functions.

--
Heikki Linnakangas
Neon (https://neon.tech)

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Eisentraut 2024-08-14 07:03:55 macOS prefetching support
Previous Message Steven Niu 2024-08-14 06:35:39 Re: [Patch] remove duplicated smgrclose