On Sat, 1 Mar 2008, Richard Guenther wrote: > > But arbitrary arithmetic expressions aren't marked as potentially trapping > > / having side-effects with -ftrapv, so cases such as > > > > int f(int a, int b) { return 0 * (a + b); } > > > > get the potentially trapping arithmetic folded away. If -ftrapv is to > > have properly defined semantics, those must include trapping if (a + b) > > overflows in the above code. > > Sure, the only clean way to do this is to introduce new tree codes for > trapping arithmetic. Then the usual mechanisms of omit_one_operand > and friends like tree_could_trap_p can work. VRP can for example then > optimize trapping codes to non-trapping codes.
Yes, new tree codes (or flags on existing ones) to distinguish trapping / wrapping / undefined arithmetic are a clean approach. Then -ftrapv and -fwrapv would be used only when front ends build trees, and not subsequently to affect the semantics of given GIMPLE trees. It might be useful for optimizers to understand two expressions being equivalent in one direction only (if you have an overflow-undefined version of an expression, and an overflow-wrapping or overflow-trapping version, you can just evaluate the latter version and use the result for the overflow-undefined version, but not vice versa). Depending on the target (whether it has instruction patterns for these operations), and on other flags such as -Os, and on the particular types involved, the trapping codes might then get converted to wrapping codes plus inline checks at some point through tree-ssa (especially if one argument is a constant), or might make it all the way to expand. If given bit-field types, Ada types with special ranges, etc. (types not having the full range of their mode, or checked arithmetic on char or short where we don't provide libgcc functions because such arithmetic won't arise in C because of promotions), inline checks would definitely be needed since there wouldn't be suitable libgcc functions. (The inline checks for special cases could simply be: do the checked arithmetic in the full width of the mode where there is a libgcc function, then add inline range checks on the result for the exact range desired.) So far, the LTO work has concentrated on proving the concept by allowing real programs such as GCC and SPEC (but in a single language and built with a single set of options) to be built and linked using the LTO infrastructure. (In the earlier days there was also all the work on reducing memory usage; unfortunately most of the miscellaneous tree trimming changes from that are still languishing on the oldlto branch without having been merged to trunk, despite many having been preapproved to go on trunk after 4.3 branched.) To complete LTO it will be necessary to change all implicit GIMPLE semantics (in global variables or langhooks) into explicit semantics directly encoded in the GIMPLE - including flag_trapv and flag_wrapv among many others, but I don't know when that part of the LTO work might happen. -- Joseph S. Myers [EMAIL PROTECTED]