https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81444
Bug ID: 81444 Summary: expmed.c:init_expmed_one_mode uses wrong mode for widening cost computations Product: gcc Version: 7.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: gjl at gcc dot gnu.org Target Milestone: --- expmed.c:init_expmed_one_mode uses a wrong mode for widening cost computations. For example, on avr this function will compute the costs for set_mul_highpart_cost as follows: Almost correct (TImode is strange, this is due to init_expmed_one_conv clobbering modes): init_expmed_one_mode[:pass=?]: 0, (truncate:QI (lshiftrt:HI (mult:HI (zero_extend:HI (reg:TI 42)) (zero_extend:HI (reg:TI 42))) (const_int 8 [0x8]))) = 20 Wrong: mult_highpart will use SImode (2*HImode). This target is special as it provides a 24-bit mode (PSI) between HI and SI. The cost of "-88" will be used in the remainder where (truncate:HI (lshiftrt:SI (mult:SI... is the actual RTX. init_expmed_one_mode[:pass=?]: 0, (truncate:HI (lshiftrt:PSI (mult:PSI (zero_extend:PSI (reg:TI 42)) (zero_extend:PSI (reg:TI 42))) (const_int 16 [0x10]))) = -88 Following is not used. It would be unusable for sensible widening operation because SI < 2 * PSI. init_expmed_one_mode[:pass=?]: 0, (truncate:PSI (lshiftrt:SI (mult:SI (zero_extend:SI (reg:TI 42)) (zero_extend:SI (reg:TI 42))) (const_int 24 [0x18]))) = 32 Correct again but still strange TImode: init_expmed_one_mode[:pass=?]: 0, (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (reg:TI 42)) (zero_extend:DI (reg:TI 42))) (const_int 32 [0x20]))) = 64 ... Instead, what expmed computes costs for should read: init_expmed_one_mode[:pass=?]: 0, (truncate:QI (lshiftrt:HI (mult:HI (zero_extend:HI (reg:QI 42)) (zero_extend:HI (reg:QI 42))) (const_int 8 [0x8]))) = 20 init_expmed_one_mode[:pass=?]: 0, (truncate:HI (lshiftrt:SI (mult:SI (zero_extend:SI (reg:HI 42)) (zero_extend:SI (reg:HI 42))) (const_int 16 [0x10]))) = 32 init_expmed_one_mode[:pass=?]: 0, (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (reg:SI 42)) (zero_extend:DI (reg:SI 42))) (const_int 32 [0x20]))) = 64 etc.