[llvm-dev] Fixed Point Support in LLVM

Bevin Hansson via llvm-dev llvm-dev at lists.llvm.org
Tue Aug 21 00:51:44 PDT 2018

On 2018-08-20 21:52, Philip Reames via llvm-dev wrote:
> A couple of thoughts here.  None particularly well thought out, so 
> please take this more as brainstorming then specific recommendations.
> In terms of typing, have you considered representing your fixed points 
> as structs in IR as apposed to packed integers?  I suspect - but am by 
> no means sure - that exposing the parts to the optimizer separately 
> may lead to better overall optimization quality.  SROA is quite good 
> at destroying small structs.
This might be an interesting idea if you're working on a C level (say, 
you could have structs with bitfields containing the parts of the 
fixed-point number), but I don't know if there's a benefit to it on IR 
level, since most of the operations you'd want to do on fixed-point 
numbers really are regular integer operations. In some basic experiments 
we've done with _Complex (which is represented with a struct), we find 
that the optimizer doesn't always do as good a job with structs as it 
does with just integers, even when SROA unpacks things.
> In terms of ABI, how are fixed points passed as arguments and return 
> values?  This may impact your choice of IR representation. If you can 
> get away with something simple (e.g. passed as iN, bitcast to desired 
> types) you'll be much better off then if you have a complicated ABI.
I think the discussion of ABI came up in review of one of the Clang 
patches; unsure what the verdict was. Most targets likely don't have a 
well defined ABI for fixed-point numbers, so it would be up for 
discussion, but I think the easiest way is just to say that fixed-point 
types have the same ABI as their same-sized integer counterparts. If 
their representation is also in the form of integers, then this is trivial.
> If I understand your operations, you're going to need to have the 
> scale as an explicit parameter to your intrinsics right?  If so, 
> you're essentially going to end up with needing a family of intrinsics 
> for each operation.  You have a couple of approaches for modeling 
> that: either constant parameters or name manging might work.
In our implementation, the intrinsics that require a scale have one as 
an extra constant parameter. This is multiplication and division, and 
the saturating counterparts.

I think that our intrinsic set would have to be extended a bit to work 
with the design that Leonard is working on, since we are implementing 
DSP-C rather than Embedded-C. Some intrinsics would have to be added 
(unsigned multiplication; possibly differentiating between signed and 
unsigned saturating addition/subtraction?) and the saturating 
addition/subtraction would need a scale parameter.
> Have you considered phrasing this as builtin functions as opposed to 
> intrinsics?  We have fairly decent support in TLI for conditionally 
> available builtins where as intrinsics are generally assumed to be 
> always supported.  Phrasing your operations as a set of builtins 
> implemented by a runtime library may allow both easier prototyping and 
> easier per target integration.  In particular, pattern matching IR to 
> the operations would be much more natural if framed as TLI functions 
> since we have the concept of an unsupported builtin already supported.
Builtins for unsupported combinations of width/scale would be 
interesting, but most of these operations can be expanded fairly easily, 
and they can be implemented in terms of integer operations anyway which 
already have builtins for unsupported widths/operations.

Furthermore, it needs to be possible to instruction select them easily 
for targets with native support, so intrinsics is the simplest approach 

/ Bevin

More information about the llvm-dev mailing list