leonardchan added inline comments.

================
Comment at: include/clang/Basic/TargetInfo.h:89
+  // corresponding unsaturated types.
+  unsigned char ShortAccumFBits, ShortAccumIBits;
+  unsigned char AccumFBits, AccumIBits;
----------------
ebevhan wrote:
> leonardchan wrote:
> > ebevhan wrote:
> > > leonardchan wrote:
> > > > ebevhan wrote:
> > > > > I suspect it's still possible to calculate the ibits based on the 
> > > > > fbits, even for _Accum.
> > > > > 
> > > > > Are the unsigned values needed? The fbits for unsigned _Fract are the 
> > > > > same as for signed _Fract if SameFBits is set, and +1 otherwise. The 
> > > > > same should go for unsigned _Accum, but I don't think it's entirely 
> > > > > clear how this affects the integral part.
> > > > Similar to the previous comment, if we choose to make SameFBits 
> > > > dependent on/controlled by the target, then I think it would be better 
> > > > for the target to explicitly specify the integral bits since there 
> > > > could be some cases where there may be padding (such as for unsigned 
> > > > _Accum types if this flag is set), and in this case, I think it should 
> > > > be explicit that the `bit_width != IBits + FBits`.
> > > > 
> > > > We also can't fill in that padding for the unsigned _Accum types as an 
> > > > extra integral bit since the standard says that `"each signed accum 
> > > > type has at least as many integral bits as its corresponding unsigned 
> > > > accum type".`
> > > > 
> > > > For the unsigned _Fract values, I think we can get rid of them if we 
> > > > choose to keep the flag instead, but it would no longer apply to 
> > > > unsigned _Accum types since it would allow for extra padding in these 
> > > > types and would conflict with the logic of `bit_width == IBits + FBits`
> > > > 
> > > > For now, I actually think the simplest option is to keep these target 
> > > > properties, but have the target override them individually, with checks 
> > > > to make sure the values adhere to the standard.
> > > Is it not the case that `bitwidth != IBits + FBits` for signed types 
> > > only? Signed types require a sign bit (which is neither a fractional bit 
> > > nor an integral bit, according to spec) but unsigned types do not, and if 
> > > IBits and FBits for the signed and unsigned types are the same, the MSB 
> > > is simply a padding bit, at least for _Accum (for _Fract everything above 
> > > the fbits is padding). 
> > > 
> > > My reasoning for keeping the number of configurable values down was to 
> > > limit the number of twiddly knobs to make the implementation simpler. 
> > > Granting a lot of freedom is nice, but I suspect that it will be quite 
> > > hard to get the implementation working properly for every valid 
> > > configuration. I also don't really see much of a reason for `FBits != 
> > > UFBits` in general. I know the spec gives a recommendation to implement 
> > > it that way, but I think the benefit of normalizing the signed and 
> > > unsigned representations outweighs the lost bit in the unsigned type.
> > > 
> > > It's hard to say what the differences are beyond that since I'm not sure 
> > > how you plan on treating padding bits. In our implementation, padding 
> > > bits (the MSB in all of the unsigned types for us) after any operation 
> > > are zeroed.
> > I see. The implementation would be much simpler this way. The initial idea 
> > was to treat the padding bits as "don't care" bits where we would mask only 
> > the data bits when doing operations like comparisons that look at the whole 
> > integer.
> That does work, but for binary operations it means you might need multiple 
> maskings per operation. If you mask after every operation instead, you only 
> need one. In our implementation, the only padding bit we have is the MSB in 
> the unsigned types. We simply insert a 'bit clear' after every operation that 
> produces an unsigned type (with some exceptions).
> 
> The E-C spec says that padding bits are 'unspecified', but 
> implementation-wise, they have to be defined to something in order to operate 
> on them. So long as you ensure that it is never possible to observe anything 
> but zero in those bits from a program perspective, most operations just work. 
> Naturally, there are ways to subvert this design. If you have a `signed 
> _Fract *` and cast it to an `unsigned _Fract *` and the values happen to be 
> negative, the padding bit will be set and you'll get exciting behavior.
> 
> Although... I just realized that the topmost half of the `_Fract`s in your 
> configuration is all padding. That might make things a bit more complicated 
> for things like signed types... Ideally the sign bit would be extended into 
> the padding for those.
Yeah, I initially had 2 general purpose ideas for handling the padding:

- Zero/sign extend them after all operations that modify the value (+, *, <<, 
casting to 
 another type, ...). This way we know the sign part of a fixed point type, 
regardless of how much padding there is would, always extend to the padding and 
sign bit of the underlying scaled integer.
- Masking only the data and sign bits before all operations that read the value 
and don't modify it (==, !=, <, ...). This way we only compare the non-padding 
bits whenever performing operations that require reading all bits in the 
underlying integer.

I wanted to choose the method that addressed operations fixed point types would 
least likely be used for, that is would these types be generally used more for 
arithmetic or comparisons. I chose the second method, but don't have any strong 
evidence to support this. This is also what the later patches implement but can 
be reworked.


================
Comment at: lib/AST/ExprConstant.cpp:9437
+      }
+      return Success(-Value, E);
+    }
----------------
ebevhan wrote:
> This looks very suspect to me as well... This might not respect padding on 
> types whose sign bit is not the MSB, such as _Fract. The same goes for the 
> overflow check above.
> 
> I think it's quite important that we define the semantics of what padding 
> bits should contain. Probably zeroes for unsigned types and a sexted sign bit 
> for signed types.
Initially I had the _Accum and their corresponding _Fract types the same widths 
to avoid casting between _Accums to a different sized _Fract (`ie short _Fract 
to short _Accum`), but after thinking about it, it might be simpler in the end 
to just have the _Fract widths have half as much as the _Accum width and have 
the fractional bits be one less the width (unless SameFBits is set in which 
case there will still be only 1 padding).

This would also reduce the number of knobs that would be tweaked for different 
targets and help cover this case by effectively ignoring the padding bits.


Repository:
  rC Clang

https://reviews.llvm.org/D46915



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to