Richard Guenther wrote: >> I've run into another issue supporting a 20-bit integer for which I'd >> appreciate a hint. With this code: >> >> typedef long int __attribute__((__a20__)) int20_t; >> int20_t xi; >> int20_t addit () { xi += 0x54321L; } >> >> xi ends up in mode PSImode, which is a MODE_PARTIAL_INT with 20 bits of >> precision and 32-bit width. >> >> convert() notices that, because the constant in the add expression is >> SImode, there's an SImode add being truncated to a PSImode result, and >> pushes the truncation down into the operands. >> >> The problem is this ends up in convert_to_integer, which detects that the >> signed operation might overflow so calls unsigned_type_for() to get the >> unsigned variant. >> >> Unfortunately, this ends up in c_common_type_for_size(), which knows nothing >> about PSImode, and returns an unsigned type with 32 bits of precision when >> asked for one with 20 bits of precision. > > That's expected - this function returns a type that is suitable for holding > all > values, not a type that has necessarily matching precision. If the caller > wants such type it needs to verify what the function returned. Which seems > to me to be the correct fix for this (premature) optimization in > convert_to_integer. > > Richard. > >> The expression is rewritten with >> the 32-bit constant integer recast to the 32-bit unsigned type (instead >> of the 20-bit one it might have used), and infinite recursion results.
This is already filed as http://gcc.gnu.org/PR51527 It works with 4.8 trunk but crashes with 4.7. Did not yet track what changes made it work with 4.8, though. Unfortunately, noone remembers :-( http://gcc.gnu.org/ml/gcc/2012-03/msg00440.html Johann >> Is it proper for c_common_type_for_size() to know about partial int modes >> and return the best one available? Is there a hook that would allow me to >> do this customized in my back-end? Or is there another way to get >> unsigned_type_for() to return the "right" type for an unusual integer >> precision? >> >> Thanks. >> >> Peter