From 3f18603c522c80b67db57a42bda01c6525d1acc2 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 18 Oct 2016 20:03:45 +0000 Subject: [PATCH] GlobalISel: translate memcpy intrinsics. llvm-svn: 284525 --- .../include/llvm/CodeGen/GlobalISel/CallLowering.h | 20 +++++++++++--------- .../include/llvm/CodeGen/GlobalISel/IRTranslator.h | 2 ++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 22 ++++++++++++++++++++++ .../AArch64/GlobalISel/arm64-irtranslator.ll | 14 ++++++++++++++ 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h index 8307d39..217c65c 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -29,7 +29,17 @@ class Value; class CallLowering { const TargetLowering *TLI; - protected: +public: + struct ArgInfo { + unsigned Reg; + Type *Ty; + ISD::ArgFlagsTy Flags; + + ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}) + : Reg(Reg), Ty(Ty), Flags(Flags) {} + }; + +protected: /// Getter for generic TargetLowering class. const TargetLowering *getTLI() const { return TLI; @@ -41,14 +51,6 @@ class CallLowering { return static_cast(TLI); } - struct ArgInfo { - unsigned Reg; - Type *Ty; - ISD::ArgFlagsTy Flags; - - ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}) - : Reg(Reg), Ty(Ty), Flags(Flags) {} - }; template void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 435cbed..0bed9d1 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -118,6 +118,8 @@ private: /// Translate an LLVM store instruction into generic IR. bool translateStore(const User &U); + bool translateMemcpy(const CallInst &CI); + bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID); /// Translate call instruction. diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 155a39a..e073717 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -358,6 +358,26 @@ bool IRTranslator::translateGetElementPtr(const User &U) { return true; } +bool IRTranslator::translateMemcpy(const CallInst &CI) { + LLT SizeTy{*CI.getArgOperand(2)->getType(), *DL}; + if (cast(CI.getArgOperand(0)->getType())->getAddressSpace() != + 0 || + cast(CI.getArgOperand(1)->getType())->getAddressSpace() != + 0 || + SizeTy.getSizeInBits() != DL->getPointerSizeInBits(0)) + return false; + + SmallVector Args; + for (int i = 0; i < 3; ++i) { + const auto &Arg = CI.getArgOperand(i); + Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType()); + } + + MachineOperand Callee = MachineOperand::CreateES("memcpy"); + + return CLI->lowerCall(MIRBuilder, Callee, + CallLowering::ArgInfo(0, CI.getType()), Args); +} bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID) { @@ -370,6 +390,8 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, 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; + case Intrinsic::memcpy: + return translateMemcpy(CI); } LLT Ty{*CI.getOperand(0)->getType(), *DL}; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 2b20d16..29c2d9b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -867,3 +867,17 @@ define void()* @test_global_func() { ret void()* @allocai64 } + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32 %align, i1 %volatile) +define void @test_memcpy(i8* %dst, i8* %src, i64 %size) { +; CHECK-LABEL: name: test_memcpy +; CHECK: [[DST:%[0-9]+]](p0) = COPY %x0 +; CHECK: [[SRC:%[0-9]+]](p0) = COPY %x1 +; CHECK: [[SIZE:%[0-9]+]](s64) = COPY %x2 +; CHECK: %x0 = COPY [[DST]] +; CHECK: %x1 = COPY [[SRC]] +; CHECK: %x2 = COPY [[SIZE]] +; CHECK: BL $memcpy, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %x0, implicit %x1, implicit %x2 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i32 1, i1 0) + ret void +} -- 2.7.4