[llvm] r327520 - [GlobalIsel][X86] Support for G_SDIV instruction

Alexander Ivchenko via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 08:41:11 PDT 2018


Author: aivchenk
Date: Wed Mar 14 08:41:11 2018
New Revision: 327520

URL: http://llvm.org/viewvc/llvm-project?rev=327520&view=rev
Log:
[GlobalIsel][X86] Support for G_SDIV instruction

Reviewed By: igorb

Differential Revision: https://reviews.llvm.org/D44430

Added:
    llvm/trunk/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/x86-select-sdiv.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-legalize-sdiv.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-select-sdiv.mir
Modified:
    llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
    llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
    llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-irtranslator.ll

Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=327520&r1=327519&r2=327520&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Wed Mar 14 08:41:11 2018
@@ -114,6 +114,8 @@ private:
   bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
   bool selectShift(MachineInstr &I, MachineRegisterInfo &MRI,
                    MachineFunction &MF) const;
+  bool selectSDiv(MachineInstr &I, MachineRegisterInfo &MRI,
+                   MachineFunction &MF) const;
 
   // emit insert subreg instruction and insert it before MachineInstr &I
   bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
@@ -379,6 +381,8 @@ bool X86InstructionSelector::select(Mach
   case TargetOpcode::G_ASHR:
   case TargetOpcode::G_LSHR:
     return selectShift(I, MRI, MF);
+  case TargetOpcode::G_SDIV:
+    return selectSDiv(I, MRI, MF);
   }
 
   return false;
@@ -1480,6 +1484,86 @@ bool X86InstructionSelector::selectShift
   I.eraseFromParent();
   return true;
 }
+
+bool X86InstructionSelector::selectSDiv(MachineInstr &I,
+                                        MachineRegisterInfo &MRI,
+                                        MachineFunction &MF) const {
+
+  assert(I.getOpcode() == TargetOpcode::G_SDIV && "unexpected instruction");
+
+  const unsigned DstReg = I.getOperand(0).getReg();
+  const unsigned DividentReg = I.getOperand(1).getReg();
+  const unsigned DiviserReg = I.getOperand(2).getReg();
+
+  const LLT RegTy = MRI.getType(DstReg);
+  assert(RegTy == MRI.getType(DividentReg) &&
+         RegTy == MRI.getType(DiviserReg) &&
+         "Arguments and return value types must match");
+
+  const RegisterBank &RegRB = *RBI.getRegBank(DstReg, MRI, TRI);
+
+  // For the X86 IDIV instruction, in most cases the dividend
+  // (numerator) must be in a specific register pair highreg:lowreg,
+  // producing the quotient in lowreg and the remainder in highreg.
+  // For most data types, to set up the instruction, the dividend is
+  // copied into lowreg, and lowreg is sign-extended into highreg.  The
+  // exception is i8, where the dividend is defined as a single register rather
+  // than a register pair, and we therefore directly sign-extend the dividend
+  // into lowreg, instead of copying, and ignore the highreg.
+  const static struct SDivEntry {
+    unsigned SizeInBits;
+    unsigned QuotientReg;
+    unsigned DividentRegUpper;
+    unsigned DividentRegLower;
+    unsigned OpSignExtend;
+    unsigned OpCopy;
+    unsigned OpDiv;
+  } OpTable[] = {
+      {8, X86::AL, X86::NoRegister, X86::AX, 0, X86::MOVSX16rr8,
+       X86::IDIV8r}, // i8
+      {16, X86::AX, X86::DX, X86::AX, X86::CWD, TargetOpcode::COPY,
+       X86::IDIV16r}, // i16
+      {32, X86::EAX, X86::EDX, X86::EAX, X86::CDQ, TargetOpcode::COPY,
+       X86::IDIV32r}, // i32
+      {64, X86::RAX, X86::RDX, X86::RAX, X86::CQO, TargetOpcode::COPY,
+       X86::IDIV64r} // i64
+  };
+
+  if (RegRB.getID() != X86::GPRRegBankID)
+    return false;
+
+  auto SDivEntryIt = std::find_if(
+      std::begin(OpTable), std::end(OpTable), [RegTy](const SDivEntry &El) {
+    return El.SizeInBits == RegTy.getSizeInBits();
+      });
+
+  if (SDivEntryIt == std::end(OpTable))
+    return false;
+
+  const TargetRegisterClass *RegRC = getRegClass(RegTy, RegRB);
+  if (!RBI.constrainGenericRegister(DividentReg, *RegRC, MRI) ||
+      !RBI.constrainGenericRegister(DiviserReg, *RegRC, MRI) ||
+      !RBI.constrainGenericRegister(DstReg, *RegRC, MRI)) {
+    DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
+                 << " operand\n");
+    return false;
+  }
+
+  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SDivEntryIt->OpCopy),
+          SDivEntryIt->DividentRegLower)
+      .addReg(DividentReg);
+  if (SDivEntryIt->DividentRegUpper != X86::NoRegister)
+    BuildMI(*I.getParent(), I, I.getDebugLoc(),
+            TII.get(SDivEntryIt->OpSignExtend));
+  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SDivEntryIt->OpDiv))
+      .addReg(DiviserReg);
+  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
+          DstReg)
+      .addReg(SDivEntryIt->QuotientReg);
+
+  I.eraseFromParent();
+  return true;
+}
 
 InstructionSelector *
 llvm::createX86InstructionSelector(const X86TargetMachine &TM,

Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=327520&r1=327519&r2=327520&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Wed Mar 14 08:41:11 2018
@@ -131,8 +131,8 @@ void X86LegalizerInfo::setLegalizerInfo3
         .widenScalarToNextPow2(0, /*Min*/ 8);
     getActionDefinitionsBuilder(G_INTTOPTR).legalFor({s32, p0});
 
-    // Shifts
-    getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
+    // Shifts and SDIV
+    getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR, G_SDIV})
         .legalFor({s8, s16, s32})
         .clampScalar(0, s8, s32);
   }
@@ -214,8 +214,8 @@ void X86LegalizerInfo::setLegalizerInfo6
   // Comparison
   setAction({G_ICMP, 1, s64}, Legal);
 
-  // Shifts
-  getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
+  // Shifts and SDIV
+  getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR, G_SDIV})
     .legalFor({s8, s16, s32, s64})
     .clampScalar(0, s8, s64);
 

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir?rev=327520&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir Wed Mar 14 08:41:11 2018
@@ -0,0 +1,114 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=i686-linux-gnu -global-isel -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+  ; ModuleID = 'sdiv.ll'
+  source_filename = "sdiv.ll"
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+  define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) {
+    %res = sdiv i8 %arg1, %arg2
+    ret i8 %res
+  }
+
+  define i16 @test_sdiv_i16(i16 %arg1, i16 %arg2) {
+    %res = sdiv i16 %arg1, %arg2
+    ret i16 %res
+  }
+
+  define i32 @test_sdiv_i32(i32 %arg1, i32 %arg2) {
+    %res = sdiv i32 %arg1, %arg2
+    ret i32 %res
+  }
+
+...
+---
+name:            test_sdiv_i8
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i8
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s8) = G_SDIV [[TRUNC]], [[TRUNC1]]
+    ; CHECK: $al = COPY [[SDIV]](s8)
+    ; CHECK: RET 0, implicit $al
+    %2:_(s32) = COPY $edi
+    %0:_(s8) = G_TRUNC %2(s32)
+    %3:_(s32) = COPY $esi
+    %1:_(s8) = G_TRUNC %3(s32)
+    %4:_(s8) = G_SDIV %0, %1
+    $al = COPY %4(s8)
+    RET 0, implicit $al
+
+...
+---
+name:            test_sdiv_i16
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i16
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s16) = G_SDIV [[TRUNC]], [[TRUNC1]]
+    ; CHECK: $ax = COPY [[SDIV]](s16)
+    ; CHECK: RET 0, implicit $ax
+    %2:_(s32) = COPY $edi
+    %0:_(s16) = G_TRUNC %2(s32)
+    %3:_(s32) = COPY $esi
+    %1:_(s16) = G_TRUNC %3(s32)
+    %4:_(s16) = G_SDIV %0, %1
+    $ax = COPY %4(s16)
+    RET 0, implicit $ax
+
+...
+---
+name:            test_sdiv_i32
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i32
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
+    ; CHECK: $eax = COPY [[SDIV]](s32)
+    ; CHECK: RET 0, implicit $eax
+    %0:_(s32) = COPY $edi
+    %1:_(s32) = COPY $esi
+    %2:_(s32) = G_SDIV %0, %1
+    $eax = COPY %2(s32)
+    RET 0, implicit $eax
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/x86-select-sdiv.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/x86-select-sdiv.mir?rev=327520&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/x86-select-sdiv.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/x86-select-sdiv.mir Wed Mar 14 08:41:11 2018
@@ -0,0 +1,128 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+  ; ModuleID = 'sdiv.ll'
+  source_filename = "sdiv.ll"
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+  define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) {
+    %res = sdiv i8 %arg1, %arg2
+    ret i8 %res
+  }
+
+  define i16 @test_sdiv_i16(i16 %arg1, i16 %arg2) {
+    %res = sdiv i16 %arg1, %arg2
+    ret i16 %res
+  }
+
+  define i32 @test_sdiv_i32(i32 %arg1, i32 %arg2) {
+    %res = sdiv i32 %arg1, %arg2
+    ret i32 %res
+  }
+
+...
+---
+name:            test_sdiv_i8
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+  - { id: 4, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i8
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:gr32_abcd = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
+    ; CHECK: [[COPY2:%[0-9]+]]:gr32_abcd = COPY $esi
+    ; CHECK: [[COPY3:%[0-9]+]]:gr8 = COPY [[COPY2]].sub_8bit
+    ; CHECK: $ax = MOVSX16rr8 [[COPY1]]
+    ; CHECK: IDIV8r [[COPY3]], implicit-def $al, implicit-def $ah, implicit-def $eflags, implicit $ax
+    ; CHECK: [[COPY4:%[0-9]+]]:gr8 = COPY $al
+    ; CHECK: $al = COPY [[COPY4]]
+    ; CHECK: RET 0, implicit $al
+    %2:gpr(s32) = COPY $edi
+    %0:gpr(s8) = G_TRUNC %2(s32)
+    %3:gpr(s32) = COPY $esi
+    %1:gpr(s8) = G_TRUNC %3(s32)
+    %4:gpr(s8) = G_SDIV %0, %1
+    $al = COPY %4(s8)
+    RET 0, implicit $al
+
+...
+---
+name:            test_sdiv_i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+  - { id: 4, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i16
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
+    ; CHECK: [[COPY2:%[0-9]+]]:gr32 = COPY $esi
+    ; CHECK: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit
+    ; CHECK: $ax = COPY [[COPY1]]
+    ; CHECK: CWD implicit-def $ax, implicit-def $dx, implicit $ax
+    ; CHECK: IDIV16r [[COPY3]], implicit-def $ax, implicit-def $dx, implicit-def $eflags, implicit $ax, implicit $dx
+    ; CHECK: [[COPY4:%[0-9]+]]:gr16 = COPY $ax
+    ; CHECK: $ax = COPY [[COPY4]]
+    ; CHECK: RET 0, implicit $ax
+    %2:gpr(s32) = COPY $edi
+    %0:gpr(s16) = G_TRUNC %2(s32)
+    %3:gpr(s32) = COPY $esi
+    %1:gpr(s16) = G_TRUNC %3(s32)
+    %4:gpr(s16) = G_SDIV %0, %1
+    $ax = COPY %4(s16)
+    RET 0, implicit $ax
+
+...
+---
+name:            test_sdiv_i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i32
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
+    ; CHECK: $eax = COPY [[COPY]]
+    ; CHECK: CDQ implicit-def $eax, implicit-def $edx, implicit $eax
+    ; CHECK: IDIV32r [[COPY1]], implicit-def $eax, implicit-def $edx, implicit-def $eflags, implicit $eax, implicit $edx
+    ; CHECK: [[COPY2:%[0-9]+]]:gr32 = COPY $eax
+    ; CHECK: $eax = COPY [[COPY2]]
+    ; CHECK: RET 0, implicit $eax
+    %0:gpr(s32) = COPY $edi
+    %1:gpr(s32) = COPY $esi
+    %2:gpr(s32) = G_SDIV %0, %1
+    $eax = COPY %2(s32)
+    RET 0, implicit $eax
+
+...

Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-irtranslator.ll?rev=327520&r1=327519&r2=327520&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-irtranslator.ll Wed Mar 14 08:41:11 2018
@@ -129,3 +129,59 @@ define i64 @zext_i32_to_i64(i32 %val) {
   %res = zext i32 %val to i64
   ret i64 %res
 }
+
+define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) {
+  ; CHECK-LABEL: name: test_sdiv_i8
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $edi, $esi
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+  ; CHECK:   [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+  ; CHECK:   [[SDIV:%[0-9]+]]:_(s8) = G_SDIV [[TRUNC]], [[TRUNC1]]
+  ; CHECK:   $al = COPY [[SDIV]](s8)
+  ; CHECK:   RET 0, implicit $al
+  %res = sdiv i8 %arg1, %arg2
+  ret i8 %res
+}
+
+define i16 @test_sdiv_i16(i16 %arg1, i16 %arg2) {
+  ; CHECK-LABEL: name: test_sdiv_i16
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $edi, $esi
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+  ; CHECK:   [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+  ; CHECK:   [[SDIV:%[0-9]+]]:_(s16) = G_SDIV [[TRUNC]], [[TRUNC1]]
+  ; CHECK:   $ax = COPY [[SDIV]](s16)
+  ; CHECK:   RET 0, implicit $ax
+  %res = sdiv i16 %arg1, %arg2
+  ret i16 %res
+}
+
+define i32 @test_sdiv_i32(i32 %arg1, i32 %arg2) {
+  ; CHECK-LABEL: name: test_sdiv_i32
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $edi, $esi
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+  ; CHECK:   [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
+  ; CHECK:   $eax = COPY [[SDIV]](s32)
+  ; CHECK:   RET 0, implicit $eax
+  %res = sdiv i32 %arg1, %arg2
+  ret i32 %res
+}
+
+define i64 @test_sdiv_i64(i64 %arg1, i64 %arg2) {
+  ; CHECK-LABEL: name: test_sdiv_i64
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $rdi, $rsi
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
+  ; CHECK:   [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[COPY]], [[COPY1]]
+  ; CHECK:   $rax = COPY [[SDIV]](s64)
+  ; CHECK:   RET 0, implicit $rax
+  %res = sdiv i64 %arg1, %arg2
+  ret i64 %res
+}

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-legalize-sdiv.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-legalize-sdiv.mir?rev=327520&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-legalize-sdiv.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-legalize-sdiv.mir Wed Mar 14 08:41:11 2018
@@ -0,0 +1,145 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+  ; ModuleID = 'sdiv.ll'
+  source_filename = "sdiv.ll"
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+  define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) {
+    %res = sdiv i8 %arg1, %arg2
+    ret i8 %res
+  }
+
+  define i16 @test_sdiv_i16(i16 %arg1, i16 %arg2) {
+    %res = sdiv i16 %arg1, %arg2
+    ret i16 %res
+  }
+
+  define i32 @test_sdiv_i32(i32 %arg1, i32 %arg2) {
+    %res = sdiv i32 %arg1, %arg2
+    ret i32 %res
+  }
+
+  define i64 @test_sdiv_i64(i64 %arg1, i64 %arg2) {
+    %res = sdiv i64 %arg1, %arg2
+    ret i64 %res
+  }
+
+...
+---
+name:            test_sdiv_i8
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i8
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s8) = G_SDIV [[TRUNC]], [[TRUNC1]]
+    ; CHECK: $al = COPY [[SDIV]](s8)
+    ; CHECK: RET 0, implicit $al
+    %2:_(s32) = COPY $edi
+    %0:_(s8) = G_TRUNC %2(s32)
+    %3:_(s32) = COPY $esi
+    %1:_(s8) = G_TRUNC %3(s32)
+    %4:_(s8) = G_SDIV %0, %1
+    $al = COPY %4(s8)
+    RET 0, implicit $al
+
+...
+---
+name:            test_sdiv_i16
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i16
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s16) = G_SDIV [[TRUNC]], [[TRUNC1]]
+    ; CHECK: $ax = COPY [[SDIV]](s16)
+    ; CHECK: RET 0, implicit $ax
+    %2:_(s32) = COPY $edi
+    %0:_(s16) = G_TRUNC %2(s32)
+    %3:_(s32) = COPY $esi
+    %1:_(s16) = G_TRUNC %3(s32)
+    %4:_(s16) = G_SDIV %0, %1
+    $ax = COPY %4(s16)
+    RET 0, implicit $ax
+
+...
+---
+name:            test_sdiv_i32
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i32
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
+    ; CHECK: $eax = COPY [[SDIV]](s32)
+    ; CHECK: RET 0, implicit $eax
+    %0:_(s32) = COPY $edi
+    %1:_(s32) = COPY $esi
+    %2:_(s32) = G_SDIV %0, %1
+    $eax = COPY %2(s32)
+    RET 0, implicit $eax
+
+...
+---
+name:            test_sdiv_i64
+alignment:       4
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $rdi, $rsi
+
+    ; CHECK-LABEL: name: test_sdiv_i64
+    ; CHECK: liveins: $rdi, $rsi
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
+    ; CHECK: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[COPY]], [[COPY1]]
+    ; CHECK: $rax = COPY [[SDIV]](s64)
+    ; CHECK: RET 0, implicit $rax
+    %0:_(s64) = COPY $rdi
+    %1:_(s64) = COPY $rsi
+    %2:_(s64) = G_SDIV %0, %1
+    $rax = COPY %2(s64)
+    RET 0, implicit $rax
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-select-sdiv.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-select-sdiv.mir?rev=327520&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-select-sdiv.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/x86_64-select-sdiv.mir Wed Mar 14 08:41:11 2018
@@ -0,0 +1,164 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+  ; ModuleID = 'sdiv.ll'
+  source_filename = "sdiv.ll"
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+  define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) {
+    %res = sdiv i8 %arg1, %arg2
+    ret i8 %res
+  }
+
+  define i16 @test_sdiv_i16(i16 %arg1, i16 %arg2) {
+    %res = sdiv i16 %arg1, %arg2
+    ret i16 %res
+  }
+
+  define i32 @test_sdiv_i32(i32 %arg1, i32 %arg2) {
+    %res = sdiv i32 %arg1, %arg2
+    ret i32 %res
+  }
+
+  define i64 @test_sdiv_i64(i64 %arg1, i64 %arg2) {
+    %res = sdiv i64 %arg1, %arg2
+    ret i64 %res
+  }
+
+...
+---
+name:            test_sdiv_i8
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+  - { id: 4, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i8
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
+    ; CHECK: [[COPY2:%[0-9]+]]:gr32 = COPY $esi
+    ; CHECK: [[COPY3:%[0-9]+]]:gr8 = COPY [[COPY2]].sub_8bit
+    ; CHECK: $ax = MOVSX16rr8 [[COPY1]]
+    ; CHECK: IDIV8r [[COPY3]], implicit-def $al, implicit-def $ah, implicit-def $eflags, implicit $ax
+    ; CHECK: [[COPY4:%[0-9]+]]:gr8 = COPY $al
+    ; CHECK: $al = COPY [[COPY4]]
+    ; CHECK: RET 0, implicit $al
+    %2:gpr(s32) = COPY $edi
+    %0:gpr(s8) = G_TRUNC %2(s32)
+    %3:gpr(s32) = COPY $esi
+    %1:gpr(s8) = G_TRUNC %3(s32)
+    %4:gpr(s8) = G_SDIV %0, %1
+    $al = COPY %4(s8)
+    RET 0, implicit $al
+
+...
+---
+name:            test_sdiv_i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+  - { id: 4, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i16
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
+    ; CHECK: [[COPY2:%[0-9]+]]:gr32 = COPY $esi
+    ; CHECK: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit
+    ; CHECK: $ax = COPY [[COPY1]]
+    ; CHECK: CWD implicit-def $ax, implicit-def $dx, implicit $ax
+    ; CHECK: IDIV16r [[COPY3]], implicit-def $ax, implicit-def $dx, implicit-def $eflags, implicit $ax, implicit $dx
+    ; CHECK: [[COPY4:%[0-9]+]]:gr16 = COPY $ax
+    ; CHECK: $ax = COPY [[COPY4]]
+    ; CHECK: RET 0, implicit $ax
+    %2:gpr(s32) = COPY $edi
+    %0:gpr(s16) = G_TRUNC %2(s32)
+    %3:gpr(s32) = COPY $esi
+    %1:gpr(s16) = G_TRUNC %3(s32)
+    %4:gpr(s16) = G_SDIV %0, %1
+    $ax = COPY %4(s16)
+    RET 0, implicit $ax
+
+...
+---
+name:            test_sdiv_i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $edi, $esi
+
+    ; CHECK-LABEL: name: test_sdiv_i32
+    ; CHECK: liveins: $edi, $esi
+    ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
+    ; CHECK: $eax = COPY [[COPY]]
+    ; CHECK: CDQ implicit-def $eax, implicit-def $edx, implicit $eax
+    ; CHECK: IDIV32r [[COPY1]], implicit-def $eax, implicit-def $edx, implicit-def $eflags, implicit $eax, implicit $edx
+    ; CHECK: [[COPY2:%[0-9]+]]:gr32 = COPY $eax
+    ; CHECK: $eax = COPY [[COPY2]]
+    ; CHECK: RET 0, implicit $eax
+    %0:gpr(s32) = COPY $edi
+    %1:gpr(s32) = COPY $esi
+    %2:gpr(s32) = G_SDIV %0, %1
+    $eax = COPY %2(s32)
+    RET 0, implicit $eax
+
+...
+---
+name:            test_sdiv_i64
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: $rdi, $rsi
+
+    ; CHECK-LABEL: name: test_sdiv_i64
+    ; CHECK: liveins: $rdi, $rsi
+    ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
+    ; CHECK: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
+    ; CHECK: $rax = COPY [[COPY]]
+    ; CHECK: CQO implicit-def $rax, implicit-def $rdx, implicit $rax
+    ; CHECK: IDIV64r [[COPY1]], implicit-def $rax, implicit-def $rdx, implicit-def $eflags, implicit $rax, implicit $rdx
+    ; CHECK: [[COPY2:%[0-9]+]]:gr64 = COPY $rax
+    ; CHECK: $rax = COPY [[COPY2]]
+    ; CHECK: RET 0, implicit $rax
+    %0:gpr(s64) = COPY $rdi
+    %1:gpr(s64) = COPY $rsi
+    %2:gpr(s64) = G_SDIV %0, %1
+    $rax = COPY %2(s64)
+    RET 0, implicit $rax
+
+...




More information about the llvm-commits mailing list