[PATCH] D53738: [Fixed Point Arithmetic] Fixed Point Addition

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 29 19:11:11 PST 2018


rjmccall added inline comments.


================
Comment at: clang/include/clang/Basic/FixedPoint.h:67
+  FixedPointSemantics
+  getCommonSemantics(const FixedPointSemantics &Other) const;
+
----------------
leonardchan wrote:
> rjmccall wrote:
> > Actually representing the fully-precise value is operation-specific; you'd need a different calculation for at least addition and multiplication, and maybe also subtraction and (maybe?) division.  Is this what you actually want?
> For addition and subtraction, I believe we just need to extend and shift to a type that is large enough to hold the larger scale and integral bits, then we can do a normal add/sub. I think the relational operations can use this also since we would just need to resize and align scales for them.
> 
> For multiplication, the intrinsics we will use also assume the scale for both operands are the same, which I believe will also require finding semantics large enough to hold the larger scale and integral bits.
> 
> ```
> declare iN @llvm.smul.fix(iN %L, %iN R, i32 %Scale)
> ```
> 
> Division is similar since the saturating and non-saturating intrinsics assume both operands have the same scale.
> 
> ```
> declare iN @llvm.sdiv.fix(iN %L, %iN R, i32 %Scale)
> ```
> 
> In each of these cases, I believe the common semantics just needs to be large enough to hold the scale and largest representable value, which is what this method does.
Okay, so I believe what you're saying is that `getCommonSemantics` is defined as returning a semantics that is capable of precisely representing both input values, not one that's capable of precisely representing the result of the computation.  The documentation could be clearer about that.


================
Comment at: clang/lib/Basic/FixedPoint.cpp:141
+  if (ResultIsSigned || ResultHasUnsignedPadding)
+    CommonWidth++;
+
----------------
leonardchan wrote:
> rjmccall wrote:
> > Is this right?  If I have `a+b+c+d+e+f+g+h+i`, where those are all the same signed type, won't the width of the common semantics keep growing as I add more operands?
> This should be right. Each addition is split into separate binary operations which produce separate common fixed point semantics from 2 different semantics. The width is also primarily made from the larger scale and large number of integral bits (which excludes the sign or unsigned padding).
> 
> For example:
> 
> ```
> a+b -> Width: 32 (scale 14 + integral bits 16 + sign bit 1)
> (a+b)+c -> Width: 32 ^^^^^
> ((a+b)+c)+d -> Width: 32 ^^^^^
> ```
> 
> Added a test for this.
I see.  If that's done consistently then it's fine that it technically slightly misrepresents the range of negative values.


================
Comment at: clang/lib/CodeGen/CGExprScalar.cpp:3370
+
+  const auto *BinOp = dyn_cast<BinaryOperator>(op.E);
+  assert(BinOp && "Expected the operator to be a binary operator");
----------------
Please use `cast`.


================
Comment at: clang/lib/Sema/SemaExpr.cpp:1237
+  if (Ty->isIntegerType())
+    return 0;
+
----------------
Please optimize this function around expecting a `BuiltinType`.  That is, instead of separately checking for an integer type here, please assert it when (1) the `getAs` fails or (2) you fall into the `default` case.


================
Comment at: clang/lib/Sema/SemaExpr.cpp:1304
+    RHSTy = ResultTy;
+  }
+
----------------
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.


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