[GISel]: Implement widenScalar for Legalizing G_PHI
https://reviews.llvm.org/D37018
llvm-svn: 311763
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index c54b12b..5e75f4d 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -659,6 +659,37 @@
MI.getOperand(2).setReg(OffsetExt);
return Legalized;
}
+ case TargetOpcode::G_PHI: {
+ assert(TypeIdx == 0 && "Expecting only Idx 0");
+ MachineFunction *MF = MI.getParent()->getParent();
+ auto getExtendedReg = [this, MF, WideTy](unsigned Reg,
+ MachineBasicBlock &MBB) {
+ auto FirstTermIt = MBB.getFirstTerminator();
+ MIRBuilder.setInsertPt(MBB, FirstTermIt);
+ MachineInstr *DefMI = MRI.getVRegDef(Reg);
+ MachineInstrBuilder MIB;
+ if (DefMI->getOpcode() == TargetOpcode::G_TRUNC)
+ MIB = MIRBuilder.buildAnyExtOrTrunc(WideTy,
+ DefMI->getOperand(1).getReg());
+ else
+ MIB = MIRBuilder.buildAnyExt(WideTy, Reg);
+ return MIB->getOperand(0).getReg();
+ };
+ auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, WideTy);
+ for (auto OpIt = MI.operands_begin() + 1, OpE = MI.operands_end();
+ OpIt != OpE;) {
+ unsigned Reg = OpIt++->getReg();
+ MachineBasicBlock *OpMBB = OpIt++->getMBB();
+ MIB.addReg(getExtendedReg(Reg, *OpMBB));
+ MIB.addMBB(OpMBB);
+ }
+ auto *MBB = MI.getParent();
+ MIRBuilder.setInsertPt(*MBB, MBB->getFirstNonPHI());
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(),
+ MIB->getOperand(0).getReg());
+ MI.eraseFromParent();
+ return Legalized;
+ }
}
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 8ca07f3..b4fe5f1 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -346,14 +346,17 @@
return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
- unsigned Op) {
+MachineInstrBuilder
+MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc, unsigned Res, unsigned Op) {
+ assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
+ TargetOpcode::G_SEXT == ExtOpc) &&
+ "Expecting Extending Opc");
assert(MRI->getType(Res).isScalar() || MRI->getType(Res).isVector());
assert(MRI->getType(Res).isScalar() == MRI->getType(Op).isScalar());
unsigned Opcode = TargetOpcode::COPY;
if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
- Opcode = TargetOpcode::G_SEXT;
+ Opcode = ExtOpc;
else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
Opcode = TargetOpcode::G_TRUNC;
else
@@ -362,20 +365,19 @@
return buildInstr(Opcode).addDef(Res).addUse(Op);
}
+MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
+ unsigned Op) {
+ return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
+}
+
MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res,
unsigned Op) {
- assert(MRI->getType(Res).isScalar() || MRI->getType(Res).isVector());
- assert(MRI->getType(Res).isScalar() == MRI->getType(Op).isScalar());
+ return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
+}
- unsigned Opcode = TargetOpcode::COPY;
- if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
- Opcode = TargetOpcode::G_ZEXT;
- else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
- Opcode = TargetOpcode::G_TRUNC;
- else
- assert(MRI->getType(Res) == MRI->getType(Op));
-
- return buildInstr(Opcode).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildAnyExtOrTrunc(unsigned Res,
+ unsigned Op) {
+ return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
}
MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {