In the compilers course that I teach at the University of Lisbon students have to implement a compiler for a given language, and generate LLVM IR. While students have the freedom to choose any language they wish for the compiler, Java is a popular choice due to their familiarity with the language.
One particular issue students had was to choose the right constant for a given floating-point number.
int main()
{
float a = 3.2;
float b = 3.9;
return 0;
}
is compiled to
define i32 @main() #0 {
%1 = alloca i32, align 4
%a = alloca float, align 4
%b = alloca float, align 4
store i32 0, i32* %1, align 4
store float 0x40099999A0000000, float* %a, align 4
store float 0x400F333340000000, float* %b, align 4
ret i32 0
}
Now the goal is to generate “0×40099999A0000000” from 3.2, “0×400F333340000000” from 3.9 and so on.
To solve this issue, I extracted and refactored code from Scala-Native, which you can find below.