From b3af3376ee7f50a6113b7216aea9c5648eaa1465 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Wed, 15 Jan 2020 08:49:22 -0800 Subject: [PATCH] Revert "Revert rG6078f2fedcac5797ac39ee5ef3fd7a35ef1202d5 - "[AArch64][GlobalISel]: Support @llvm.{return,frame}address selection."" The original change wasn't constraining the operand regclasses which broke EXPENSIVE_CHECKS. --- .../AArch64/AArch64InstructionSelector.cpp | 42 ++++++++++++++++++- .../AArch64/GlobalISel/select-frameaddr.ll | 20 +++++++++ .../AArch64/GlobalISel/select-returnaddr.ll | 22 ++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/AArch64/GlobalISel/select-frameaddr.ll create mode 100644 test/CodeGen/AArch64/GlobalISel/select-returnaddr.ll diff --git a/lib/Target/AArch64/AArch64InstructionSelector.cpp b/lib/Target/AArch64/AArch64InstructionSelector.cpp index b9ac2657e1c..8629db4a8a7 100644 --- a/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -4091,7 +4091,7 @@ bool AArch64InstructionSelector::selectIntrinsic( switch (IntrinID) { default: break; - case Intrinsic::aarch64_crypto_sha1h: + case Intrinsic::aarch64_crypto_sha1h: { Register DstReg = I.getOperand(0).getReg(); Register SrcReg = I.getOperand(2).getReg(); @@ -4130,6 +4130,46 @@ bool AArch64InstructionSelector::selectIntrinsic( I.eraseFromParent(); return true; } + case Intrinsic::frameaddress: + case Intrinsic::returnaddress: { + MachineFunction &MF = *I.getParent()->getParent(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + + unsigned Depth = I.getOperand(2).getImm(); + Register DstReg = I.getOperand(0).getReg(); + RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI); + + if (Depth == 0 && IntrinID == Intrinsic::returnaddress) { + MFI.setReturnAddressIsTaken(true); + MF.addLiveIn(AArch64::LR, &AArch64::GPR64spRegClass); + I.getParent()->addLiveIn(AArch64::LR); + MIRBuilder.buildCopy({DstReg}, {Register(AArch64::LR)}); + I.eraseFromParent(); + return true; + } + + MFI.setFrameAddressIsTaken(true); + Register FrameAddr(AArch64::FP); + while (Depth--) { + Register NextFrame = MRI.createVirtualRegister(&AArch64::GPR64spRegClass); + auto Ldr = + MIRBuilder.buildInstr(AArch64::LDRXui, {NextFrame}, {FrameAddr}) + .addImm(0); + constrainSelectedInstRegOperands(*Ldr, TII, TRI, RBI); + FrameAddr = NextFrame; + } + + if (IntrinID == Intrinsic::frameaddress) + MIRBuilder.buildCopy({DstReg}, {FrameAddr}); + else { + MFI.setReturnAddressIsTaken(true); + MIRBuilder.buildInstr(AArch64::LDRXui, {DstReg}, {FrameAddr}).addImm(1); + } + + I.eraseFromParent(); + return true; + } + } return false; } diff --git a/test/CodeGen/AArch64/GlobalISel/select-frameaddr.ll b/test/CodeGen/AArch64/GlobalISel/select-frameaddr.ll new file mode 100644 index 00000000000..83bea900bb6 --- /dev/null +++ b/test/CodeGen/AArch64/GlobalISel/select-frameaddr.ll @@ -0,0 +1,20 @@ +; RUN: llc -mtriple=arm64-apple-ios -global-isel -o - %s | FileCheck %s + +define i8* @rt0(i32 %x) nounwind readnone { +entry: +; CHECK-LABEL: rt0: +; CHECK: mov x0, x29 + %0 = tail call i8* @llvm.frameaddress(i32 0) + ret i8* %0 +} + +define i8* @rt2() nounwind readnone { +entry: +; CHECK-LABEL: rt2: +; CHECK: ldr x[[reg:[0-9]+]], [x29] +; CHECK: ldr x0, [x[[reg]]] + %0 = tail call i8* @llvm.frameaddress(i32 2) + ret i8* %0 +} + +declare i8* @llvm.frameaddress(i32) nounwind readnone diff --git a/test/CodeGen/AArch64/GlobalISel/select-returnaddr.ll b/test/CodeGen/AArch64/GlobalISel/select-returnaddr.ll new file mode 100644 index 00000000000..137f3266704 --- /dev/null +++ b/test/CodeGen/AArch64/GlobalISel/select-returnaddr.ll @@ -0,0 +1,22 @@ +; RUN: llc -mtriple=arm64-apple-ios -global-isel -o - %s | FileCheck %s + +define i8* @rt0(i32 %x) nounwind readnone { +entry: +; CHECK-LABEL: rt0: +; CHECK-NOT: stp +; CHECK: mov x0, x30 + %0 = tail call i8* @llvm.returnaddress(i32 0) + ret i8* %0 +} + +define i8* @rt2() nounwind readnone { +entry: +; CHECK-LABEL: rt2: +; CHECK: ldr x[[reg:[0-9]+]], [x29] +; CHECK: ldr x[[reg]], [x[[reg]]] +; CHECK: ldr x0, [x[[reg]], #8] + %0 = tail call i8* @llvm.returnaddress(i32 2) + ret i8* %0 +} + +declare i8* @llvm.returnaddress(i32) nounwind readnone