https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84660
Bug ID: 84660 Summary: Combine doing wrong optimization for 64 bits with SHIFT_COUNT_TRUNCATED target Product: gcc Version: 7.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: npickito at gmail dot com CC: andrew at sifive dot com, palmer at dabbelt dot com, wilson at tuliptree dot org Target Milestone: --- Target: riscv64imafd-elf-newlib Option: -O3 Testcase: unsigned int foo(const unsigned int op003) __attribute__((noinline, noclone)); unsigned int foo(const unsigned int op003) { return (0xFFFF & (0xd066 << ( (0x2f ^ (0x1 & op003)) % 16 ))); } unsigned int op0 = 0; int main() { op0 = foo(0x1); __builtin_printf("op0 = %08x \n", op0); return 0; } Expect result: op0 = 00008000 What's wrong? foo was optimized to return 0 directly. Before combine: (x.c.260r.ud_dce) (insn 2 4 3 2 (set (reg/v:DI 78 [ op003 ]) (reg:DI 10 a0 [ op003 ])) "x.c":2 131 {*movdi_64bit} (expr_list:REG_DEAD (reg:DI 10 a0 [ op003 ]) (nil))) (note 3 2 7 2 NOTE_INSN_FUNCTION_BEG) (insn 7 3 9 2 (set (reg:DI 81) (and:DI (reg/v:DI 78 [ op003 ]) (const_int 1 [0x1]))) "x.c":4 70 {anddi3} (expr_list:REG_DEAD (reg/v:DI 78 [ op003 ]) (nil))) (insn 9 7 11 2 (set (reg:DI 83) (xor:DI (reg:DI 81) (const_int 47 [0x2f]))) "x.c":4 72 {xordi3} (expr_list:REG_DEAD (reg:DI 81) (nil))) (insn 11 9 12 2 (set (reg:DI 85) (and:DI (reg:DI 83) (const_int 15 [0xf]))) "x.c":4 70 {anddi3} (expr_list:REG_DEAD (reg:DI 83) (nil))) (insn 12 11 13 2 (set (reg:SI 88) (const_int 53248 [0xd000])) "x.c":4 132 {*movsi_internal} (nil)) (insn 13 12 14 2 (set (reg:SI 87) (plus:SI (reg:SI 88) (const_int 102 [0x66]))) "x.c":4 3 {addsi3} (expr_list:REG_DEAD (reg:SI 88) (expr_list:REG_EQUAL (const_int 53350 [0xd066]) (nil)))) (insn 14 13 15 2 (set (reg:SI 86) (ashift:SI (reg:SI 87) (subreg:SI (reg:DI 85) 0))) "x.c":4 146 {ashlsi3} (expr_list:REG_DEAD (reg:SI 87) (expr_list:REG_DEAD (reg:DI 85) (nil)))) (insn 11 9 12 2 (set (reg:DI 85) (and:DI (reg:DI 83) (const_int 15 [0xf]))) "x.c":4 70 {anddi3} (expr_list:REG_DEAD (reg:DI 83) (nil))) (insn 15 14 16 2 (set (reg:DI 91) (const_int 65536 [0x10000])) "x.c":4 131 {*movdi_64bit} (nil)) (insn 16 15 17 2 (set (reg:DI 90) (plus:DI (reg:DI 91) (const_int -1 [0xffffffffffffffff]))) "x.c":4 4 {adddi3} (expr_list:REG_DEAD (reg:DI 91) (expr_list:REG_EQUAL (const_int 65535 [0xffff]) (nil)))) (insn 17 16 18 2 (set (reg:DI 89) (and:DI (subreg:DI (reg:SI 86) 0) (reg:DI 90))) "x.c":4 70 {anddi3} (expr_list:REG_DEAD (reg:DI 90) (expr_list:REG_DEAD (reg:SI 86) (nil)))) (insn 18 17 23 2 (set (reg:DI 92) (sign_extend:DI (subreg:SI (reg:DI 89) 0))) "x.c":4 86 {extendsidi2} (expr_list:REG_DEAD (reg:DI 89) (nil))) (insn 23 18 24 2 (set (reg/i:DI 10 a0) (reg:DI 92)) "x.c":5 131 {*movdi_64bit} (expr_list:REG_DEAD (reg:DI 92) (nil))) After combine: (x.c.262r.ce2) (insn 23 18 24 2 (set (reg/i:DI 10 a0) (const_int 0 [0])) "x.c":5 131 {*movdi_64bit} (nil)) What's happen during combine: ... Trying 11 -> 14: Successfully matched this instruction: (set (reg:SI 86) (ashift:SI (reg:SI 87) (subreg:SI (reg:DI 83) 0))) allowing combination of insns 11 and 14 original costs 4 + 4 = 8 replacement cost 4 deferring deletion of insn with uid = 11. modifying insn i3 14: r86:SI=r87:SI<<r83:DI#0 REG_DEAD r83:DI REG_DEAD r87:SI deferring rescan insn with uid = 14. ... Trying 15, 16 -> 17: Successfully matched this instruction: (set (reg:DI 89) (zero_extend:DI (subreg:HI (reg:SI 86) 0))) allowing combination of insns 15, 16 and 17 original costs 4 + 4 + 4 = 12 replacement cost 8 deferring deletion of insn with uid = 16. deferring deletion of insn with uid = 15. modifying insn i3 17: r89:DI=zero_extend(r86:SI#0) REG_DEAD r86:SI deferring rescan insn with uid = 17. ... Trying 9, 14 -> 17: Successfully matched this instruction: (set (reg:DI 89) (const_int 0 [0])) allowing combination of insns 9, 14 and 17 original costs 4 + 4 + 8 = 16 replacement cost 4 deferring deletion of insn with uid = 14. deferring deletion of insn with uid = 9. deferring deletion of insn with uid = 12. deferring deletion of insn with uid = 13. deferring deletion of insn with uid = 7. modifying insn i3 17: r89:DI=0 deferring rescan insn with uid = 17.