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:
parent
a30faf0090
commit
4841e615e3
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user