https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97968
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Known to fail| |11.1.0, 8.1.0 Known to work| |7.1.0 Ever confirmed|0 |1 Component|rtl-optimization |middle-end Keywords| |ra Last reconfirmed| |2021-09-01 Summary|Unnecessary mov instruction |[9/10/11/12 Regression] |with comparison and cmov |Unnecessary mov instruction | |with comparison and cmov Status|UNCONFIRMED |NEW Severity|normal |enhancement --- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- So looking into this, I think this is a register allocation issue. We produce: (insn 23 6 2 2 (set (reg:SI 87) (reg:SI 5 di [ n ])) "/app/example.cpp":3:1 75 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 5 di [ n ]) (nil))) (insn 2 23 24 2 (set (reg/v:SI 83 [ n ]) (reg:SI 87)) "/app/example.cpp":3:1 75 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 87) (nil))) (insn 24 2 3 2 (set (reg:SI 88) (reg:SI 4 si [ j ])) "/app/example.cpp":3:1 75 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 4 si [ j ]) (nil))) (note 3 24 4 2 NOTE_INSN_DELETED) (note 4 3 20 2 NOTE_INSN_FUNCTION_BEG) (insn 20 4 25 2 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:SI 83 [ n ]) (reg:SI 88))) "/app/example.cpp":4:18 11 {*cmpsi_1} (expr_list:REG_DEAD (reg:SI 88) (nil))) (insn 25 20 22 2 (set (reg:SI 86) (const_int 0 [0])) "/app/example.cpp":4:18 75 {*movsi_internal} (expr_list:REG_EQUIV (const_int 0 [0]) (nil))) (insn 22 25 17 2 (set (reg/v:SI 83 [ n ]) (if_then_else:SI (gt (reg:CCGC 17 flags) (const_int 0 [0])) (reg/v:SI 83 [ n ]) (reg:SI 86))) "/app/example.cpp":4:18 1140 {*movsicc_noc} (expr_list:REG_DEAD (reg:SI 86) (expr_list:REG_DEAD (reg:CCGC 17 flags) (nil)))) (insn 17 22 18 2 (set (reg/i:SI 0 ax) (reg/v:SI 83 [ n ])) "/app/example.cpp":5:1 75 {*movsi_internal} (expr_list:REG_DEAD (reg/v:SI 83 [ n ]) (nil))) But we tie the input to the movsicc_noc to the output early on with reg 83. that means we select 83 to be ax which means emitting a move early on instead of selecting 86 as ax and having the second 83 be ax. Now it looks in GCC 7 we got this before RA: (insn 26 27 17 2 (set (reg:SI 87 [ <retval> ]) (if_then_else:SI (gt (reg:CCGC 17 flags) (const_int 0 [0])) (reg/v:SI 88 [ n ]) (reg:SI 91))) "/app/example.cpp":4 968 {*movsicc_noc} (expr_list:REG_DEAD (reg:SI 91) (expr_list:REG_DEAD (reg/v:SI 88 [ n ]) (expr_list:REG_DEAD (reg:CCGC 17 flags) (nil))))) (insn 17 26 18 2 (set (reg/i:SI 0 ax) (reg:SI 87 [ <retval> ])) "/app/example.cpp":5 82 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 87 [ <retval> ]) (nil))) The change looks like is the way we expand the code from gimple to RTL. In post GCC 8, we tie right away the return value to the register which holds n and move 0 into n.