GlobalISel: Implement narrowScalar for mul
llvm-svn: 352300
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index cf997a8..2ab3564 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -343,6 +343,8 @@
     MI.eraseFromParent();
     return Legalized;
   }
+  case TargetOpcode::G_MUL:
+    return narrowScalarMul(MI, TypeIdx, NarrowTy);
   case TargetOpcode::G_EXTRACT: {
     if (TypeIdx != 1)
       return UnableToLegalize;
@@ -1527,6 +1529,51 @@
 }
 
 LegalizerHelper::LegalizeResult
+LegalizerHelper::narrowScalarMul(MachineInstr &MI, unsigned TypeIdx, LLT NewTy) {
+  unsigned DstReg = MI.getOperand(0).getReg();
+  unsigned Src0 = MI.getOperand(1).getReg();
+  unsigned Src1 = MI.getOperand(2).getReg();
+  LLT Ty = MRI.getType(DstReg);
+  if (Ty.isVector())
+    return UnableToLegalize;
+
+  unsigned Size = Ty.getSizeInBits();
+  unsigned NewSize = Size / 2;
+  if (Size != 2 * NewSize)
+    return UnableToLegalize;
+
+  LLT HalfTy = LLT::scalar(NewSize);
+  // TODO: if HalfTy != NewTy, handle the breakdown all at once?
+
+  unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty);
+  unsigned Lo = MRI.createGenericVirtualRegister(HalfTy);
+  unsigned Hi = MRI.createGenericVirtualRegister(HalfTy);
+  unsigned ExtLo = MRI.createGenericVirtualRegister(Ty);
+  unsigned ExtHi = MRI.createGenericVirtualRegister(Ty);
+  unsigned ShiftedHi = MRI.createGenericVirtualRegister(Ty);
+
+  SmallVector<unsigned, 2> Src0Parts;
+  SmallVector<unsigned, 2> Src1Parts;
+
+  extractParts(Src0, HalfTy, 2, Src0Parts);
+  extractParts(Src1, HalfTy, 2, Src1Parts);
+
+  MIRBuilder.buildMul(Lo, Src0Parts[0], Src1Parts[0]);
+
+  // TODO: Use smulh or umulh depending on what the target has.
+  MIRBuilder.buildUMulH(Hi, Src0Parts[1], Src1Parts[1]);
+
+  MIRBuilder.buildConstant(ShiftAmt, NewSize);
+  MIRBuilder.buildAnyExt(ExtHi, Hi);
+  MIRBuilder.buildShl(ShiftedHi, ExtHi, ShiftAmt);
+
+  MIRBuilder.buildZExt(ExtLo, Lo);
+  MIRBuilder.buildOr(DstReg, ExtLo, ShiftedHi);
+  MI.eraseFromParent();
+  return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
 LegalizerHelper::lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
   unsigned Opc = MI.getOpcode();
   auto &TII = *MI.getMF()->getSubtarget().getInstrInfo();