[llvm-bugs] [Bug 29041] Incorrect conversion from float to char to int

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Aug 19 02:13:01 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=29041

James Molloy <james.molloy at arm.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #6 from James Molloy <james.molloy at arm.com> ---
This is slightly more involved; I'm going to resolve this as FIXED but actually
your testcase has undefined behaviour.

Your case converts a float directly to an unsigned char, which has undefined
behaviour on overflow. It is therefore correct to assume the result of the
FP-to-UI conversion leaves the uppermost 24 bits zeroed.

Now, we were doing a faulty transform where we converted the FP-to-UINT into a
FP-to-SINT and then not informing the rest of the optimizer that the resulting
int was sign extended not zero extended. This resulted in:

  fcvtzs w0, s0
  ret

Fixing this bug causes the expected output:

  fcvtzs w0, s0
  and w0, w0, #0xff
  ret

However, we're only doing that mask because we've decided to create a signed
conversion. If we undo that dodgy heuristic, we produce an unsigned conversion:

  fcvtzu w0, s0
  ret // Note no mask!

We don't need to mask because conversion from float->uint8_t is undefined if
the integer part of the float value is not representable in uint8_t. Therefore
we can assume this doesn't happen!

If you want the explicit mask (perhaps because you want to handle out of range
inputs by truncating mod 256), you should make the conversion convert from
float to uint32_t then truncate that:

  unsigned char charVal = (unsigned char)(unsigned int)infloatVal;

This then produces:

  fcvtzu w0, s0
  and w0, w0, #0xff
  ret

(Note, the above is with the dodgy heuristic fixed which isn't in trunk. So you
will just see the signed conversion and the mask as above which *does work* for
your case but only because the compiler is doing something stupid and shouldn't
be relied upon).

Cheers,

James

Codegen fix in r279223.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160819/5d85dc1e/attachment.html>


More information about the llvm-bugs mailing list