diff --git a/llvm/lib/Target/X86/X86FixupLEAs.cpp b/llvm/lib/Target/X86/X86FixupLEAs.cpp --- a/llvm/lib/Target/X86/X86FixupLEAs.cpp +++ b/llvm/lib/Target/X86/X86FixupLEAs.cpp @@ -786,12 +786,33 @@ LLVM_DEBUG(dbgs() << "FixLEA: Replaced by: ";); MachineInstr *NewMI = nullptr; + bool BaseOrIndexIsDst = DestReg == BaseReg || DestReg == IndexReg; + // First try and remove the base while sticking with LEA iff base == index and + // scale == 1. We can handle: + // 1. lea D(%base,%index,1) -> lea D(,%index,2) + // 2. lea D(%r13/%rbp,%index) -> lea D(,%index,2) + // Only do this if the LEA would otherwise be split into 2-instruction + // (either it has a an Offset or neither base nor index are dst) + if (IsScale1 && BaseReg == IndexReg && (hasLEAOffset(Offset) || (IsInefficientBase && !BaseOrIndexIsDst))) { + NewMI = BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(LEAOpcode)) + .add(Dest) + .addReg(0) + .addImm(2) + .add(Index) + .add(Offset) + .add(Segment); + LLVM_DEBUG(NewMI->dump();); + + MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1); + MBB.erase(I); + I = NewMI; + return; + } else if (IsScale1 && BaseOrIndexIsDst) { + // Try to replace LEA with one or two (for the 3-op LEA case) + // add instructions: + // 1.lea (%base,%index,1), %base => add %index,%base + // 2.lea (%base,%index,1), %index => add %base,%index - // First try to replace LEA with one or two (for the 3-op LEA case) - // add instructions: - // 1.lea (%base,%index,1), %base => add %index,%base - // 2.lea (%base,%index,1), %index => add %base,%index - if (IsScale1 && (DestReg == BaseReg || DestReg == IndexReg)) { unsigned NewOpc = getADDrrFromLEA(MI.getOpcode()); if (DestReg != BaseReg) std::swap(BaseReg, IndexReg); diff --git a/llvm/test/CodeGen/X86/leaFixup32.mir b/llvm/test/CodeGen/X86/leaFixup32.mir --- a/llvm/test/CodeGen/X86/leaFixup32.mir +++ b/llvm/test/CodeGen/X86/leaFixup32.mir @@ -376,8 +376,7 @@ ; CHECK-LABEL: name: test1mov1add_ebp_32 ; CHECK: liveins: $eax, $ebp, $ebx - ; CHECK: $ebx = MOV32rr $ebp - ; CHECK: $ebx = ADD32rr $ebx, $ebp, implicit-def $eflags + ; CHECK: $ebx = LEA32r $noreg, 2, $ebp, 0, $noreg ; CHECK: RET64 $ebx $ebx = LEA32r killed $ebp, 1, $ebp, 0, $noreg RET64 $ebx @@ -414,8 +413,7 @@ ; CHECK-LABEL: name: testleaadd_ebp_index_32 ; CHECK: liveins: $eax, $ebp, $ebx - ; CHECK: $ebx = LEA32r $noreg, 1, $ebp, 5, $noreg - ; CHECK: $ebx = ADD32rr $ebx, $ebp, implicit-def $eflags + ; CHECK: $ebx = LEA32r $noreg, 2, $ebp, 5, $noreg ; CHECK: RET64 $ebx $ebx = LEA32r $ebp, 1, $ebp, 5, $noreg RET64 $ebx diff --git a/llvm/test/CodeGen/X86/leaFixup64.mir b/llvm/test/CodeGen/X86/leaFixup64.mir --- a/llvm/test/CodeGen/X86/leaFixup64.mir +++ b/llvm/test/CodeGen/X86/leaFixup64.mir @@ -722,7 +722,7 @@ ; CHECK-LABEL: name: test1mov1add_rbp_64_32 ; CHECK: liveins: $rax, $rbp, $rbx - ; CHECK: $ebx = LEA64_32r killed $rbp, 1, killed $rbp, 0, $noreg + ; CHECK: $ebx = LEA64_32r $noreg, 2, killed $rbp, 0, $noreg ; CHECK: RET64 $ebx $ebx = LEA64_32r killed $rbp, 1, killed $rbp, 0, $noreg RET64 $ebx @@ -759,7 +759,7 @@ ; CHECK-LABEL: name: testleaadd_rbp_index_64_32 ; CHECK: liveins: $rax, $rbp, $rbx - ; CHECK: $ebx = LEA64_32r killed $rbp, 1, killed $rbp, 5, $noreg + ; CHECK: $ebx = LEA64_32r $noreg, 2, killed $rbp, 5, $noreg ; CHECK: RET64 $ebx $ebx = LEA64_32r killed $rbp, 1, killed $rbp, 5, $noreg RET64 $ebx @@ -871,8 +871,7 @@ ; CHECK-LABEL: name: test1mov1add_rbp_64 ; CHECK: liveins: $rax, $rbp, $rbx - ; CHECK: $rbx = MOV64rr $rbp - ; CHECK: $rbx = ADD64rr $rbx, $rbp, implicit-def $eflags + ; CHECK: $rbx = LEA64r $noreg, 2, $rbp, 0, $noreg ; CHECK: RET64 $ebx $rbx = LEA64r killed $rbp, 1, $rbp, 0, $noreg RET64 $ebx @@ -909,8 +908,7 @@ ; CHECK-LABEL: name: testleaadd_rbp_index_64 ; CHECK: liveins: $rax, $rbp, $rbx - ; CHECK: $rbx = LEA64r $noreg, 1, $rbp, 5, $noreg - ; CHECK: $rbx = ADD64rr $rbx, $rbp, implicit-def $eflags + ; CHECK: $rbx = LEA64r $noreg, 2, $rbp, 5, $noreg ; CHECK: RET64 $ebx $rbx = LEA64r $rbp, 1, $rbp, 5, $noreg RET64 $ebx diff --git a/llvm/test/CodeGen/X86/select-1-or-neg1.ll b/llvm/test/CodeGen/X86/select-1-or-neg1.ll --- a/llvm/test/CodeGen/X86/select-1-or-neg1.ll +++ b/llvm/test/CodeGen/X86/select-1-or-neg1.ll @@ -19,8 +19,7 @@ ; SLOWLEA3-NEXT: xorl %eax, %eax ; SLOWLEA3-NEXT: cmpl $1, %edi ; SLOWLEA3-NEXT: sete %al -; SLOWLEA3-NEXT: addl %eax, %eax -; SLOWLEA3-NEXT: decl %eax +; SLOWLEA3-NEXT: leal -1(,%rax,2), %eax ; SLOWLEA3-NEXT: retq %cmp = icmp eq i32 %x, 1 %sel = select i1 %cmp, i32 1, i32 -1