https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109414
Jeffrey A. Law <law at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED Status|UNCONFIRMED |RESOLVED CC| |law at gcc dot gnu.org --- Comment #5 from Jeffrey A. Law <law at gcc dot gnu.org> --- These code generation inefficiences have been fixed. I didn't bisect, but I would hazard a guess it was Jivan's work on exposing the widening nature of the 32 bit operations and extracting the result via a promoted subreg. ie, for the first example we now generate this during expand: (insn 2 5 3 2 (set (reg/v:DI 136 [ x ]) (reg:DI 10 a0 [ x ])) "j.c":1:26 -1 (nil)) (insn 3 2 4 2 (set (reg/v:DI 137 [ n ]) (reg:DI 11 a1 [ n ])) "j.c":1:26 -1 (nil)) (note 4 3 7 2 NOTE_INSN_FUNCTION_BEG) (insn 7 4 8 2 (set (reg:DI 140) (sign_extend:DI (plus:SI (subreg/s/u:SI (reg/v:DI 136 [ x ]) 0) (const_int 1 [0x1])))) "j.c":2:12 -1 (nil)) (insn 8 7 9 2 (set (reg:SI 139) (subreg/s/u:SI (reg:DI 140) 0)) "j.c":2:12 -1 (expr_list:REG_EQUAL (plus:SI (subreg/s/u:SI (reg/v:DI 136 [ x ]) 0) (const_int 1 [0x1])) (nil))) (insn 9 8 10 2 (set (reg:DI 141) (xor:DI (reg/v:DI 137 [ n ]) (subreg:DI (reg:SI 139) 0))) "j.c":2:17 -1 (nil)) (insn 10 9 11 2 (set (reg:DI 142) (sign_extend:DI (subreg:SI (reg:DI 141) 0))) "j.c":2:17 discrim 1 -1 (nil)) (insn 11 10 15 2 (set (reg:DI 135 [ <retval> ]) (reg:DI 142)) "j.c":2:17 discrim 1 -1 (nil)) (insn 15 11 16 2 (set (reg/i:DI 10 a0) (reg:DI 135 [ <retval> ])) "j.c":3:1 -1 (nil)) (insn 16 15 0 2 (use (reg/i:DI 10 a0)) "j.c":3:1 -1 (nil)) Which is much easier for combine to analyze and prove the trailing sign extension is unnecessary.