[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