[LLVMdev] FP emulation (continued)

Chris Lattner sabre at nondot.org
Tue Nov 28 11:08:48 PST 2006


On Tue, 28 Nov 2006, Roman Levenstein wrote:
> Yes. I have done almost all of that already a while ago and it solves
> almost all problems, as you say. But the problem is a code like:

ok
> float f;
> float float_addition(float a, float b) {
>  return a+b;
> }
>
> which is translated by LLVM into:
>
> target endian = little
> target pointersize = 32
> target triple = "i686-pc-linux-gnu"
> deplibs = [ "c", "crtend" ]
> %f = weak global float 0.000000e+00		; <float*> [#uses=0]
>
> implementation   ; Functions:
>
> float %float_addition(float %a, float %b) {
> entry:
> 	%tmp.2 = add float %a, %b		; <float> [#uses=1]
> 	ret float %tmp.2
> }

Right.

> The global variable f is still considered to be "float" and therefore
> occupies 4 bytes and handled as a 32bit float. Due to expansion from
> f32 to f64, codegen tries to load it from a 32bit memory cell and then
> expand into f64. But I have no 32bit FP type on my target and no 32bit
> FP representation in memory. So, I really want "float" to be just an
> alias for "double". "f" should be trated in the same way, as if it is a
> 64bit double. This was the reason, why I asked if something should be
> done in the front-end to achieve this, additionally to the actions that
> you describe. Or may be there is a way to have an LLVM pass that just
> traverses the module and changes the types of all float variables to
> double?

There are two ways to do it.  First, you could modify llvm-gcc for your 
target to say that sizeof(float) == sizeof(double).  I don't recommend 
this strategy though.

The second way to do this is to implement an "extending load" instruction. 
This instruction allows your target to load a 32-bit FP value from memory 
and do an implicit extension to f64.  You can implement this with a 
libcall of course.

-Chris

-- 
http://nondot.org/sabre/
http://llvm.org/



More information about the llvm-dev mailing list