I find it difficult to understand the difference between the LLVM-IR instructions "fptosi ... to" and "fptoui ... to".
I wrote an example program to better understand the semantics of these instructions.
#include <stdio.h>
int main(int argc, char** argv)
{
double d = -3.5 - 4;
unsigned int ui = (unsigned int) d;
int si = (int) d;
printf("unsigned %u, 0x%x\n", ui, ui);
printf("signed %i, 0x%x\n", si, si);
return 0;
}
As expected, clang generates these two kinds of instructions
...
%5 = fptoui double %4 to i32
store i32 %5, i32* %ui, align 4
%6 = load double* %d, align 8
%7 = fptosi double %6 to i32
store i32 %7, i32* %si, align 4
...
When the program starts, the output:
unsigned 4294967289, 0xfffffff9
signed -7, 0xfffffff9
which means that both instructions produce the same value (only in one case is the value later interpreted as signed and the other interpreted as unsigned)
The LLVM IR documentation states:
The 'fptoui' command converts its floating point operand to the nearest (rounding to zero) unsigned integer value.
Is the nearest unsigned integer for a negative double 0? Does anyone know when these instructions have different semantics?