https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79048
Bug ID: 79048 Summary: Unnecessary reload for flags setting insn when operands die Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- Following testcase: extern void g(); void f1(char a,char b){ if(a|b)g(); } compiles to (-O2): f1: movl %esi, %eax orb %dil, %al jne .L4 Note that reload fails to figure out that both registers die in (insn 10): (insn 10 9 11 2 (parallel [ (set (reg:CCZ 17 flags) (compare:CCZ (ior:QI (subreg:QI (reg:SI 91 [ b ]) 0) (subreg:QI (reg:SI 89 [ a ]) 0)) (const_int 0 [0]))) (clobber (scratch:QI)) ]) "pr79045.c":2 437 {*iorqi_3} (expr_list:REG_DEAD (reg:SI 91 [ b ]) (expr_list:REG_DEAD (reg:SI 89 [ a ]) (nil)))) RA could allocate %esi (or even %edi, iorqi_3 has commutative operands) as a matched output scratch, but instead generates an unnecessary reload with additional temporary register, bloating the code and increasing register pressure: (insn 21 9 10 2 (set (reg:QI 0 ax [93]) (reg:QI 4 si [orig:91 b ] [91])) "pr79045.c":2 84 {*movqi_internal} (nil)) (insn 10 21 11 2 (parallel [ (set (reg:CCZ 17 flags) (compare:CCZ (ior:QI (reg:QI 0 ax [93]) (reg:QI 5 di [orig:89 a ] [89])) (const_int 0 [0]))) (clobber (reg:QI 0 ax [93])) ]) "pr79045.c":2 437 {*iorqi_3} (nil)) Ideally, RA should use dead input reg to allocate as matched scratch, possibly also exploiting "%" operand modifier.