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