fptoui vs fptosi

Hi,

I hope this is the right mailing-list to post this question to.

It is about the LLVM instructions fptoui and fptosi. I’m not entirely clear on the difference between these two instructions.

I wrote a little test-program and compiled it

#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 I expected, this resulted in the generation of both 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 is executed, the output is

unsigned 4294967289, 0xfffffff9
signed -7, 0xfffffff9

so both instructions produce the same result value.

The LLVM IR documentation states: “The ‘fptoui‘ instruction converts its floating point operand into the nearest (rounding towards zero) unsigned integer value.”

Wouldn’t the nearest unsigned integer for a negative value be 0? Or is this undefined behavior?

It would be helpful if someone could clarify for me, in which cases the two instructions produce different results.

Regards,
Andreas Gruenwald

Hi Andreas,

Wouldn't the nearest unsigned integer for a negative value be 0? Or is this
undefined behavior?

Yep, undefined behaviour (mostly), the next sentence is: "If the value
cannot fit in ty2, the results are undefined.". And negative numbers
certainly can't fit into an unsigned value.

It's modelled after C's restrictions (naturally enough); the wording
there is slightly better: "When a finite value of real floating type
is converted to an integer type other than _Bool, the fractional part
is discarded (i.e., the value is truncated toward zero). If the value
of the integral part cannot be represented by the integer type, the
behavior is undefined.)".

Interestingly, this means that values in the range (-1,0) are required
to convert to 0.

It would be helpful if someone could clarify for me, in which cases the two
instructions produce different results.

I believe they will never produce different results on their common domain.

Cheers.

Tim.