On Wed, May 21, 2014 at 12:53:47PM +1000, Kugan wrote: > On 20/05/14 16:52, Jakub Jelinek wrote: > > On Tue, May 20, 2014 at 12:27:31PM +1000, Kugan wrote: > >> 1. Handling NOP_EXPR or CONVERT_EXPR that are in the IL because they > >> are required for type correctness. We have two cases here: > >> > >> A) Mode is smaller than word_mode. This is usually from where the > >> zero/sign extensions are showing up in final assembly. > >> For example : > >> int = (int) short > >> which usually expands to > >> (set (reg:SI ) > >> (sext:SI (subreg:HI (reg:SI )))) > >> We can expand this > >> (set (reg:SI ) (((reg:SI )))) > >> > >> If following is true: > >> 1. Value stored in RHS and LHS are of the same signedness > >> 2. Type can hold the value. i.e., In cases like char = (char) short, we > >> check that the value in short is representable char type. (i.e. look at > >> the value range in RHS SSA_NAME and see if that can be represented in > >> types of LHS without overflowing) > >> > >> Subreg here is not a paradoxical subreg. We are removing the subreg and > >> zero/sign extend here. > >> > >> I am assuming here that QI/HI registers are represented in SImode > >> (basically word_mode) with zero/sign extend is used as in > >> (zero_extend:SI (subreg:HI (reg:SI 117)). > > > > Wouldn't it be better to just set proper flags on the SUBREG based on value > > range info (SUBREG_PROMOTED_VAR_P and SUBREG_PROMOTED_UNSIGNED_P)? > > Then not only the optimizers could eliminate in zext/sext when possible, but > > all other optimizations could benefit from that. > > Thanks for the comments. Here is an attempt (attached) that sets > SUBREG_PROMOTED_VAR_P based on value range into. Is this the good place > to do this ?
But you aren't setting it in your patch in any way, you are just resetting it instead. The thing is, start with a testcase where you get that (subreg:HI (reg:SI)) as the RTL of some SSA_NAME (is that the case on ARM?, I believe on e.g. i?86/x86_64 you'd just get (reg:HI) instead and thus you can't take advantage of that), and at that point where it is created check the range info and if it is properly sign or zero extended, set SUBREG_PROMOTED_VAR_P and SUBREG_PROMOTED_UNSIGNED_SET. Note that right now we use 2 bits for the latter, which encode values -1 (weirdo pointer extension), 0 (sign extension), 1 (zero extension). Perhaps it would be nice to allow encoding value 2 (zero and sign extension) for cases where the range info tells you that the value is both zero and sign extended (i.e. minimum of range is >= 0 and maximum is <= signed type maximum). Jakub