GlobalISel: add generic load and store instructions.

Pretty straightforward, the only oddity is the MachineMemOperand (which it's
surprisingly difficult to share code for).

llvm-svn: 276799
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 9ce7fe4..6a8712e 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -52,6 +52,21 @@
   return ValReg;
 }
 
+unsigned IRTranslator::getMemOpAlignment(const Instruction &I) {
+  unsigned Alignment = 0;
+  Type *ValTy = nullptr;
+  if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
+    Alignment = SI->getAlignment();
+    ValTy = SI->getValueOperand()->getType();
+  } else if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
+    Alignment = LI->getAlignment();
+    ValTy = LI->getType();
+  } else
+    llvm_unreachable("unhandled memory instruction");
+
+  return Alignment ? Alignment : DL->getABITypeAlignment(ValTy);
+}
+
 MachineBasicBlock &IRTranslator::getOrCreateBB(const BasicBlock &BB) {
   MachineBasicBlock *&MBB = BBToMBB[&BB];
   if (!MBB) {
@@ -100,6 +115,39 @@
   return true;
 }
 
+bool IRTranslator::translateLoad(const LoadInst &LI) {
+  assert(LI.isSimple() && "only simple loads are supported at the moment");
+
+  MachineFunction &MF = MIRBuilder.getMF();
+  unsigned Res = getOrCreateVReg(LI);
+  unsigned Addr = getOrCreateVReg(*LI.getPointerOperand());
+  LLT VTy{*LI.getType()}, PTy{*LI.getPointerOperand()->getType()};
+
+  MIRBuilder.buildLoad(
+      VTy, PTy, Res, Addr,
+      *MF.getMachineMemOperand(MachinePointerInfo(LI.getPointerOperand()),
+                               MachineMemOperand::MOLoad,
+                               VTy.getSizeInBits() / 8, getMemOpAlignment(LI)));
+  return true;
+}
+
+bool IRTranslator::translateStore(const StoreInst &SI) {
+  assert(SI.isSimple() && "only simple loads are supported at the moment");
+
+  MachineFunction &MF = MIRBuilder.getMF();
+  unsigned Val = getOrCreateVReg(*SI.getValueOperand());
+  unsigned Addr = getOrCreateVReg(*SI.getPointerOperand());
+  LLT VTy{*SI.getValueOperand()->getType()},
+      PTy{*SI.getPointerOperand()->getType()};
+
+  MIRBuilder.buildStore(
+      VTy, PTy, Val, Addr,
+      *MF.getMachineMemOperand(MachinePointerInfo(SI.getPointerOperand()),
+                               MachineMemOperand::MOStore,
+                               VTy.getSizeInBits() / 8, getMemOpAlignment(SI)));
+  return true;
+}
+
 bool IRTranslator::translateBitCast(const CastInst &CI) {
   if (LLT{*CI.getDestTy()} == LLT{*CI.getSrcTy()}) {
     MIRBuilder.buildCopy(getOrCreateVReg(CI),
@@ -163,6 +211,12 @@
   case Instruction::PtrToInt:
     return translateCast(TargetOpcode::G_PTRTOINT, cast<CastInst>(Inst));
 
+  // Memory ops.
+  case Instruction::Load:
+    return translateLoad(cast<LoadInst>(Inst));
+  case Instruction::Store:
+    return translateStore(cast<StoreInst>(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 30971e7..be4cafc 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -94,6 +94,23 @@
   return buildInstr(TargetOpcode::COPY, Res, Op);
 }
 
+MachineInstr *MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
+                                          unsigned Addr,
+                                          MachineMemOperand &MMO) {
+  MachineInstr *NewMI = buildInstr(TargetOpcode::G_LOAD, {VTy, PTy}, Res, Addr);
+  NewMI->addMemOperand(getMF(), &MMO);
+  return NewMI;
+}
+
+MachineInstr *MachineIRBuilder::buildStore(LLT VTy, LLT PTy, unsigned Val,
+                                           unsigned Addr,
+                                           MachineMemOperand &MMO) {
+  MachineInstr *NewMI = buildInstr(TargetOpcode::G_STORE, {VTy, PTy});
+  NewMI->addMemOperand(getMF(), &MMO);
+  MachineInstrBuilder(getMF(), NewMI).addReg(Val).addReg(Addr);
+  return NewMI;
+}
+
 MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results,
                                              unsigned Src,
                                              ArrayRef<unsigned> Indexes) {