Index: llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -216,16 +216,16 @@ 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); Index: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -789,8 +789,7 @@ return true; } -unsigned -IRTranslator::getSimpleUnaryIntrinsicOpcode(Intrinsic::ID ID) { +unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { switch (ID) { default: break; @@ -812,12 +811,16 @@ 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 @@ 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::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 @@ 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();