Index: include/llvm/CodeGen/GlobalISel/IRTranslator.h =================================================================== --- include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -163,6 +163,23 @@ /// this function. DenseMap FrameIndices; + /// Static map of opcodes which can be translated using + /// translateSimpleUnaryIntrinsic. + const DenseMap SimpleUnaryIntrinsicOpcodes = { + {Intrinsic::ceil, TargetOpcode::G_FCEIL}, + {Intrinsic::cos, TargetOpcode::G_FCOS}, + {Intrinsic::ctpop, TargetOpcode::G_CTPOP}, + {Intrinsic::exp, TargetOpcode::G_FEXP}, + {Intrinsic::exp2, TargetOpcode::G_FEXP2}, + {Intrinsic::fabs, TargetOpcode::G_FABS}, + {Intrinsic::log, TargetOpcode::G_FLOG}, + {Intrinsic::log2, TargetOpcode::G_FLOG2}, + {Intrinsic::log10, TargetOpcode::G_FLOG10}, + {Intrinsic::round, TargetOpcode::G_INTRINSIC_ROUND}, + {Intrinsic::sin, TargetOpcode::G_FSIN}, + {Intrinsic::sqrt, TargetOpcode::G_FSQRT}, + {Intrinsic::trunc, TargetOpcode::G_INTRINSIC_TRUNC}}; + /// \name Methods for translating form LLVM IR to MachineInstr. /// \see ::translate for general information on the translate methods. /// @{ @@ -216,6 +233,11 @@ bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op, MachineIRBuilder &MIRBuilder); + /// Translates the intrinsics found in SimpleUnaryIntrinsicOpcodes. + /// \return true if the translation succeeded. + bool translateSimpleUnaryIntrinsic(const CallInst &CI, Intrinsic::ID ID, + MachineIRBuilder &MIRBuilder); + bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder); Index: lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- lib/CodeGen/GlobalISel/IRTranslator.cpp +++ lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -788,8 +788,31 @@ return true; } +bool IRTranslator::translateSimpleUnaryIntrinsic( + const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder) { + + auto Op = SimpleUnaryIntrinsicOpcodes.find(ID); + + // Is this a simple unary intrinsic? + if (Op == SimpleUnaryIntrinsicOpcodes.end()) + return false; + + // Yes. Let's translate it. + auto Inst = MIRBuilder.buildInstr(Op->second) + .addDef(getOrCreateVReg(CI)) + .addUse(getOrCreateVReg(*CI.getArgOperand(0))); + Inst->copyIRFlags(CI); + return true; +} + 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)) + return true; + switch (ID) { default: break; @@ -918,58 +941,6 @@ Pow->copyIRFlags(CI); return true; } - case Intrinsic::exp: { - auto Exp = MIRBuilder.buildInstr(TargetOpcode::G_FEXP) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Exp->copyIRFlags(CI); - return true; - } - case Intrinsic::exp2: { - auto Exp2 = MIRBuilder.buildInstr(TargetOpcode::G_FEXP2) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Exp2->copyIRFlags(CI); - return true; - } - case Intrinsic::log: { - auto Log = MIRBuilder.buildInstr(TargetOpcode::G_FLOG) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Log->copyIRFlags(CI); - return true; - } - case Intrinsic::log2: { - auto Log2 = MIRBuilder.buildInstr(TargetOpcode::G_FLOG2) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Log2->copyIRFlags(CI); - return true; - } - case Intrinsic::log10: { - auto Log10 = MIRBuilder.buildInstr(TargetOpcode::G_FLOG10) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Log10->copyIRFlags(CI); - return true; - } - case Intrinsic::fabs: { - auto Fabs = MIRBuilder.buildInstr(TargetOpcode::G_FABS) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Fabs->copyIRFlags(CI); - return true; - } - case Intrinsic::trunc: - MIRBuilder.buildInstr(TargetOpcode::G_INTRINSIC_TRUNC) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; - case Intrinsic::round: - MIRBuilder.buildInstr(TargetOpcode::G_INTRINSIC_ROUND) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; case Intrinsic::fma: { auto FMA = MIRBuilder.buildInstr(TargetOpcode::G_FMA) .addDef(getOrCreateVReg(CI)) @@ -1058,12 +1029,6 @@ .addUse(getOrCreateVReg(*CI.getArgOperand(0))); return true; } - case Intrinsic::ctpop: { - MIRBuilder.buildInstr(TargetOpcode::G_CTPOP) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; - } case Intrinsic::invariant_start: { LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL); unsigned Undef = MRI->createGenericVirtualRegister(PtrTy); @@ -1072,26 +1037,6 @@ } case Intrinsic::invariant_end: return true; - case Intrinsic::ceil: - MIRBuilder.buildInstr(TargetOpcode::G_FCEIL) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; - case Intrinsic::cos: - MIRBuilder.buildInstr(TargetOpcode::G_FCOS) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; - case Intrinsic::sin: - MIRBuilder.buildInstr(TargetOpcode::G_FSIN) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; - case Intrinsic::sqrt: - MIRBuilder.buildInstr(TargetOpcode::G_FSQRT) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - return true; } return false; }