1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

GlobalISel: factor overflow handling into separate function. NFC.

llvm-svn: 289149
This commit is contained in:
Tim Northover 2016-12-08 22:44:00 +00:00
parent b16c6ac588
commit 9192e8f992
2 changed files with 41 additions and 28 deletions

View File

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

View File

@ -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) {