1
0
mirror of https://github.com/RPCSX/llvm.git synced 2025-04-05 01:31:36 +00:00

GlobalISel: translate memcpy intrinsics.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284525 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2016-10-18 20:03:45 +00:00
parent a30faf0090
commit 4841e615e3
4 changed files with 49 additions and 9 deletions
include/llvm/CodeGen/GlobalISel
lib/CodeGen/GlobalISel
test/CodeGen/AArch64/GlobalISel

@ -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<const XXXTargetLowering *>(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 <typename FuncInfoTy>
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL,

@ -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.

@ -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<PointerType>(CI.getArgOperand(0)->getType())->getAddressSpace() !=
0 ||
cast<PointerType>(CI.getArgOperand(1)->getType())->getAddressSpace() !=
0 ||
SizeTy.getSizeInBits() != DL->getPointerSizeInBits(0))
return false;
SmallVector<CallLowering::ArgInfo, 8> 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};

@ -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
}