summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h3
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp66
2 files changed, 41 insertions, 28 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index f310d8e987d..76e0d47ceea 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -126,6 +126,9 @@ private:
void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder);
+ bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
+ MachineIRBuilder &MIRBuilder);
+
bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder);
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 6fa77fa92be..92607dc738e 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -438,17 +438,46 @@ void IRTranslator::getStackGuard(unsigned DstReg,
MIB.setMemRefs(MemRefs, MemRefs + 1);
}
+bool IRTranslator::translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
+ MachineIRBuilder &MIRBuilder) {
+ LLT Ty{*CI.getOperand(0)->getType(), *DL};
+ LLT s1 = LLT::scalar(1);
+ unsigned Width = Ty.getSizeInBits();
+ unsigned Res = MRI->createGenericVirtualRegister(Ty);
+ unsigned Overflow = MRI->createGenericVirtualRegister(s1);
+ auto MIB = MIRBuilder.buildInstr(Op)
+ .addDef(Res)
+ .addDef(Overflow)
+ .addUse(getOrCreateVReg(*CI.getOperand(0)))
+ .addUse(getOrCreateVReg(*CI.getOperand(1)));
+
+ if (Op == TargetOpcode::G_UADDE || Op == TargetOpcode::G_USUBE) {
+ unsigned Zero = MRI->createGenericVirtualRegister(s1);
+ EntryBuilder.buildConstant(Zero, 0);
+ MIB.addUse(Zero);
+ }
+
+ MIRBuilder.buildSequence(getOrCreateVReg(CI), Res, 0, Overflow, Width);
+ return true;
+}
+
bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder) {
- unsigned Op = 0;
switch (ID) {
- default: return false;
- case Intrinsic::uadd_with_overflow: Op = TargetOpcode::G_UADDE; break;
- case Intrinsic::sadd_with_overflow: Op = TargetOpcode::G_SADDO; break;
- case Intrinsic::usub_with_overflow: Op = TargetOpcode::G_USUBE; break;
- case Intrinsic::ssub_with_overflow: Op = TargetOpcode::G_SSUBO; break;
- case Intrinsic::umul_with_overflow: Op = TargetOpcode::G_UMULO; break;
- case Intrinsic::smul_with_overflow: Op = TargetOpcode::G_SMULO; break;
+ default:
+ break;
+ case Intrinsic::uadd_with_overflow:
+ return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDE, MIRBuilder);
+ case Intrinsic::sadd_with_overflow:
+ return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
+ case Intrinsic::usub_with_overflow:
+ return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBE, MIRBuilder);
+ case Intrinsic::ssub_with_overflow:
+ return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
+ case Intrinsic::umul_with_overflow:
+ return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
+ case Intrinsic::smul_with_overflow:
+ return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
case Intrinsic::memcpy:
return translateMemcpy(CI, MIRBuilder);
case Intrinsic::eh_typeid_for: {
@@ -484,26 +513,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
return true;
}
}
-
- LLT Ty{*CI.getOperand(0)->getType(), *DL};
- LLT s1 = LLT::scalar(1);
- unsigned Width = Ty.getSizeInBits();
- unsigned Res = MRI->createGenericVirtualRegister(Ty);
- unsigned Overflow = MRI->createGenericVirtualRegister(s1);
- auto MIB = MIRBuilder.buildInstr(Op)
- .addDef(Res)
- .addDef(Overflow)
- .addUse(getOrCreateVReg(*CI.getOperand(0)))
- .addUse(getOrCreateVReg(*CI.getOperand(1)));
-
- if (Op == TargetOpcode::G_UADDE || Op == TargetOpcode::G_USUBE) {
- unsigned Zero = MRI->createGenericVirtualRegister(s1);
- EntryBuilder.buildConstant(Zero, 0);
- MIB.addUse(Zero);
- }
-
- MIRBuilder.buildSequence(getOrCreateVReg(CI), Res, 0, Overflow, Width);
- return true;
+ return false;
}
bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
OpenPOWER on IntegriCloud