summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp16
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp29
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp1
-rw-r--r--llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp4
4 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index dfa252d0b62..76555f99c58 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -99,6 +99,22 @@ MachineInstrBuilder MachineIRBuilder::buildAdd(LLT Ty, unsigned Res,
.addUse(Op1);
}
+MachineInstrBuilder MachineIRBuilder::buildSub(LLT Ty, unsigned Res,
+ unsigned Op0, unsigned Op1) {
+ return buildInstr(TargetOpcode::G_SUB, Ty)
+ .addDef(Res)
+ .addUse(Op0)
+ .addUse(Op1);
+}
+
+MachineInstrBuilder MachineIRBuilder::buildMul(LLT Ty, unsigned Res,
+ unsigned Op0, unsigned Op1) {
+ return buildInstr(TargetOpcode::G_MUL, Ty)
+ .addDef(Res)
+ .addUse(Op0)
+ .addUse(Op1);
+}
+
MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
return buildInstr(TargetOpcode::G_BR, LLT::unsized()).addMBB(&Dest);
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index 401f29a6ddc..ec59c834296 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -42,6 +42,8 @@ MachineLegalizeHelper::legalizeInstrStep(MachineInstr &MI,
return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
case MachineLegalizer::WidenScalar:
return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
+ case MachineLegalizer::Lower:
+ return lower(MI, std::get<1>(Action), std::get<2>(Action));
case MachineLegalizer::FewerElements:
return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
default:
@@ -269,6 +271,33 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
}
MachineLegalizeHelper::LegalizeResult
+MachineLegalizeHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
+ using namespace TargetOpcode;
+ unsigned Size = Ty.getSizeInBits();
+ MIRBuilder.setInstr(MI);
+
+ switch(MI.getOpcode()) {
+ default:
+ return UnableToLegalize;
+ case TargetOpcode::G_SREM:
+ case TargetOpcode::G_UREM: {
+ unsigned QuotReg = MRI.createGenericVirtualRegister(Size);
+ MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV, Ty)
+ .addDef(QuotReg)
+ .addUse(MI.getOperand(1).getReg())
+ .addUse(MI.getOperand(2).getReg());
+
+ unsigned ProdReg = MRI.createGenericVirtualRegister(Size);
+ MIRBuilder.buildMul(Ty, ProdReg, QuotReg, MI.getOperand(2).getReg());
+ MIRBuilder.buildSub(Ty, MI.getOperand(0).getReg(),
+ MI.getOperand(1).getReg(), ProdReg);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+ }
+}
+
+MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
LLT NarrowTy) {
assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
index 873288ee42c..c6ee362c63f 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
@@ -126,6 +126,7 @@ LLT MachineLegalizer::findLegalType(const InstrAspect &Aspect,
default:
llvm_unreachable("Cannot find legal type");
case Legal:
+ case Lower:
return Aspect.Type;
case NarrowScalar: {
return findLegalType(Aspect,
diff --git a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
index 0c9addf83ba..681d1378ca2 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
@@ -51,6 +51,10 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() {
setAction({BinOp, Ty}, WidenScalar);
}
+ for (auto BinOp : { G_SREM, G_UREM })
+ for (auto Ty : { s1, s8, s16, s32, s64 })
+ setAction({BinOp, Ty}, Lower);
+
for (auto Op : { G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULO, G_UMULO }) {
for (auto Ty : { s32, s64 })
setAction({Op, Ty}, Legal);
OpenPOWER on IntegriCloud