diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 8844260116c4..c75d823501ac 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -216,16 +216,16 @@ private: bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op, MachineIRBuilder &MIRBuilder); - /// Helper function for translateSimpleUnaryIntrinsic. + /// Helper function for translateSimpleIntrinsic. /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a - /// simple unary intrinsic (ceil, fabs, etc.). Otherwise, returns + /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns /// Intrinsic::not_intrinsic. - unsigned getSimpleUnaryIntrinsicOpcode(Intrinsic::ID ID); + unsigned getSimpleIntrinsicOpcode(Intrinsic::ID ID); - /// Translates the intrinsics defined in getSimpleUnaryIntrinsicOpcode. + /// Translates the intrinsics defined in getSimpleIntrinsicOpcode. /// \return true if the translation succeeded. - bool translateSimpleUnaryIntrinsic(const CallInst &CI, Intrinsic::ID ID, - MachineIRBuilder &MIRBuilder); + bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID, + 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 dd4e0df31888..7db54079af1f 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -789,8 +789,7 @@ bool IRTranslator::translateOverflowIntrinsic(const CallInst &CI, unsigned Op, return true; } -unsigned -IRTranslator::getSimpleUnaryIntrinsicOpcode(Intrinsic::ID ID) { +unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { switch (ID) { default: break; @@ -812,12 +811,16 @@ IRTranslator::getSimpleUnaryIntrinsicOpcode(Intrinsic::ID ID) { return TargetOpcode::G_FCANONICALIZE; case Intrinsic::floor: return TargetOpcode::G_FFLOOR; + case Intrinsic::fma: + return TargetOpcode::G_FMA; case Intrinsic::log: return TargetOpcode::G_FLOG; case Intrinsic::log2: return TargetOpcode::G_FLOG2; case Intrinsic::log10: return TargetOpcode::G_FLOG10; + case Intrinsic::pow: + return TargetOpcode::G_FPOW; case Intrinsic::round: return TargetOpcode::G_INTRINSIC_ROUND; case Intrinsic::sin: @@ -830,18 +833,22 @@ IRTranslator::getSimpleUnaryIntrinsicOpcode(Intrinsic::ID ID) { return Intrinsic::not_intrinsic; } -bool IRTranslator::translateSimpleUnaryIntrinsic( - const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder) { +bool IRTranslator::translateSimpleIntrinsic(const CallInst &CI, + Intrinsic::ID ID, + MachineIRBuilder &MIRBuilder) { - unsigned Op = getSimpleUnaryIntrinsicOpcode(ID); + unsigned Op = getSimpleIntrinsicOpcode(ID); - // Is this a simple unary intrinsic? + // Is this a simple intrinsic? if (Op == Intrinsic::not_intrinsic) return false; // Yes. Let's translate it. - MIRBuilder.buildInstr(Op, {getOrCreateVReg(CI)}, - {getOrCreateVReg(*CI.getArgOperand(0))}, + SmallVector VRegs; + for (auto &Arg : CI.arg_operands()) + VRegs.push_back(getOrCreateVReg(*Arg)); + + MIRBuilder.buildInstr(Op, {getOrCreateVReg(CI)}, VRegs, MachineInstr::copyFlagsFromInstruction(CI)); return true; } @@ -849,9 +856,9 @@ bool IRTranslator::translateSimpleUnaryIntrinsic( bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder) { - // If this is a simple unary intrinsic (that is, we just need to add a def of - // a vreg, and a use of a vreg, then translate it. - if (translateSimpleUnaryIntrinsic(CI, ID, MIRBuilder)) + // If this is a simple intrinsic (that is, we just need to add a def of + // a vreg, and uses for each arg operand, then translate it. + if (translateSimpleIntrinsic(CI, ID, MIRBuilder)) return true; switch (ID) { @@ -974,21 +981,6 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder); case Intrinsic::smul_with_overflow: return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder); - case Intrinsic::pow: { - MIRBuilder.buildInstr(TargetOpcode::G_FPOW, {getOrCreateVReg(CI)}, - {getOrCreateVReg(*CI.getArgOperand(0)), - getOrCreateVReg(*CI.getArgOperand(1))}, - MachineInstr::copyFlagsFromInstruction(CI)); - return true; - } - case Intrinsic::fma: { - MIRBuilder.buildInstr(TargetOpcode::G_FMA, {getOrCreateVReg(CI)}, - {getOrCreateVReg(*CI.getArgOperand(0)), - getOrCreateVReg(*CI.getArgOperand(1)), - getOrCreateVReg(*CI.getArgOperand(2))}, - MachineInstr::copyFlagsFromInstruction(CI)); - return true; - } case Intrinsic::fmuladd: { const TargetMachine &TM = MF->getTarget(); const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();