www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - FP magic in std.math.pow

reply Seb <seb wilzba.ch> writes:
Consider this short program:

void main()
{
     alias S = float;
     S s1 = 0x1.24c92ep+5;
     S s2 = -0x1.1c71c8p+0;

     import std.math : std_pow = pow;
     import core.stdc.stdio : printf;
     import core.stdc.math: powf;

     printf("std: %a\n", std_pow(s1, s2));
     printf("pow: %a\n", s1 ^^ s2);
     printf("pow: %a\n", powf(s1, s2));

     version(LDC)
     {
         import ldc.intrinsics : llvm_pow;
         printf("ldc: %a\n", llvm_pow(s1, s2));
     }
}

std: 0x1.2c155ap-6
pow: 0x1.2c155ap-6
powf: 0x1.2c1558p-6

As you can see below the C powf compiles to the assembly powf and 
LDC compiles to powf too. The output of std.math.pow is rather 
large, hence not listed.

1) Is this a bug in Phobos or just a very annoying "feature"?
2) I thought that DMD was decoupled from Phobos? So I was very 
astonished to see that it's not (see [1])

[1] 
https://github.com/dlang/dmd/blob/master/src/expression.d#L14781

```
.text._Dmain	segment
	assume	CS:.text._Dmain
_Dmain:
		push	RBP
		mov	RBP,RSP
		sub	RSP,010h
		movss	XMM0,FLAT:.rodata[00h][RIP]
		movss	-8[RBP],XMM0
		movss	XMM1,FLAT:.rodata[00h][RIP]
		movss	-4[RBP],XMM1
		movss	XMM1,-4[RBP]
		movss	XMM0,-8[RBP]
		call	  powf PC32
		cvtss2sd	XMM0,XMM0
		mov	EDI,offset FLAT:.rodata 32
		mov	AL,1
		call	  printf PC32
		xor	EAX,EAX
		leave
		ret
		0f1f
		add	0[RCX],AL
.text._Dmain	ends
```
Jul 31 2016
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Sunday, 31 July 2016 at 22:38:59 UTC, Seb wrote:
 Consider this short program:

 void main()
 {
     alias S = float;
     S s1 = 0x1.24c92ep+5;
     S s2 = -0x1.1c71c8p+0;

 [...]
It's an anoying feature. The reason this is not implemented in dmd is that pow does not map to a simple cpu instruction on x86. I will have another shot at fixing this once the CTFE stuff is in.
Jul 31 2016
parent Seb <seb wilzba.ch> writes:
On Sunday, 31 July 2016 at 22:45:16 UTC, Stefan Koch wrote:
 On Sunday, 31 July 2016 at 22:38:59 UTC, Seb wrote:
 Consider this short program:

 void main()
 {
     alias S = float;
     S s1 = 0x1.24c92ep+5;
     S s2 = -0x1.1c71c8p+0;

 [...]
It's an anoying feature. The reason this is not implemented in dmd is that pow does not map to a simple cpu instruction on x86. I will have another shot at fixing this once the CTFE stuff is in.
It's about 1000 instructions with std.math.pow. Yeah any improvement of the FP magic in DMD would be highly appreciated ;-)
Aug 01 2016