[llvm] a2f4534 - Transform slow LEA_B_I_D/LEA_SLOWBASE_I -> LEA_IS_D/LEA_IS iff base == index
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 31 23:26:39 PST 2023
Author: Noah Goldstein
Date: 2023-02-01T01:26:06-06:00
New Revision: a2f45348d4ea93434d166ab9c6f73a28dba18595
URL: https://github.com/llvm/llvm-project/commit/a2f45348d4ea93434d166ab9c6f73a28dba18595
DIFF: https://github.com/llvm/llvm-project/commit/a2f45348d4ea93434d166ab9c6f73a28dba18595.diff
LOG: Transform slow LEA_B_I_D/LEA_SLOWBASE_I -> LEA_IS_D/LEA_IS iff base == index
The two 3c LEA cases:
lea D(base, index,1) -> lea D(,index,2)
lea D(r13/rbp, index) -> lea D(,r13/rbp,2) // D maybe zero
Current take 2 instructions to transform. We can do a bit better by
using LEA w.o a base if base == index and scale == 1.
Reviewed By: pengfei
Differential Revision: https://reviews.llvm.org/D141980
Added:
Modified:
llvm/lib/Target/X86/X86FixupLEAs.cpp
llvm/test/CodeGen/X86/leaFixup32.mir
llvm/test/CodeGen/X86/leaFixup64.mir
llvm/test/CodeGen/X86/select-1-or-neg1.ll
llvm/test/DebugInfo/MIR/InstrRef/x86-lea-fixup-2.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86FixupLEAs.cpp b/llvm/lib/Target/X86/X86FixupLEAs.cpp
index b01145809ac6d..5c1ac8dd96715 100644
--- a/llvm/lib/Target/X86/X86FixupLEAs.cpp
+++ b/llvm/lib/Target/X86/X86FixupLEAs.cpp
@@ -786,12 +786,34 @@ void FixupLEAPass::processInstrForSlow3OpLEA(MachineBasicBlock::iterator &I,
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
index c929df8acfc1f..d1de6793f0f71 100644
--- a/llvm/test/CodeGen/X86/leaFixup32.mir
+++ b/llvm/test/CodeGen/X86/leaFixup32.mir
@@ -48,15 +48,15 @@
ret i32 0
}
- ;test1mov1add_ebp_32: 2 operands LEA32r that can be replaced with 1 add 1 mov instructions
+ ;test_leab_ebp_leais_32: 2 operands LEA32r that can be replaced with LEA_IS form
; where the base is rbp/r13/ebp register
- define i32 @test1mov1add_ebp_32() {
+ define i32 @test_leab_ebp_leais_32() {
ret i32 0
}
- ;testleaadd_ebp_index_32: 3 operands LEA32r that can be replaced with 1 lea 1 add instructions
+ ;test_leabi_ebp_leais_32: 3 operands LEA32r that can be replaced with LEA_IS form
; where the base and the index are ebp register and there is offset
- define i32 @testleaadd_ebp_index_32() {
+ define i32 @test_leabi_ebp_leais_32() {
ret i32 0
}
@@ -345,7 +345,7 @@ body: |
...
---
-name: test1mov1add_ebp_32
+name: test_leab_ebp_leais_32
alignment: 16
exposesReturnsTwice: false
legalized: false
@@ -374,17 +374,16 @@ body: |
bb.0 (%ir-block.0):
liveins: $eax, $ebp, $ebx
- ; CHECK-LABEL: name: test1mov1add_ebp_32
+ ; CHECK-LABEL: name: test_leab_ebp_leais_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
...
---
-name: testleaadd_ebp_index_32
+name: test_leabi_ebp_leais_32
alignment: 16
exposesReturnsTwice: false
legalized: false
@@ -412,10 +411,9 @@ body: |
bb.0 (%ir-block.0):
liveins: $eax, $ebp, $ebx
- ; CHECK-LABEL: name: testleaadd_ebp_index_32
+ ; CHECK-LABEL: name: test_leabi_ebp_leais_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
index 2bab3c10e78e3..fe5c414a56f95 100644
--- a/llvm/test/CodeGen/X86/leaFixup64.mir
+++ b/llvm/test/CodeGen/X86/leaFixup64.mir
@@ -86,15 +86,15 @@
ret i32 0
}
- ;test1mov1add_rbp_64_32: 2 operands LEA64_32r cannot be replaced with 1 add 1 mov instructions
+ ;test_leab_rbp_leais_64_32: 2 operands LEA64_32r that can be replaced with LEA_IS form
; where the base is rbp/r13/ebp register
- define i32 @test1mov1add_rbp_64_32() {
+ define i32 @test_leab_rbp_leais_64_32() {
ret i32 0
}
- ;testleaadd_rbp_index_64_32: 3 operands LEA64_32r that cannot replaced with 1 lea 1 add instructions
+ ;test_leabi_rbp_leais_64_32: 3 operands LEA64_32r that can be replaced with LEA_IS form
; where the base and the index are ebp register and there is offset
- define i32 @testleaadd_rbp_index_64_32() {
+ define i32 @test_leabi_rbp_leais_64_32() {
ret i32 0
}
@@ -110,15 +110,15 @@
ret i32 0
}
- ;test1mov1add_rbp_64: 2 operands LEA64r that can be replaced with 1 add 1 mov instructions
+ ;test_leab_rbp_leais_64: 2 operands LEA64r that can be replaced with LEA_IS form
; where the base is rbp/r13/ebp register
- define i32 @test1mov1add_rbp_64() {
+ define i32 @test_leab_rbp_leais_64() {
ret i32 0
}
- ;testleaadd_rbp_index_64: 3 operands LEA64r that can be replaced with 1 lea 1 add instructions
+ ;test_leabi_rbp_leais_64: 3 operands LEA64r that can be replaced with LEA_IS form
; where the base and the index are ebp register and there is offset
- define i32 @testleaadd_rbp_index_64() {
+ define i32 @test_leabi_rbp_leais_64() {
ret i32 0
}
@@ -692,7 +692,7 @@ body: |
...
---
-name: test1mov1add_rbp_64_32
+name: test_leab_rbp_leais_64_32
alignment: 16
exposesReturnsTwice: false
legalized: false
@@ -720,16 +720,16 @@ body: |
bb.0 (%ir-block.0):
liveins: $rax, $rbp, $rbx
- ; CHECK-LABEL: name: test1mov1add_rbp_64_32
+ ; CHECK-LABEL: name: test_leab_rbp_leais_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
...
---
-name: testleaadd_rbp_index_64_32
+name: test_leabi_rbp_leais_64_32
alignment: 16
exposesReturnsTwice: false
legalized: false
@@ -757,9 +757,9 @@ body: |
bb.0 (%ir-block.0):
liveins: $rax, $rbp, $rbx
- ; CHECK-LABEL: name: testleaadd_rbp_index_64_32
+ ; CHECK-LABEL: name: test_leabi_rbp_leais_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
@@ -841,7 +841,7 @@ body: |
...
---
-name: test1mov1add_rbp_64
+name: test_leab_rbp_leais_64
alignment: 16
exposesReturnsTwice: false
legalized: false
@@ -869,17 +869,16 @@ body: |
bb.0 (%ir-block.0):
liveins: $rax, $rbp, $rbx
- ; CHECK-LABEL: name: test1mov1add_rbp_64
+ ; CHECK-LABEL: name: test_leab_rbp_leais_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
...
---
-name: testleaadd_rbp_index_64
+name: test_leabi_rbp_leais_64
alignment: 16
exposesReturnsTwice: false
legalized: false
@@ -907,10 +906,9 @@ body: |
bb.0 (%ir-block.0):
liveins: $rax, $rbp, $rbx
- ; CHECK-LABEL: name: testleaadd_rbp_index_64
+ ; CHECK-LABEL: name: test_leabi_rbp_leais_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
index c85cc08f886b3..9a4cb55e52bd9 100644
--- a/llvm/test/CodeGen/X86/select-1-or-neg1.ll
+++ b/llvm/test/CodeGen/X86/select-1-or-neg1.ll
@@ -19,8 +19,7 @@ define i32 @PR28968(i32 %x) {
; 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
diff --git a/llvm/test/DebugInfo/MIR/InstrRef/x86-lea-fixup-2.mir b/llvm/test/DebugInfo/MIR/InstrRef/x86-lea-fixup-2.mir
index f834a9e2ed5f7..778e1f8fa4420 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/x86-lea-fixup-2.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/x86-lea-fixup-2.mir
@@ -23,8 +23,8 @@ body: |
...
---
-name: test1mov1add_ebp_32
-# CHECK-LABEL: name: test1mov1add_ebp_32
+name: testleais_ebp_32
+# CHECK-LABEL: name: testleais_ebp_32
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
@@ -38,14 +38,14 @@ body: |
bb.0:
liveins: $eax, $ebp, $ebx
- ; CHECK: $ebx = ADD32rr {{.*}} debug-instr-number 2
+ ; CHECK: $ebx = LEA32r $noreg, 2, $ebp, 0, $noreg, debug-instr-number 2
$ebx = LEA32r killed $ebp, 1, $ebp, 0, $noreg, debug-instr-number 1
RET64 $ebx
...
---
-name: testleaadd_ebp_index_32
-# CHECK-LABEL: name: testleaadd_ebp_index_32
+name: testleabid_ebp_leaisd_32
+# CHECK-LABEL: name: testleabid_ebp_leaisd_32
alignment: 16
tracksRegLiveness: true
debugInstrRef: true
@@ -58,7 +58,7 @@ body: |
bb.0:
liveins: $eax, $ebp, $ebx
- ; CHECK: $ebx = ADD32rr {{.*}} debug-instr-number 2
+ ; CHECK: $ebx = LEA32r $noreg, 2, $ebp, 5, $noreg, debug-instr-number 2
$ebx = LEA32r $ebp, 1, $ebp, 5, $noreg, debug-instr-number 1
RET64 $ebx
More information about the llvm-commits
mailing list