From 1ae1b9397e9e60438c22e240fb989ecfa39bb527 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 30 Jan 2017 19:33:07 +0000 Subject: [PATCH] GlobalISel: translate memset & memmove. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293541 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/CodeGen/GlobalISel/IRTranslator.h | 4 ++- lib/CodeGen/GlobalISel/IRTranslator.cpp | 34 ++++++++++++++----- .../AArch64/GlobalISel/arm64-irtranslator.ll | 28 +++++++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 07df370ee59..25e8588c437 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -130,7 +130,9 @@ private: /// Translate an LLVM store instruction into generic IR. bool translateStore(const User &U, MachineIRBuilder &MIRBuilder); - bool translateMemcpy(const CallInst &CI, MachineIRBuilder &MIRBuilder); + /// Translate an LLVM string intrinsic (memcpy, memset, ...). + bool translateMemfunc(const CallInst &CI, MachineIRBuilder &MIRBuilder, + unsigned Intrinsic); void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder); diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 58bd65ef323..3a2469dca49 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -468,13 +468,12 @@ bool IRTranslator::translateGetElementPtr(const User &U, return true; } -bool IRTranslator::translateMemcpy(const CallInst &CI, - MachineIRBuilder &MIRBuilder) { +bool IRTranslator::translateMemfunc(const CallInst &CI, + MachineIRBuilder &MIRBuilder, + unsigned ID) { LLT SizeTy{*CI.getArgOperand(2)->getType(), *DL}; - if (cast(CI.getArgOperand(0)->getType())->getAddressSpace() != - 0 || - cast(CI.getArgOperand(1)->getType())->getAddressSpace() != - 0 || + Type *DstTy = CI.getArgOperand(0)->getType(); + if (cast(DstTy)->getAddressSpace() != 0 || SizeTy.getSizeInBits() != DL->getPointerSizeInBits(0)) return false; @@ -484,9 +483,24 @@ bool IRTranslator::translateMemcpy(const CallInst &CI, Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType()); } - MachineOperand Callee = MachineOperand::CreateES("memcpy"); + const char *Callee; + switch (ID) { + case Intrinsic::memmove: + case Intrinsic::memcpy: { + Type *SrcTy = CI.getArgOperand(1)->getType(); + if(cast(SrcTy)->getAddressSpace() != 0) + return false; + Callee = ID == Intrinsic::memcpy ? "memcpy" : "memmove"; + break; + } + case Intrinsic::memset: + Callee = "memset"; + break; + default: + return false; + } - return CLI->lowerCall(MIRBuilder, Callee, + return CLI->lowerCall(MIRBuilder, MachineOperand::CreateES(Callee), CallLowering::ArgInfo(0, CI.getType()), Args); } @@ -607,7 +621,9 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, case Intrinsic::smul_with_overflow: return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder); case Intrinsic::memcpy: - return translateMemcpy(CI, MIRBuilder); + case Intrinsic::memmove: + case Intrinsic::memset: + return translateMemfunc(CI, MIRBuilder, ID); case Intrinsic::eh_typeid_for: { GlobalValue *GV = ExtractTypeInfo(CI.getArgOperand(0)); unsigned Reg = getOrCreateVReg(CI); diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 3938a3a8961..bac3017a925 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1054,6 +1054,34 @@ define void @test_memcpy(i8* %dst, i8* %src, i64 %size) { ret void } +declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i32 %align, i1 %volatile) +define void @test_memmove(i8* %dst, i8* %src, i64 %size) { +; CHECK-LABEL: name: test_memmove +; 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 $memmove, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %x0, implicit %x1, implicit %x2 + call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i32 1, i1 0) + ret void +} + +declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i32 %align, i1 %volatile) +define void @test_memset(i8* %dst, i8 %val, i64 %size) { +; CHECK-LABEL: name: test_memset +; CHECK: [[DST:%[0-9]+]](p0) = COPY %x0 +; CHECK: [[SRC:%[0-9]+]](s8) = COPY %w1 +; CHECK: [[SIZE:%[0-9]+]](s64) = COPY %x2 +; CHECK: %x0 = COPY [[DST]] +; CHECK: %w1 = COPY [[SRC]] +; CHECK: %x2 = COPY [[SIZE]] +; CHECK: BL $memset, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %x0, implicit %w1, implicit %x2 + call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i32 1, i1 0) + ret void +} + declare i64 @llvm.objectsize.i64(i8*, i1) declare i32 @llvm.objectsize.i32(i8*, i1) define void @test_objectsize(i8* %addr0, i8* %addr1) { -- 2.40.0