Hi,
On the "Fix right() with the most negative integer" thread [1], Dagfinn
Ilmari Mannsåker noted that several places still guard negating the most
negative value with a hand-written "x == PG_INTnn_MIN" test rather than
the pg_neg_s{16,32,64}_overflow() helpers in int.h, and David Rowley
suggested cleaning them up separately. Here is that patch.It converts the open-coded negation-overflow checks in the integer, bigint and money types: - unary minus: int2um, int4um, int8um - abs: int2abs, int4abs, int8abs - divide by -1: int2div, int4div, int42div, int8div, int84div, int82div - lcm: int4lcm, int8lcm - money: cash_div_int64, cash_in - numeric: numericvar_to_int64 int?gcd_internal() is left alone: its "if (arg < 0) arg = -arg;" runs only after INT_MIN has already been rejected. text_right() is another such site but is being fixed as a bug on [1] (with the plain test, since pg_neg_s32_overflow() only exists from v18); I'll fold it in once that lands in master. No behavioral change: each site keeps its existing hard- or soft-error path. On how the non-HAVE__BUILTIN_OP_OVERFLOW path was checked: I built with that macro commented out in pg_config.h, so the calls compile through int.h's #else fallback (objdump confirms int4um then emits the explicit "cmp $0x80000000; je" rather than the builtin's "jo"), and the int2/int4/int8/money/numeric regression tests pass on that build. The fallback is byte-for-byte the "if (a == PG_INTnn_MIN) ...; -a" it replaces, so those builds are unchanged. Where the builtin is available the code is identical or one instruction shorter (the negate sets OF, so "jo" replaces the separate compare), so there is no performance downside. [1] https://www.postgresql.org/message-id/flat/caon2xhnnbz-acpjgdmd5_39+8qr5aukezk4x3zm-0zdsatn...@mail.gmail.com -- Regards, Ewan Young
v1-0001-Use-pg_neg_s-16-32-64-_overflow-for-open-coded-negat.patch
Description: Binary data
