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));