http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60738
Bug ID: 60738 Summary: A missing opportunity about process_single_reg_class_operands Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: wmi at google dot com Testcase 1.c: int a, b, c, d, e, cond; void foo() { int r1, r2, r3; r1 = b; r2 = d; if (__builtin_expect(cond > 3, 0)) { e = e * 5; c = a << r1; } c = c << r2; __builtin_printf("r1 + r2 = %d\n", r1 + r2); } ~/workarea/gcc-r208410/build/install/bin/gcc -O2 -S 1.c foo: .LFB0: .cfi_startproc cmpl $3, cond(%rip) movl b(%rip), %esi movl d(%rip), %eax jg .L2 movl c(%rip), %edx .L3: movl %eax, %ecx // r2 gets assigned %eax. This is reload for insn1. addl %eax, %esi movl $.LC0, %edi sall %cl, %edx // insn1. Its constraint requires r2 in %ecx xorl %eax, %eax movl %edx, c(%rip) jmp printf .p2align 4,,10 .p2align 3 .L2: movl e(%rip), %edx movl %esi, %ecx // r1 gets assigned %esi. This is reload for insn2. leal (%rdx,%rdx,4), %edx movl %edx, e(%rip) movl a(%rip), %edx sall %cl, %edx // insn2. Its constraint requires r1 in %ecx jmp .L3 .cfi_endproc Because the bb starting from L2 is relatively cold, it is better to generate the code below: foo: .LFB0: .cfi_startproc cmpl $3, cond(%rip) movl b(%rip), %esi movl d(%rip), %ecx jg .L2 movl c(%rip), %eax .L3: sall %cl, %eax // r2 gets assigned %ecx. no reload is needed. addl %ecx, %esi movl $.LC0, %edi movl %eax, c(%rip) xorl %eax, %eax jmp printf .p2align 4,,10 .p2align 3 .L2: movl e(%rip), %eax movl %ecx, %edx // r2's live range is splitted here. This is the start of the splitted live range. movl %esi, %ecx // r1 gets assigned %esi, this is reload for insn2. leal (%rax,%rax,4), %eax movl %eax, e(%rip) movl a(%rip), %eax sall %cl, %eax // insn2. constraint of insn2 requires r1 in %ecx movl %edx, %ecx // r2's live range is splitted here. This is the end of the splitted live range. jmp .L3 .cfi_endproc Now there is less code in the hotpath (The bb starting from .L3). r1 and r2 used in sall insns need CX_REG class which is single_reg_operand_class in IRA. Existing logic in process_single_reg_class_operands in ira-lives.c doesn't allow %ecx to being assigned to r1 or r2. May it need improvement here?