From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Peter Eisentraut <peter_e(at)gmx(dot)net> |
Cc: | Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>, Noah Misch <noah(at)leadboat(dot)com>, Michael Paquier <michael(dot)paquier(at)gmail(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: [COMMITTERS] pgsql: Add trigonometric functions that work in degrees. |
Date: | 2016-04-25 23:13:16 |
Message-ID: | 21507.1461625996@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-committers pgsql-hackers |
Peter Eisentraut <peter_e(at)gmx(dot)net> writes:
> On 04/25/2016 03:09 PM, Tom Lane wrote:
>> I'm going to go ahead and push this, because it seems clearly more robust
>> than what we have. But I'd appreciate a report on whether it fixes your
>> issue.
> 6b1a213bbd6599228b2b67f7552ff7cc378797bf did not fix it.
OK ... but it's still a good change, because it removes the assumption
that the compiler won't inline init_degree_constants().
> Attached is the assembler output (-O0) from float.c as of that commit.
Ah. Here's the problem: line 1873 is
return (asin(x) / asin_0_5) * 30.0;
and that compiles into
subl $8, %esp
pushl -12(%ebp) ... push x
pushl -16(%ebp)
call asin ... call asin()
addl $16, %esp
fldl asin_0_5 ... divide by asin_0_5
fdivrp %st, %st(1)
fldt .LC46 ... multiply by 30.0
fmulp %st, %st(1)
fstpl -24(%ebp) ... round to 64 bits
fldl -24(%ebp)
Evidently, asin() is returning an 80-bit result, and that's not
getting rounded to double width before we divide by asin_0_5.
The least ugly change that might fix this is to explicitly cast the
result of asin to double:
return ((float8) asin(x) / asin_0_5) * 30.0;
However, I'm not certain that that would do anything; the compiler
might feel that the result of asin() is already double. The next
messier answer is to explicitly store the function result in a local
variable:
{
float8 asin_x = asin(x);
return (asin_x / asin_0_5) * 30.0;
}
A sufficiently cavalier compiler might choose to optimize that away,
too. A look at gcc's manual suggests that we might need to use
the -ffloat-store option to guarantee it will work; which is ugly
and I'd prefer not to turn that on globally anyway. If it comes to
that, probably the better answer is to turn asin_x into a global
variable, similarly to what we just did with the constants.
Can you try the above variants of line 1873 and see if either of them
fixes the issue for you?
regards, tom lane
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2016-04-26 03:25:54 | Re: [COMMITTERS] pgsql: Add trigonometric functions that work in degrees. |
Previous Message | Peter Eisentraut | 2016-04-25 21:18:01 | pgsql: pg_dump: Message style improvements |
From | Date | Subject | |
---|---|---|---|
Next Message | Bruce Momjian | 2016-04-25 23:18:12 | Re: Is there a way around function search_path killing SQL function inlining? |
Previous Message | Stephen Frost | 2016-04-25 22:55:28 | Re: SET ROLE and reserved roles |