https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95787
Bug ID: 95787 Summary: Complete lack of optimization on assignment to some types when followed by Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: gabravier at gmail dot com Target Milestone: --- extern unsigned short a; int f() { a = 0; return 0; } With -O3, LLVM outputs this : f(): # @f() mov word ptr [rip + a], 0 xor eax, eax ret GCC outputs this : f(): xor eax, eax mov WORD PTR a[rip], ax xor eax, eax ret GCC has the same problem for every single architecture, the final tree representation looks like this : ;; Function f (_Z1fv, funcdef_no=1, decl_uid=4740, cgraph_uid=2, symbol_order=1) f () { <bb 2> [local count: 1073741824]: a = 0; return 0; } And the final RTL representation looks like this : ;; Function f (_Z1fv, funcdef_no=1, decl_uid=4740, cgraph_uid=2, symbol_order=1) f Dataflow summary: ;; fully invalidated by EH 0 [ax] 1 [dx] 2 [cx] 4 [si] 5 [di] 8 [st] 9 [st(1)] 10 [st(2)] 11 [st(3)] 12 [st(4)] 13 [st(5)] 14 [st(6)] 15 [st(7)] 17 [flags] 18 [fpsr] 20 [xmm0] 21 [xmm1] 22 [xmm2] 23 [xmm3] 24 [xmm4] 25 [xmm5] 26 [xmm6] 27 [xmm7] 28 [mm0] 29 [mm1] 30 [mm2] 31 [mm3] 32 [mm4] 33 [mm5] 34 [mm6] 35 [mm7] 36 [r8] 37 [r9] 38 [r10] 39 [r11] 44 [xmm8] 45 [xmm9] 46 [xmm10] 47 [xmm11] 48 [xmm12] 49 [xmm13] 50 [xmm14] 51 [xmm15] 52 [xmm16] 53 [xmm17] 54 [xmm18] 55 [xmm19] 56 [xmm20] 57 [xmm21] 58 [xmm22] 59 [xmm23] 60 [xmm24] 61 [xmm25] 62 [xmm26] 63 [xmm27] 64 [xmm28] 65 [xmm29] 66 [xmm30] 67 [xmm31] 68 [k0] 69 [k1] 70 [k2] 71 [k3] 72 [k4] 73 [k5] 74 [k6] 75 [k7] ;; hardware regs used 7 [sp] ;; regular block artificial uses 7 [sp] ;; eh block artificial uses 7 [sp] 16 [argp] ;; entry block defs 0 [ax] 1 [dx] 2 [cx] 4 [si] 5 [di] 7 [sp] 20 [xmm0] 21 [xmm1] 22 [xmm2] 23 [xmm3] 24 [xmm4] 25 [xmm5] 26 [xmm6] 27 [xmm7] 36 [r8] 37 [r9] ;; exit block uses 0 [ax] 7 [sp] ;; regs ever live 0 [ax] 17 [flags] ;; ref usage r0={3d,3u} r1={1d} r2={1d} r4={1d} r5={1d} r7={1d,2u} r17={2d} r20={1d} r21={1d} r22={1d} r23={1d} r24={1d} r25={1d} r26={1d} r27={1d} r36={1d} r37={1d} ;; total ref usage 25{20d,5u,0e} in 5{5 regular + 0 call} insns. (note 1 0 14 NOTE_INSN_DELETED) (note 14 1 16 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 16 14 2 2 NOTE_INSN_PROLOGUE_END) (note 2 16 22 2 NOTE_INSN_FUNCTION_BEG) (insn 22 2 23 2 (parallel [ (set (reg:SI 0 ax) (const_int 0 [0])) (clobber (reg:CC 17 flags)) ]) "./example.cpp":27:7 67 {*movsi_xor} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 23 22 24 2 (set (mem/c:HI (symbol_ref:DI ("a") [flags 0x40] <var_decl 0x7f9720202cf0 a>) [1 a+0 S2 A16]) (reg:HI 0 ax)) "./example.cpp":27:7 76 {*movhi_internal} (expr_list:REG_DEAD (reg:HI 0 ax) (nil))) (insn 24 23 11 2 (parallel [ (set (reg:DI 0 ax) (const_int 0 [0])) (clobber (reg:CC 17 flags)) ]) "./example.cpp":29:1 68 {*movdi_xor} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 11 24 25 2 (use (reg/i:SI 0 ax)) "./example.cpp":29:1 -1 (nil)) (note 25 11 18 2 NOTE_INSN_EPILOGUE_BEG) (jump_insn 18 25 19 2 (simple_return) "./example.cpp":29:1 819 {simple_return_internal} (nil) -> simple_return) (barrier 19 18 13) (note 13 19 0 NOTE_INSN_DELETED) So it looks like this is a problem with RTL (it explicitly sets a register to 0 and sets `a` to that register).