[PATCH] D53738: [Fixed Point Arithmetic] Fixed Point Addition
Bevin Hansson via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 3 05:55:26 PST 2018
ebevhan added inline comments.
================
Comment at: clang/lib/Sema/SemaExpr.cpp:1304
+ RHSTy = ResultTy;
+ }
+
----------------
rjmccall wrote:
> leonardchan wrote:
> > rjmccall wrote:
> > > ebevhan wrote:
> > > > rjmccall wrote:
> > > > > Hmm. So adding a signed integer to an unsigned fixed-point type always converts the integer to unsigned? That's a little weird, but only because the fixed-point rule seems to be the other way. Anyway, I assume it's not a bug in the spec.
> > > > `handleFixedPointConversion` only calculates the result type of the expression, not the calculation type. The final result type of the operation will be the unsigned fixed-point type, but the calculation itself will be done in a signed type with enough precision to represent both the signed integer and the unsigned fixed-point type.
> > > >
> > > > Though, if the result ends up being negative, the final result is undefined unless the type is saturating. I don't think there is a test for the saturating case (signed integer + unsigned saturating fixed-point) in the SaturatedAddition tests.
> > > > `handleFixedPointConversion` only calculates the result type of the expression, not the calculation type.
> > >
> > > Right, I understand that, but the result type of the expression obviously impacts the expressive range of the result, since you can end up with a negative value.
> > >
> > > Hmm. With that said, if the general principle is to perform the operation with full precision on the original operand values, why are unsigned fixed-point operands coerced to their corresponding signed types *before* the operation? This is precision-limiting if the unsigned representation doesn't use a padding bit. That seems like a bug in the spec.
> > > Hmm. With that said, if the general principle is to perform the operation with full precision on the original operand values, why are unsigned fixed-point operands coerced to their corresponding signed types *before* the operation? This is precision-limiting if the unsigned representation doesn't use a padding bit. That seems like a bug in the spec.
> >
> > Possibly. When the standard mentions converting from signed to unsigned fixed point, the only requirement involved is conservation of magnitude (the number of integral bits excluding the sign)
> >
> > ```
> > when signed and unsigned fixed-point types are mixed, the unsigned type is converted to the corresponding signed type, and this should go without loss of magnitude
> > ```
> >
> > This is just speculation, but I'm under the impression that not as much "attention" was given for unsigned types as for signed types since "`In the embedded processor world, support for unsigned fixed-point data types is rare; normally only signed fixed-point data types are supported`", but was kept anyway since unsigned types are used a lot.
> >
> > ```
> > However, to disallow unsigned fixed-point arithmetic from programming languages (in general, and from C in particular) based on this observation, seems overly restrictive.
> > ```
> >
> > I also imagine that if the programmer needs more precision, the correct approach would be to cast up to a type with a higher scale. The standard seems to make an effort to expose as much in regards to the underlying fixed point types as possible:
> >
> > ```
> > it should be possible to write fixed-point algorithms that are independent of the actual fixed-point hardware support. This implies that a programmer (or a running program) should have access to all parameters that define the behavior of the underlying hardware (in other words: even if these parameters are implementation-defined).
> > ```
> >
> > So the user would at least know that unsigned types may not have the same scale as their corresponding signed types if the hardware handles them with different scales.
> >
> > Also added test for signed integer + unsigned saturating fixed point.
> As long as we maintain the same typing behavior, does the standard permit us to just Do The Right Thing here and do the extended arithmetic with the original unsigned operand? I'm sure there are some cases where we would produce a slightly different value than an implementation that does the coercion before the operation, but that might be permitted under the standard, and as you say, it would only affect some situations that it doesn't seem the standard has given much thought to.
The coercion of unsigned to signed is likely done for pragmatic reasons; if you have a signed and unsigned type of the same rank, operating on them together won't require any 'extra bits'. This means that if your hardware has native support for the operations, you won't end up in a situation where you really need 33 or 34 bits (for a 32 bit value) to actually perform the operation. This is one of the benefits of these kinds of implicit conversions.
It probably makes the implementation a bit easier as well, since you don't have to consider cases where both sides have different signedness. The loss of the extra bit of precision from the unsigned operand is probably not considered to be very important. As Leonard said, if you wanted higher precision you can simply use the next rank of types. ...Of course, they seem to have forgotten that that exact issue with differing signedness also applies to operations with fixed-point and integer operands.
Personally, I think the spec could be a bit more restrictive with how it handles these conversions, as the way they are now makes it really hard to generate code sensibly for machines that have native support for these kinds of operations; in many cases you'll end up requiring a couple bits too many or a couple bits too few to fit in a sensible register size, and ensuring that the scales match what your hardware can handle is also a challenge.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D53738/new/
https://reviews.llvm.org/D53738
More information about the cfe-commits
mailing list