[LLVMdev] interesting IR problem related to mips 16

reed kotler rkotler at mips.com
Wed Apr 17 16:11:48 PDT 2013


When a mips16 wants to return a floating point value, it's at a quandary 
in mixed mode programs (having both mips16 and mips32 code).

float foo() {
   return 1.0;
}

Mips16 code is compiled in soft float, with there being an options to 
have the emulation library be written in mips32 and use floating point 
instructions in those mips32 support functions (if the machine supports 
floating point) but in any case, Mips16 is always using soft float (this 
optional emulation library you get with -hard-float for mips16 and is 
the default).

So if the code returns a float, it will get converted into returning an 
integer which in mips abi means it will be returned in an integer register.

so it becomes:
int foo() {
   return int_representation(1.0);
}

However, mips32 code calling this is compiled without soft float and 
does not know anything about this. and will expect the return result to 
be in F0.

So gcc will generate a call to a helper function that moves the V0 
integer return register, to F0 (the floating point return register) 
before returning.

further transformation:
int foo() {
   helper_function(1.0);
   return int_representation(1.0);
}

So now, no matter whether a mips16 or mips32 function calls foo, it will 
be able to retrieve the return result.

The problem is that the helper_function has an important side effect, 
i.e. it sets the value of f0 but this is not reflected in the IR.

so if foo had been changed to:

float x, y, z;
float foo() {
   float x = y + z;
   return 1.0;
}

now if we convert to

float x,y,z;
float foo() {
   softfloat(x=y+z)
   helper_function(1.0);
   return int_representation(1.0);
}

During optimization , this could get converted to:
float x,y,z;
float foo() {
   helper_function(1.0);
   softfloat(x=y+z)
   return int_representation(1.0);
}


Because there is no dependency preventing this.

now the side effect of the helper function will be destroyed by the 
execution of x = y + z;

There is no "glue" between the call to the helper function and return 
statement.

Any ideas how to do what I want in the IR as opposed to the DAG?

TIA.

Reed





More information about the llvm-dev mailing list