[FastISel][AArch64] Add support for frameaddress intrinsic.

This commit implements the frameaddress intrinsic for the AArch64 architecture
in FastISel.

There were two test cases that pretty much tested the same, so I combined them
to a single test case.

Fixes <rdar://problem/17811834>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213959 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Juergen Ributzka 2014-07-25 17:47:14 +00:00
parent 2602b66b91
commit 06640d93e0
3 changed files with 47 additions and 27 deletions

View File

@ -1438,8 +1438,34 @@ bool AArch64FastISel::TryEmitSmallMemCpy(Address Dest, Address Src,
bool AArch64FastISel::FastLowerIntrinsicCall(const IntrinsicInst *II) {
// FIXME: Handle more intrinsics.
switch (II->getIntrinsicID()) {
default:
return false;
default: return false;
case Intrinsic::frameaddress: {
MachineFrameInfo *MFI = FuncInfo.MF->getFrameInfo();
MFI->setFrameAddressIsTaken(true);
const AArch64RegisterInfo *RegInfo =
static_cast<const AArch64RegisterInfo *>(TM.getRegisterInfo());
unsigned FramePtr = RegInfo->getFrameRegister(*(FuncInfo.MF));
unsigned SrcReg = FramePtr;
// Recursively load frame address
// ldr x0, [fp]
// ldr x0, [x0]
// ldr x0, [x0]
// ...
unsigned DestReg;
unsigned Depth = cast<ConstantInt>(II->getOperand(0))->getZExtValue();
while (Depth--) {
DestReg = createResultReg(&AArch64::GPR64RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(AArch64::LDRXui), DestReg)
.addReg(SrcReg).addImm(0);
SrcReg = DestReg;
}
UpdateValueMap(II, SrcReg);
return true;
}
case Intrinsic::memcpy:
case Intrinsic::memmove: {
const auto *MTI = cast<MemTransferInst>(II);

View File

@ -1,15 +0,0 @@
; RUN: llc < %s -march=arm64 | FileCheck %s
define i8* @t() nounwind {
entry:
; CHECK-LABEL: t:
; CHECK: stp x29, x30, [sp, #-16]!
; CHECK: mov x29, sp
; CHECK: mov x0, x29
; CHECK: ldp x29, x30, [sp], #16
; CHECK: ret
%0 = call i8* @llvm.frameaddress(i32 0)
ret i8* %0
}
declare i8* @llvm.frameaddress(i32) nounwind readnone

View File

@ -1,20 +1,29 @@
; RUN: llc -o - %s -mtriple=arm64-apple-ios7.0 | FileCheck %s
; RUN: llc -mtriple=arm64-apple-ios7.0 < %s | FileCheck %s
; RUN: llc -mtriple=arm64-apple-ios7.0 -fast-isel -fast-isel-abort < %s | FileCheck %s
define i8* @t() nounwind {
define i8* @test_frameaddress0() nounwind {
entry:
; CHECK-LABEL: t:
; CHECK-LABEL: test_frameaddress0:
; CHECK: stp x29, x30, [sp, #-16]!
; CHECK: mov x29, sp
; CHECK: mov x0, x29
%0 = call i8* @llvm.frameaddress(i32 0)
ret i8* %0
; CHECK: ldp x29, x30, [sp], #16
; CHECK: ret
%0 = call i8* @llvm.frameaddress(i32 0)
ret i8* %0
}
define i8* @t2() nounwind {
define i8* @test_frameaddress2() nounwind {
entry:
; CHECK-LABEL: t2:
; CHECK-LABEL: test_frameaddress2:
; CHECK: stp x29, x30, [sp, #-16]!
; CHECK: mov x29, sp
; CHECK: ldr x[[reg:[0-9]+]], [x29]
; CHECK: ldr {{x[0-9]+}}, [x[[reg]]]
%0 = call i8* @llvm.frameaddress(i32 2)
ret i8* %0
; CHECK: ldr x0, [x[[reg]]]
; CHECK: ldp x29, x30, [sp], #16
; CHECK: ret
%0 = call i8* @llvm.frameaddress(i32 2)
ret i8* %0
}
declare i8* @llvm.frameaddress(i32) nounwind readnone