llvm-gcc cannot emit @llvm.pow.* ?

Hi,

Current llvm-gcc cannot emit llvm intrinsic function like llvm.pow.* and llvm.sin.*
For example:

double foo(double x, double y) {
return pow(x,y);
}

will compiled into ll:

define double @foo(double %x, double %y) {
%tmp3 = tail call double @pow( double %x, double %y )
ret double %tmp3
}

This is not consistent with llvm language reference.

Hi,

Current llvm-gcc cannot emit llvm intrinsic function like llvm.pow.* and
llvm.sin.*
For example:

double foo(double x, double y) {
  return pow(x,y);
}

will compiled into ll:

define double @foo(double %x, double %y) {
   %tmp3 = tail call double @pow( double %x, double %y )
  ret double %tmp3
}

This is not consistent with llvm language reference.

first of all, this is logically wrong - the language reference
doesn't say anywhere that you *have* to use llvm.pow.* rather than
pow from the C library. Also, don't forget that the llvm intrinsics
don't set errno, so using them is only valid on systems/for languages
for which errno is ignored. That said, llvm.pow.* is for raising
to an integer power, and here you raise to a double power.

Ciao,

Duncan.

2007/11/22, Duncan Sands <baldrick@free.fr>:

Hi,

Current llvm-gcc cannot emit llvm intrinsic function like llvm.pow.* and
llvm.sin.*
For example:

double foo(double x, double y) {
return pow(x,y);
}

will compiled into ll:

define double @foo(double %x, double %y) {
%tmp3 = tail call double @pow( double %x, double %y )
ret double %tmp3
}

This is not consistent with llvm language reference.

first of all, this is logically wrong - the language reference
doesn’t say anywhere that you have to use llvm.pow.* rather than
pow from the C library.

Sure. But now the question is the llvm-gcc will not emit llvm.pow.* anytime.

Also, don’t forget that the llvm intrinsics
don’t set errno, so using them is only valid on systems/for languages
for which errno is ignored. That said, llvm.pow.* is for raising
to an integer power, and here you raise to a double power.

I don’t understand. why we can’t use llvm.pow.f64 for double power?

Sheng.

Hi,

Sure. But now the question is the llvm-gcc will not emit llvm.pow.* anytime.

indeed there seems to be no code in llvm-gcc to do so, though there is code for
raising to an integer power (in llvm-convert). Please feel free to investigate
and add some. Presumably it should turn gcc's BUILT_IN_POW into llvm.pow.*.
That said, as far as I can see the C front-end doesn't generate BUILT_IN_POW
at all, though the fortran and java front-ends do. It is true that the gcc
constant folder can fold x*x to pow(x, 2.0) but this has been turned off in
llvm-gcc (PR1631); in any case this is not what you are looking for. So it
seems to me that the first question to answer is: why doesn't gcc itself use
the gcc pow builtin for C?

Also, don't forget that the llvm intrinsics
> don't set errno, so using them is only valid on systems/for languages
> for which errno is ignored. That said, llvm.pow.* is for raising
> to an integer power, and here you raise to a double power.

I don't understand. why we can't use llvm.pow.f64 for double power?

Sorry, I was confusing with powi.

Ciao,

Duncan.

PS: It is possible that the C front-end doesn't need to
explicitly produce BUILT_IN_POW because it is auto-synthesized
somehow from a call to "pow". I wouldn't know. One way to
find out is to compile a testcase and rummage around inside
the gcc trees when they hit llvm-convert.

Hi,

2007/11/22, Duncan Sands <baldrick@free.fr>:

PS: It is possible that the C front-end doesn’t need to
explicitly produce BUILT_IN_POW because it is auto-synthesized
somehow from a call to “pow”. I wouldn’t know. One way to
find out is to compile a testcase and rummage around inside
the gcc trees when they hit llvm-convert.

Yes, they do hit llvm-convert. I created function EmitBuiltinPOW() in llvm-convert.cpp and
add case BUILT_IN_POW to EmitBuiltinCall . Testcase result shows it will call EmitBuiltinCall and finally emit llvm.pow.*

Sheng.

Yes, they do hit llvm-convert. I created function EmitBuiltinPOW() in
llvm-convert.cpp and
add case BUILT_IN_POW to EmitBuiltinCall . Testcase result shows it will
call EmitBuiltinCall and finally emit llvm.pow.*

Don't forget that pow(x,y) will set errno if x is negative and y is not an
integral value. Thus it is only correct to convert to llvm.pow.* if
!flag_errno_math, like for the sqrt case.