[llvm-commits] (half precision) [llvm] r84239 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp

Peter Johnson johnson.peter at gmail.com
Wed Oct 21 21:41:00 PDT 2009


On Wed, Oct 21, 2009 at 5:29 PM, Chris Lattner <clattner at apple.com> wrote:
>
> On Oct 20, 2009, at 5:23 PM, Dale Johannesen wrote:
>
>> Some testcases to exercise basic functionality would be nice.  I think
>> there is a bug here that should have shown up in testing.
>
> Peter, can you take a look at Dale's feedback?
>
> -Chris

Dale is quite correct.  I had caught the 0x1f cleanup (see my bug 5195
comment) but had missed the >>10 bug.

Agreed that unit tests would be good.  There don't seem to be any
APFloat unit tests for APInt conversions.  I'll work on writing some
for the half precision case but probably won't try to tackle the full
complement.  Should I just add them to the unittest/ADT/APFloat.cpp
file?

-Peter

>
>>
>> On Oct 15, 2009, at 7:13 PM, Chris Lattner wrote:
>>>
>>> +APInt
>>> +APFloat::convertHalfAPFloatToAPInt() const
>>> +{
>>> +  assert(semantics == (const llvm::fltSemantics*)&IEEEhalf);
>>> +  assert (partCount()==1);
>>> +
>>> +  uint32_t myexponent, mysignificand;
>>> +
>>> +  if (category==fcNormal) {
>>> +    myexponent = exponent+15; //bias
>>> +    mysignificand = (uint32_t)*significandParts();
>>> +    if (myexponent == 1 && !(mysignificand & 0x400))
>>> +      myexponent = 0;   // denormal
>>> +  } else if (category==fcZero) {
>>> +    myexponent = 0;
>>> +    mysignificand = 0;
>>> +  } else if (category==fcInfinity) {
>>> +    myexponent = 0xff;
>>
>> 0x1f (doesn't matter functionally, but cleaner)
>>
>>> +    mysignificand = 0;
>>> +  } else {
>>> +    assert(category == fcNaN && "Unknown category!");
>>> +    myexponent = 0xff;
>>
>> 0x1f
>>
>>> +    mysignificand = (uint32_t)*significandParts();
>>> +  }
>>> +
>>> +  return APInt(16, (((sign&1) << 15) | ((myexponent&0x1f) << 10) |
>>> +                    (mysignificand & 0x3ff)));
>>> +}
>>> +
>>
>>
>>
>>> +void
>>> +APFloat::initFromHalfAPInt(const APInt & api)
>>> +{
>>> +  assert(api.getBitWidth()==16);
>>> +  uint32_t i = (uint32_t)*api.getRawData();
>>> +  uint32_t myexponent = (i >> 15) & 0x1f;
>>
>> Bug: should be >> 10
>>
>>> +  uint32_t mysignificand = i & 0x3ff;
>>> +
>>> +  initialize(&APFloat::IEEEhalf);
>>> +  assert(partCount()==1);
>>> +
>>> +  sign = i >> 15;
>>> +  if (myexponent==0 && mysignificand==0) {
>>> +    // exponent, significand meaningless
>>> +    category = fcZero;
>>> +  } else if (myexponent==0x1f && mysignificand==0) {
>>> +    // exponent, significand meaningless
>>> +    category = fcInfinity;
>>> +  } else if (myexponent==0x1f && mysignificand!=0) {
>>> +    // sign, exponent, significand meaningless
>>> +    category = fcNaN;
>>> +    *significandParts() = mysignificand;
>>> +  } else {
>>> +    category = fcNormal;
>>> +    exponent = myexponent - 15;  //bias
>>> +    *significandParts() = mysignificand;
>>> +    if (myexponent==0)    // denormal
>>> +      exponent = -14;
>>> +    else
>>> +      *significandParts() |= 0x400; // integer bit
>>> +  }
>>> +}
>>> +
>>> /// Treat api as containing the bits of a floating point number.
>>> Currently
>>> /// we infer the floating point type from the size of the APInt.  The
>>> /// isIEEE argument distinguishes between PPC128 and IEEE128 (not
>>> meaningful
>>> @@ -3058,7 +3124,9 @@
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>




More information about the llvm-commits mailing list