GlobalISel: add generic casts to IRTranslator

This adds LLVM's 3 main cast instructions (inttoptr, ptrtoint, bitcast) to the
IRTranslator. The first two are direct translations (with 2 MachineInstr types
each). Since LLT discards information, a bitcast might become trivial and we
emit a COPY in those cases instead.

llvm-svn: 276690
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 82cec25..f7db60f 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -100,6 +100,23 @@
   return true;
 }
 
+bool IRTranslator::translateBitCast(const CastInst &CI) {
+  if (LLT{*CI.getDestTy()} == LLT{*CI.getSrcTy()}) {
+    MIRBuilder.buildInstr(TargetOpcode::COPY, getOrCreateVReg(CI),
+                          getOrCreateVReg(*CI.getOperand(0)));
+    return true;
+  }
+  return translateCast(TargetOpcode::G_BITCAST, CI);
+}
+
+bool IRTranslator::translateCast(unsigned Opcode, const CastInst &CI) {
+  unsigned Op = getOrCreateVReg(*CI.getOperand(0));
+  unsigned Res = getOrCreateVReg(CI);
+  MIRBuilder.buildInstr(Opcode, {LLT{*CI.getDestTy()}, LLT{*CI.getSrcTy()}},
+                        Res, Op);
+  return true;
+}
+
 bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) {
   assert(AI.isStaticAlloca() && "only handle static allocas now");
   MachineFunction &MF = MIRBuilder.getMF();
@@ -138,6 +155,14 @@
   case Instruction::Ret:
     return translateReturn(Inst);
 
+  // Casts
+  case Instruction::BitCast:
+    return translateBitCast(cast<CastInst>(Inst));
+  case Instruction::IntToPtr:
+    return translateCast(TargetOpcode::G_INTTOPTR, cast<CastInst>(Inst));
+  case Instruction::PtrToInt:
+    return translateCast(TargetOpcode::G_PTRTOINT, cast<CastInst>(Inst));
+
   case Instruction::Alloca:
     return translateStaticAlloca(cast<AllocaInst>(Inst));
 
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 2b91584..f18467c 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -85,6 +85,18 @@
   return NewMI;
 }
 
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys,
+                                           unsigned Res, unsigned Op0) {
+  MachineInstr *NewMI = buildInstr(Opcode, Tys[0]);
+  for (unsigned i = 1; i < Tys.size(); ++i)
+    NewMI->setType(Tys[i], i);
+
+  MachineInstrBuilder(getMF(), NewMI)
+      .addReg(Res, RegState::Define)
+      .addReg(Op0);
+  return NewMI;
+}
+
 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
                                            unsigned Op0) {
   MachineInstr *NewMI = buildInstr(Opcode, LLT{});
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index f738385..7946fc2 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -568,7 +568,7 @@
     assert(MI.getType().isValid() && "Generic instructions must have a type");
     OS << " { ";
     for (unsigned i = 0; i < MI.getNumTypes(); ++i) {
-      MI.getType().print(OS);
+      MI.getType(i).print(OS);
       if (i + 1 != MI.getNumTypes())
         OS <<  ", ";
     }