http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47379
Summary: fwprop1 generates bad codes for x32 Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: hjl.to...@gmail.com On x32 branch, for --- typedef unsigned IPos; typedef unsigned char uch; extern uch window[]; unsigned max_chain_length; unsigned strstart; int longest_match(IPos cur_match, int len, int best_len) { unsigned chain_length = max_chain_length; register uch *scan = window + strstart; register uch *match; register uch scan_end1 = scan[best_len-1]; register uch scan_end = scan[best_len]; do { ; match = window + cur_match; if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; best_len = len; } while ( --chain_length != 0); return best_len; } --- compiled with -mx32 -O, fwprop1 pass turns: (insn 14 13 15 2 (parallel [ (set (reg/f:SI 86) (plus:SI (reg:SI 63 [ strstart.0 ]) (symbol_ref:SI ("window") [flags 0x40] <var_decl 0x7f7a44198000 window>))) (clobber (reg:CC 17 flags)) ]) x.i:9 253 {*addsi_1} (nil)) (insn 15 14 16 2 (set (reg/v/f:DI 64 [ scan ]) (zero_extend:DI (reg/f:SI 86))) x.i:9 115 {*zero_extendsidi2_rex64} (nil)) (insn 16 15 17 2 (set (reg:SI 65 [ best_len.1 ]) (reg/v:SI 85 [ best_len ])) x.i:11 64 {*movsi_internal} (nil)) (insn 17 16 18 2 (parallel [ (set (reg:SI 89) (plus:SI (reg/v:SI 85 [ best_len ]) (subreg/s/u:SI (reg/v/f:DI 64 [ scan ]) 0))) (clobber (reg:CC 17 flags)) ]) x.i:11 253 {*addsi_1} (nil)) into (insn 14 13 15 2 (parallel [ (set (reg/f:SI 86) (plus:SI (reg:SI 63 [ strstart.0 ]) (symbol_ref:SI ("window") [flags 0x40] <var_decl 0x7f7a44198000 window>))) (clobber (reg:CC 17 flags)) ]) x.i:9 253 {*addsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 15 14 17 2 (set (reg/v/f:DI 64 [ scan ]) (zero_extend:DI (reg/f:SI 86))) x.i:9 115 {*zero_extendsidi2_rex64} (expr_list:REG_DEAD (reg/f:SI 86) (nil))) (insn 17 15 18 2 (parallel [ (set (reg:SI 89) (plus:SI (reg/v:SI 85 [ best_len ]) (reg/f:SI 86))) (clobber (reg:CC 17 flags)) ]) x.i:11 253 {*addsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) with In insn 17, replacing (subreg/s/u:SI (reg/v/f:DI 64 [ scan ]) 0) with (reg/f:SI 86) Changed insn 17 deferring rescan insn with uid = 17. deferring rescan insn with uid = 17. For x32, (subreg/s/u:SI (reg/v/f:DI 64 [ scan ]) 0) is free while (reg/f:SI 86) is an extra register.