From: Thomas Koenig on
On 2009-09-12, Dan Nagle <dannagle(a)verizon.net> wrote:

> Division by a constant, on modern compilers, it is almost always
> replaced by multiplication by the reciprocal.

gcc/gfortran doesn't do that, even with -ffast-math.

Do you think it should?

Here's an example, BTW:

$ cat divide.f90
subroutine divide(a, b)
real, dimension(2), intent(inout) :: a
real, intent(in) :: b
a(1) = a(1) / b
a(2) = a(2) / b
$ gfortran -O3 -ffast-math -march=native -mfpmath=sse -msse -S divide.f90
$ cat divide.s
.file "divide.f90"
.text
.p2align 4,,15
..globl divide_
.type divide_, @function
divide_:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
movss (%eax), %xmm0
movss (%edx), %xmm1
divss %xmm1, %xmm0
movss %xmm0, (%eax)
movss 4(%eax), %xmm0
divss %xmm1, %xmm0
movss %xmm0, 4(%eax)
leave
ret
From: nmm1 on
In article <slrnhan5od.4p3.tkoenig(a)meiner.onlinehome.de>,
Thomas Koenig <tkoenig(a)netcologne.de> wrote:
>On 2009-09-12, Dan Nagle <dannagle(a)verizon.net> wrote:
>
>> Division by a constant, on modern compilers, it is almost always
>> replaced by multiplication by the reciprocal.
>
>gcc/gfortran doesn't do that, even with -ffast-math.
>
>Do you think it should?

Yes, I do. Strongly. Inter alia, it's arguably a bug not to so so.

-ffast-math sets -funsafe-math-optimizations, the latter sets
-freciprocal-math, and the last is specified to do precisely this.


Regards,
Nick Maclaren.
From: Tim Prince on
robin wrote:
> "Tim Prince" <tprince(a)nospamcomputer.org> wrote in message news:7gsp7pF2qhnrlU1(a)mid.individual.net...
> | Dan Nagle wrote:
> | > Hello,
> | >
> | > On 2009-09-10 06:51:39 -0400, "robin" <robin_v(a)bigpond.com> said:
> | >
> | >> There's no requirement to do any conversion at compile time.
> | >> x/2 can be done at execution time on certain computers
> | >> not by division but by scaling (and at considerable saving in time).
> | >
> | > Masking out the exponent, shifting, subtracting one,
> | > and merging the new exponent back into the original number
> | > may well take longer than one multiplication
> | > on modern hardware.
>
> | Not to mention checking for over/underflow.
>
> A test for underflow has to be performed regardless of whether
> actual division or simple halving is performed. That observation
> therefore is irrelevant.
A divide operation takes care of possible underflow. Subtracting from
the exponent field without checking against limits may wrap the result
around past HUGE. Since formats such as infinities and sub-normals were
introduced (over 25 years ago), more cases of failure for such shortcuts
have been present.

>
> | The compiler I learned on
> | generated code for /2. which jumped over the subtraction from the
> | exponent in the case of a 0. operand but didn't take care of all corner
> | cases.
>
> What machine was that?
>
>
On the Honeywell 6000 series, x/2. would not fail, but x/4. would
produce HUGE(x) if x==TINY(x). Of course, there were no TINY or HUGE;
they gave up after a partial implementation of f77.
From: steve on
On Sep 12, 5:41 am, Thomas Koenig <tkoe...(a)netcologne.de> wrote:
> On 2009-09-12, Dan Nagle <danna...(a)verizon.net> wrote:
>
> > Division by a constant, on modern compilers, it is almost always
> > replaced by multiplication by the reciprocal.
>
> gcc/gfortran doesn't do that, even with -ffast-math.

Read what Dan wrote. "Division by a constant".

REMOVE:kargl[79] cat jo.f90
subroutine divide(a)
real, dimension(2), intent(inout) :: a
a(1) = a(1) / 2
a(2) = a(2) / 2

fc4x -c -ffast-math -O2 -save-temps jo.f90

divide_:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
flds .LC0
flds (%eax)
fmul %st(1), %st
fstps (%eax)
fmuls 4(%eax)
fstps 4(%eax)
leave
ret

Note, you can change the 2 to any floating point number you like.
You still get to fmul.


--
steve
From: glen herrmannsfeldt on
Dan Nagle <dannagle(a)verizon.net> wrote:
(snip, someone wrote)

<> Multipliocation? whio said anything about multiplication?
<> The operation is DIVISION here.

< Division by a constant, on modern compilers, it is almost always
< replaced by multiplication by the reciprocal.

< I thought you knew that.

Floating point multiplication by a constant might round differently
than division. Many will consider that reasonable.

In fixed point, you can multiply be a reciprocal and take the high
half of the product. The result is properly truncated for many but
not all divisors. As people depend on exact results for fixed point
divide, compilers better get that one right.

-- glen