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.