GlobalISel: legalize sdiv and srem operations.

llvm-svn: 279842
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index 401f29a..ec59c83 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -42,6 +42,8 @@
     return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
   case MachineLegalizer::WidenScalar:
     return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
+  case MachineLegalizer::Lower:
+    return lower(MI, std::get<1>(Action), std::get<2>(Action));
   case MachineLegalizer::FewerElements:
     return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
   default:
@@ -269,6 +271,33 @@
 }
 
 MachineLegalizeHelper::LegalizeResult
+MachineLegalizeHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
+  using namespace TargetOpcode;
+  unsigned Size = Ty.getSizeInBits();
+  MIRBuilder.setInstr(MI);
+
+  switch(MI.getOpcode()) {
+  default:
+    return UnableToLegalize;
+  case TargetOpcode::G_SREM:
+  case TargetOpcode::G_UREM: {
+    unsigned QuotReg = MRI.createGenericVirtualRegister(Size);
+    MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV, Ty)
+        .addDef(QuotReg)
+        .addUse(MI.getOperand(1).getReg())
+        .addUse(MI.getOperand(2).getReg());
+
+    unsigned ProdReg = MRI.createGenericVirtualRegister(Size);
+    MIRBuilder.buildMul(Ty, ProdReg, QuotReg, MI.getOperand(2).getReg());
+    MIRBuilder.buildSub(Ty, MI.getOperand(0).getReg(),
+                        MI.getOperand(1).getReg(), ProdReg);
+    MI.eraseFromParent();
+    return Legalized;
+  }
+  }
+}
+
+MachineLegalizeHelper::LegalizeResult
 MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
                                            LLT NarrowTy) {
   assert(TypeIdx == 0 && "don't know how to handle secondary types yet");