[LLVMdev] Casting from float to unsigned char - incorrect output?

Richard Smith richard at metafoo.co.uk
Mon Aug 6 14:33:16 PDT 2012


This should work if your float is between INT_MIN and INT_MAX:

unsigned char trunc(float f) {
  return (unsigned char)(int)f;
}

int main() {
  printf("%d\n", trunc(-1.0));
}

For this, Clang produces:

trunc:
trunc.w.s $f0, $f12
mfc1 $2, $f0
andi $2, $2, 255
jr $ra
nop

On Mon, Aug 6, 2012 at 1:28 PM, ryan baird <ryanrbaird at gmail.com> wrote:

> I didn't realize the code was undefined, I'll let my professor know; but
>> for code comparison purposes we're still seeking advice on producing the
>> output that matches the other compilers (even if it involves doing a
>> translation on the .ll file or additional translation to the produced
>> assembly).  We can't fairly compare the code if it doesn't do the same
>> thing.  This bug came up in susan from the mibench test suite at the end of
>> setup_brightness_lut where it casts float temp to an unsigned char.  I
>> don't think we can include the results in our report if we change the tests.
>>
>> Even though the behavior is undefined, it doesn't make sense to me that a
>> function that returns an unsigned char would ever return a 32 bit -1,
>> because that value does not fit the functions return type.
>>
>>
>> On Mon, Aug 6, 2012 at 2:03 PM, Eli Friedman <eli.friedman at gmail.com>wrote:
>>
>>> On Mon, Aug 6, 2012 at 12:43 PM, ryan baird <ryanrbaird at gmail.com>
>>> wrote:
>>> > I am compiling the following code for the MIPS architecture:
>>> >
>>> > unsigned char trunc(float f) {
>>> >         return (unsigned char) f;
>>> > }
>>> >
>>> > and it produces the following assembly (directives removed for
>>> convenience:
>>> > trunc:
>>> >     trunc.w.s    $f0, $f12
>>> >     mfc1    $2, $f0
>>> >     jr    $ra
>>> >     nop
>>> >
>>> > However, this does not seem to produce the correct output for negative
>>> > numbers. When I run the following code, I get -1 instead of 255 (which
>>> is
>>> > produced by compiling natively with gcc).
>>> > int trunc(float c);
>>> > int main() {
>>> >   printf("%d\n", trunc(-1.0));
>>> > }
>>>
>>> That code has undefined behavior; see 6.3.1.4p1 in C99
>>>
>>> -Eli
>>>
>>
>>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120806/22b2f363/attachment.html>


More information about the llvm-dev mailing list