http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48580
--- Comment #9 from joseph at codesourcery dot com <joseph at codesourcery dot com> 2011-04-13 12:45:35 UTC --- On Wed, 13 Apr 2011, rguenth at gcc dot gnu.org wrote: > For the latter reasons I think the builtins should be sth like > __builtin_smul_ovfl_p (multiplication-result, op0, op1), thus pass > in the multiplication result and keep the multiplication itself > in the IL to also allow for regular optimizations to work on them. > If the multiplication is just used as the builtin call argument > expansion can get rid of it. My inclination is that we probably want to separate the API for users from the built-in functions or other operations used internally - possibly providing a header gccarith.h with a supported API and saying the built-in functions are subject to change and should not be used directly in source code. Maybe (inspired by the style used on C1X stdatomic.h) one could have operations like arith_mul_signed (a, b, 32, ARITH_SAT) that multiplies a and b (integers to infinite precision, producing an infinite precision result), saturates the result to 32-bit signed and returns an implementation-defined type (signed, two's complement, at least 32 bits), or arith_mul_signed_check (a, b, 32, ARITH_WRAP, &overflow_p) that stores an overflow flag in the provided _Bool *. Or the overflow handling (wrap, saturate, undefined, unspecified-value, trap) could be part of the macro/function name (putting it as a separate operand is inspired by the memory_order parameters in stdatomic.h). The _check versions with explicit overflow flags could be used with any overflow handling other than "undefined behavior". (So if you don't care about what the value is when the overflow flag is set - if you'll just call some error handler - then you'd use "unspecified-value" as the overflow handling.) On divide by zero, both division and modulo operations would have undefined behavior except for the "trap" case - but modulo -1 would always be defined, unlike for C INT_MIN % -1 (I'm thinking of these operations as all being defined on their own by producing an infinite precision result first, but there might also be operations such as divmod producing multiple results). It may also make sense to expose different variations of division/modulo (rounding to 0, -infinity or +infinity; a true modulo operation, rounding to -infinity, is one of those things C doesn't make easy; GCC has these as TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR and corresponding *_MOD_EXPR). Starting with addition then increasing the set of operations gradually probably makes sense. Along with all the arithmetic operations you get range check operations - take a value (in any integer type), and check whether it is in the signed/unsigned range with a given number of bits, wrapping/saturating etc. and setting overflow flags as needed. These are just like the above but with one fewer operands. The explicit number of bits (required to be an integer constant expression) is deliberate because it is sometimes useful e.g. to saturate to 16 bits, but integer promotions in C make it rather fragile to rely on 16-bit operands remaining 16-bit rather than getting implicitly promoted to 32 bits. A consequence is that operations with strange numbers of bits can be written without involving bit-field types (since the result is allowed to have more than the given number of bits). I don't expect those to be very efficient in general, but note that ARM for example has SSAT and USAT instructions to saturate a value to a given number of bits (up to 32) and set a flag if it was out of range.