[llvm] r302412 - [GlobalISel][X86] G_GEP selection support.
Igor Breger via llvm-commits
llvm-commits at lists.llvm.org
Mon May 8 02:40:43 PDT 2017
Author: ibreger
Date: Mon May 8 04:40:43 2017
New Revision: 302412
URL: http://llvm.org/viewvc/llvm-project?rev=302412&view=rev
Log:
[GlobalISel][X86] G_GEP selection support.
Summary: [GlobalISel][X86] G_GEP selection support.
Reviewers: zvi, guyblank
Reviewed By: guyblank
Subscribers: dberris, rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D32396
Added:
llvm/trunk/test/CodeGen/X86/GlobalISel/gep.ll
llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-gep.mir
llvm/trunk/test/CodeGen/X86/GlobalISel/select-gep.mir
Modified:
llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=302412&r1=302411&r2=302412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Mon May 8 04:40:43 2017
@@ -65,8 +65,8 @@ private:
MachineFunction &MF) const;
bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
- bool selectFrameIndex(MachineInstr &I, MachineRegisterInfo &MRI,
- MachineFunction &MF) const;
+ bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
+ MachineFunction &MF) const;
bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
@@ -235,7 +235,7 @@ bool X86InstructionSelector::select(Mach
return true;
if (selectLoadStoreOp(I, MRI, MF))
return true;
- if (selectFrameIndex(I, MRI, MF))
+ if (selectFrameIndexOrGep(I, MRI, MF))
return true;
if (selectConstant(I, MRI, MF))
return true;
@@ -427,27 +427,37 @@ bool X86InstructionSelector::selectLoadS
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
-bool X86InstructionSelector::selectFrameIndex(MachineInstr &I,
- MachineRegisterInfo &MRI,
- MachineFunction &MF) const {
- if (I.getOpcode() != TargetOpcode::G_FRAME_INDEX)
+bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
+ MachineRegisterInfo &MRI,
+ MachineFunction &MF) const {
+ unsigned Opc = I.getOpcode();
+
+ if (Opc != TargetOpcode::G_FRAME_INDEX && Opc != TargetOpcode::G_GEP)
return false;
const unsigned DefReg = I.getOperand(0).getReg();
LLT Ty = MRI.getType(DefReg);
- // Use LEA to calculate frame index.
+ // Use LEA to calculate frame index and GEP
unsigned NewOpc;
if (Ty == LLT::pointer(0, 64))
NewOpc = X86::LEA64r;
else if (Ty == LLT::pointer(0, 32))
NewOpc = STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
else
- llvm_unreachable("Can't select G_FRAME_INDEX, unsupported type.");
+ llvm_unreachable("Can't select G_FRAME_INDEX/G_GEP, unsupported type.");
I.setDesc(TII.get(NewOpc));
MachineInstrBuilder MIB(MF, I);
- addOffset(MIB, 0);
+
+ if (Opc == TargetOpcode::G_FRAME_INDEX) {
+ addOffset(MIB, 0);
+ } else {
+ MachineOperand &InxOp = I.getOperand(2);
+ I.addOperand(InxOp); // set IndexReg
+ InxOp.ChangeToImmediate(1); // set Scale
+ MIB.addImm(0).addReg(0);
+ }
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=302412&r1=302411&r2=302412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Mon May 8 04:40:43 2017
@@ -70,6 +70,12 @@ void X86LegalizerInfo::setLegalizerInfo3
// Pointer-handling
setAction({G_FRAME_INDEX, p0}, Legal);
+ setAction({G_GEP, p0}, Legal);
+ setAction({G_GEP, 1, s32}, Legal);
+
+ for (auto Ty : {s1, s8, s16})
+ setAction({G_GEP, 1, Ty}, WidenScalar);
+
// Constants
for (auto Ty : {s8, s16, s32, p0})
setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
@@ -114,6 +120,13 @@ void X86LegalizerInfo::setLegalizerInfo6
// Pointer-handling
setAction({G_FRAME_INDEX, p0}, Legal);
+ setAction({G_GEP, p0}, Legal);
+ setAction({G_GEP, 1, s32}, Legal);
+ setAction({G_GEP, 1, s64}, Legal);
+
+ for (auto Ty : {s1, s8, s16})
+ setAction({G_GEP, 1, Ty}, WidenScalar);
+
// Constants
for (auto Ty : {s8, s16, s32, s64, p0})
setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/gep.ll?rev=302412&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/gep.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/gep.ll Mon May 8 04:40:43 2017
@@ -0,0 +1,136 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64_GISEL
+; RUN: llc -mtriple=x86_64-linux-gnu < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
+
+define i32* @test_gep_i8(i32 *%arr, i8 %ind) {
+; X64_GISEL-LABEL: test_gep_i8:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $4, %rax
+; X64_GISEL-NEXT: movsbq %sil, %rcx
+; X64_GISEL-NEXT: imulq %rax, %rcx
+; X64_GISEL-NEXT: leaq (%rdi,%rcx), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i8:
+; X64: # BB#0:
+; X64-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def>
+; X64-NEXT: movsbq %sil, %rax
+; X64-NEXT: leaq (%rdi,%rax,4), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i8 %ind
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i8_const(i32 *%arr) {
+; X64_GISEL-LABEL: test_gep_i8_const:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $80, %rax
+; X64_GISEL-NEXT: leaq (%rdi,%rax), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i8_const:
+; X64: # BB#0:
+; X64-NEXT: leaq 80(%rdi), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i8 20
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i16(i32 *%arr, i16 %ind) {
+; X64_GISEL-LABEL: test_gep_i16:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $4, %rax
+; X64_GISEL-NEXT: movswq %si, %rcx
+; X64_GISEL-NEXT: imulq %rax, %rcx
+; X64_GISEL-NEXT: leaq (%rdi,%rcx), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i16:
+; X64: # BB#0:
+; X64-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def>
+; X64-NEXT: movswq %si, %rax
+; X64-NEXT: leaq (%rdi,%rax,4), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i16 %ind
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i16_const(i32 *%arr) {
+; X64_GISEL-LABEL: test_gep_i16_const:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $80, %rax
+; X64_GISEL-NEXT: leaq (%rdi,%rax), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i16_const:
+; X64: # BB#0:
+; X64-NEXT: leaq 80(%rdi), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i16 20
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i32(i32 *%arr, i32 %ind) {
+; X64_GISEL-LABEL: test_gep_i32:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $4, %rax
+; X64_GISEL-NEXT: movslq %esi, %rcx
+; X64_GISEL-NEXT: imulq %rax, %rcx
+; X64_GISEL-NEXT: leaq (%rdi,%rcx), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i32:
+; X64: # BB#0:
+; X64-NEXT: movslq %esi, %rax
+; X64-NEXT: leaq (%rdi,%rax,4), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i32 %ind
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i32_const(i32 *%arr) {
+; X64_GISEL-LABEL: test_gep_i32_const:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $20, %rax
+; X64_GISEL-NEXT: leaq (%rdi,%rax), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i32_const:
+; X64: # BB#0:
+; X64-NEXT: leaq 20(%rdi), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i32 5
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i64(i32 *%arr, i64 %ind) {
+; X64_GISEL-LABEL: test_gep_i64:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $4, %rax
+; X64_GISEL-NEXT: imulq %rsi, %rax
+; X64_GISEL-NEXT: leaq (%rdi,%rax), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i64:
+; X64: # BB#0:
+; X64-NEXT: leaq (%rdi,%rsi,4), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i64 %ind
+ ret i32* %arrayidx
+}
+
+define i32* @test_gep_i64_const(i32 *%arr) {
+; X64_GISEL-LABEL: test_gep_i64_const:
+; X64_GISEL: # BB#0:
+; X64_GISEL-NEXT: movq $20, %rax
+; X64_GISEL-NEXT: leaq (%rdi,%rax), %rax
+; X64_GISEL-NEXT: retq
+;
+; X64-LABEL: test_gep_i64_const:
+; X64: # BB#0:
+; X64-NEXT: leaq 20(%rdi), %rax
+; X64-NEXT: retq
+ %arrayidx = getelementptr i32, i32* %arr, i64 5
+ ret i32* %arrayidx
+}
+
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-gep.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-gep.mir?rev=302412&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-gep.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-gep.mir Mon May 8 04:40:43 2017
@@ -0,0 +1,101 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
+
+--- |
+ define void @test_gep_i8() {
+ %arrayidx = getelementptr i32, i32* undef, i8 5
+ ret void
+ }
+
+ define void @test_gep_i16() {
+ %arrayidx = getelementptr i32, i32* undef, i16 5
+ ret void
+ }
+
+ define void @test_gep_i32() {
+ %arrayidx = getelementptr i32, i32* undef, i32 5
+ ret void
+ }
+
+ define void @test_gep_i64() {
+ %arrayidx = getelementptr i32, i32* undef, i64 5
+ ret void
+ }
+...
+---
+name: test_gep_i8
+# CHECK-LABEL: name: test_gep_i8
+legalized: false
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+# CHECK: %0(p0) = IMPLICIT_DEF
+# CHECK-NEXT: %1(s8) = G_CONSTANT i8 20
+# CHECK-NEXT: %3(s32) = G_SEXT %1(s8)
+# CHECK-NEXT: %2(p0) = G_GEP %0, %3(s32)
+# CHECK-NEXT: RET 0
+body: |
+ bb.1 (%ir-block.0):
+ %0(p0) = IMPLICIT_DEF
+ %1(s8) = G_CONSTANT i8 20
+ %2(p0) = G_GEP %0, %1(s8)
+ RET 0
+...
+---
+name: test_gep_i16
+# CHECK-LABEL: name: test_gep_i16
+legalized: false
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+# CHECK: %0(p0) = IMPLICIT_DEF
+# CHECK-NEXT: %1(s16) = G_CONSTANT i16 20
+# CHECK-NEXT: %3(s32) = G_SEXT %1(s16)
+# CHECK-NEXT: %2(p0) = G_GEP %0, %3(s32)
+# CHECK-NEXT: RET 0
+body: |
+ bb.1 (%ir-block.0):
+ %0(p0) = IMPLICIT_DEF
+ %1(s16) = G_CONSTANT i16 20
+ %2(p0) = G_GEP %0, %1(s16)
+ RET 0
+...
+---
+name: test_gep_i32
+# CHECK-LABEL: name: test_gep_i32
+legalized: false
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+# CHECK: %0(p0) = IMPLICIT_DEF
+# CHECK-NEXT: %1(s32) = G_CONSTANT i32 20
+# CHECK-NEXT: %2(p0) = G_GEP %0, %1(s32)
+# CHECK-NEXT: RET 0
+body: |
+ bb.1 (%ir-block.0):
+ %0(p0) = IMPLICIT_DEF
+ %1(s32) = G_CONSTANT i32 20
+ %2(p0) = G_GEP %0, %1(s32)
+ RET 0
+...
+---
+name: test_gep_i64
+# CHECK-LABEL: name: test_gep_i64
+legalized: false
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+# CHECK: %0(p0) = IMPLICIT_DEF
+# CHECK-NEXT: %1(s64) = G_CONSTANT i64 20
+# CHECK-NEXT: %2(p0) = G_GEP %0, %1(s64)
+# CHECK-NEXT: RET 0
+body: |
+ bb.1 (%ir-block.0):
+ %0(p0) = IMPLICIT_DEF
+ %1(s64) = G_CONSTANT i64 20
+ %2(p0) = G_GEP %0, %1(s64)
+ RET 0
+...
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir?rev=302412&r1=302411&r2=302412&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir Mon May 8 04:40:43 2017
@@ -114,6 +114,12 @@
ret void
}
+ define void @test_gep() {
+ %p1 = getelementptr i32, i32* undef, i32 5
+ %p2 = getelementptr i32, i32* undef, i64 5
+ ret void
+ }
+
...
---
name: test_add_i8
@@ -703,3 +709,29 @@ body: |
RET 0
...
+---
+name: test_gep
+legalized: true
+# CHECK-LABEL: name: test_gep
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr }
+# CHECK-NEXT: - { id: 1, class: gpr }
+# CHECK-NEXT: - { id: 2, class: gpr }
+# CHECK-NEXT: - { id: 3, class: gpr }
+# CHECK-NEXT: - { id: 4, class: gpr }
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+ - { id: 4, class: _ }
+body: |
+ bb.0 (%ir-block.0):
+ %0(p0) = IMPLICIT_DEF
+ %1(s32) = G_CONSTANT i32 20
+ %2(p0) = G_GEP %0, %1(s32)
+ %3(s64) = G_CONSTANT i64 20
+ %4(p0) = G_GEP %0, %3(s64)
+ RET 0
+
+...
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-gep.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-gep.mir?rev=302412&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-gep.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-gep.mir Mon May 8 04:40:43 2017
@@ -0,0 +1,37 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK
+
+--- |
+ define i32* @test_gep_i32(i32* %arr) {
+ %arrayidx = getelementptr i32, i32* %arr, i32 5
+ ret i32* %arrayidx
+ }
+...
+---
+name: test_gep_i32
+alignment: 4
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: test_gep_i32
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr64 }
+# CHECK-NEXT: - { id: 1, class: gr64_nosp }
+# CHECK-NEXT: - { id: 2, class: gr64 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+# CHECK: body:
+# CHECK: %1 = MOV64ri32 20
+# CHECK-NEXT: %2 = LEA64r %0, 1, %1, 0, _
+body: |
+ bb.1 (%ir-block.0):
+ liveins: %rdi
+
+ %0(p0) = COPY %rdi
+ %1(s64) = G_CONSTANT i64 20
+ %2(p0) = G_GEP %0, %1(s64)
+ %rax = COPY %2(p0)
+ RET 0, implicit %rax
+
+...
More information about the llvm-commits
mailing list