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

Chris Lattner clattner at apple.com
Wed Oct 21 21:51:39 PDT 2009


On Oct 21, 2009, at 9:41 PM, Peter Johnson wrote:

> 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?

Sounds great to me, thanks Peter!

-Chris

>
> -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