On 11/05/2021 07:37, Tamar Christina via Gcc wrote: > Hi All, > > We are looking to implement saturation support in the compiler. The aim is to > recognize both Scalar and Vector variant of typical saturating expressions. > > As an example: > > 1. Saturating addition: > char sat (char a, char b) > { > int tmp = a + b; > return tmp > 127 ? 127 : ((tmp < -128) ? -128 : tmp); > } > > 2. Saturating abs: > char sat (char a) > { > int tmp = abs (a); > return tmp > 127 ? 127 : ((tmp < -128) ? -128 : tmp); > } > > 3. Rounding shifts > char rndshift (char dc) > { > int round_const = 1 << (shift - 1); > return (dc + round_const) >> shift; > } > > etc. >
I can't comment on the implementation part - I don't know anything about it. However, in your examples above I see a few points. One is your use of "char". "char" is a type that varies in signedness from target to target (and also depending on compiler flags), and is slightly different in C and C++ ('a' has char type in C++, int type in C). If you must use "char" in arithmetic contexts, I recommend using "signed char" or "unsigned char" explicitly. I would rather recommend you use the size-specific <stdint.h> types - int8_t, etc., - as being more appropriate for this kind of thing. (AFAIK all gcc targets have 8-bit CHAR.) This also makes it easier to see the sizes you need for the "tmp" value as you make functions for bigger sizes - remember that on some gcc targets, "int" is 16-bit. It is also worth noting that gcc already has support for saturating types on some targets: <https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html> My testing of these (quite a long time ago) left me with a feeling that it was not a feature anyone had worked hard to optimise - certainly it did not make use of saturating arithmetic instructions available on some of the targets I tested (ARM Cortex M4, for example). But it is possible that there are things here that would be of use to you. (I am not convinced that it is worth spending time optimising the implementation of these - I don't think the N1169 types are much used by anyone.) While it is always good that the compiler can spot patterns in generic C code and generate optimal instruction sequences, another possibility here would be a set of built-in functions for saturated and rounding arithmetic. That would take the guesswork out of it for users - if there code requires efficient saturated addition, they can use __builtin_add_sat and get the best their target can offer (just like __builtin_add_overflow, and that kind of thing). And it might be easier to implement in the compiler. I hope these comments give you a few ideas or useful thoughts. David