Index: include/llvm/CodeGen/GlobalISel/IRTranslator.h =================================================================== --- include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -213,9 +213,6 @@ void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder); - bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op, - MachineIRBuilder &MIRBuilder); - /// Helper function for translateSimpleIntrinsic. /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns Index: lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- lib/CodeGen/GlobalISel/IRTranslator.cpp +++ lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -777,18 +777,6 @@ MIB.setMemRefs({MemRef}); } -bool IRTranslator::translateOverflowIntrinsic(const CallInst &CI, unsigned Op, - MachineIRBuilder &MIRBuilder) { - ArrayRef ResRegs = getOrCreateVRegs(CI); - MIRBuilder.buildInstr(Op) - .addDef(ResRegs[0]) - .addDef(ResRegs[1]) - .addUse(getOrCreateVReg(*CI.getOperand(0))) - .addUse(getOrCreateVReg(*CI.getOperand(1))); - - return true; -} - unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { switch (ID) { default: @@ -829,7 +817,19 @@ return TargetOpcode::G_FSQRT; case Intrinsic::trunc: return TargetOpcode::G_INTRINSIC_TRUNC; - } + case Intrinsic::uadd_with_overflow: + return TargetOpcode::G_UADDO; + case Intrinsic::sadd_with_overflow: + return TargetOpcode::G_SADDO; + case Intrinsic::usub_with_overflow: + return TargetOpcode::G_USUBO; + case Intrinsic::ssub_with_overflow: + return TargetOpcode::G_SSUBO; + case Intrinsic::umul_with_overflow: + return TargetOpcode::G_UMULO; + case Intrinsic::smul_with_overflow: + return TargetOpcode::G_SMULO; + } return Intrinsic::not_intrinsic; } @@ -844,11 +844,21 @@ return false; // Yes. Let's translate it. - SmallVector VRegs; + // Our intrinsic looks something like this: + // + // [dst 1, dst2, ..., dst n] = llvm.something(src1, src2, ..., src m) + // + // Get or create vregs for all of the sources and destinations, and attach + // those to a generic instruction. + + SmallVector SrcOps; for (auto &Arg : CI.arg_operands()) - VRegs.push_back(getOrCreateVReg(*Arg)); + SrcOps.push_back(getOrCreateVReg(*Arg)); + + ArrayRef DstRegs = getOrCreateVRegs(CI); + SmallVector DstOps(DstRegs.begin(), DstRegs.end()); - MIRBuilder.buildInstr(Op, {getOrCreateVReg(CI)}, VRegs, + MIRBuilder.buildInstr(Op, DstOps, SrcOps, MachineInstr::copyFlagsFromInstruction(CI)); return true; } @@ -969,18 +979,6 @@ } return true; } - case Intrinsic::uadd_with_overflow: - return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder); - case Intrinsic::sadd_with_overflow: - return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder); - case Intrinsic::usub_with_overflow: - return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, 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::fmuladd: { const TargetMachine &TM = MF->getTarget(); const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();